* [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
@ 2024-07-22 11:43 Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 1/8] build-sys: Add rust feature option Manos Pitsidianakis
` (8 more replies)
0 siblings, 9 replies; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-22 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: Stefan Hajnoczi, Mads Ynddal, Peter Maydell, Alex Bennée,
Daniel P. Berrangé, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé, Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson
Changes from v4->v5:
- Added CI patch from Alex Benee
- Removed all cargo use, use meson rust support
- Added Kconfig logic
Changes from v3->v4:
- Add rust-specific files to .gitattributes
- Added help text to scripts/cargo_wrapper.py arguments (thanks Stephan)
- Split bindings separate crate
- Add declarative macros for symbols exported to QEMU to said crate
- Lowered MSRV to 1.77.2
- Removed auto-download and install of bindgen-cli
- Fixed re-compilation of Rust objects in case they are missing from
filesystem
- Fixed optimized builds by adding #[used] (thanks Pierrick for the help
debugging this)
Also, Pierrick helped confirming it works on Windows with some
windows-specific changes. I confirmed it works on macos by allowing
bindgen to detect system paths for clang, which is a workaround and not
a solution. However this series doesn't have the windows changes
integrated.
Changes from v2->v3:
- Addressed minor mistakes (thanks Stefan)
- Setup supported version checks for cargo, rustc and bindgen (thanks
everyone who pointed it out / suggested it)
- Fixed problem with bindgen failing if certain system headers where
needed by defining an allowlist for headers instead of a blocklist for
what we don't want (thanks Alex Bennée for reporting it)
- Cleaned up bindgen target/dependendy definition in meson.build by
removing unnecessary bits
Changes from v1->v2:
- Create bindgen target first, then add commit for device (thanks
Pierrick)
- Create a special named generated.rs for each target as compilation
would fail if more than one targets were defined. The generated.rs
target names would clash.
- Add more descriptive commit messages
- Update MAINTAINERS
- Cleanup patch order for better review, hopefully
Alex Bennée (1):
build deps: update lcitool to include rust bits
Manos Pitsidianakis (7):
build-sys: Add rust feature option
CI: Add build-system-rust-debian job
rust: add bindgen step as a meson dependency
.gitattributes: add Rust diff and merge attributes
rust: add crate to expose bindings and interfaces
rust: add PL011 device model
rust/pl011: vendor dependencies
MAINTAINERS | 20 +
rust/hw/char/pl011/vendor/either/README.rst | 185 +
configure | 12 +
meson.build | 73 +-
rust/wrapper.h | 39 +
.gitattributes | 3 +
.gitlab-ci.d/buildtest.yml | 11 +
.gitlab-ci.d/cirrus/freebsd-13.vars | 2 +-
.gitlab-ci.d/cirrus/macos-13.vars | 2 +-
.gitlab-ci.d/cirrus/macos-14.vars | 2 +-
Kconfig | 1 +
Kconfig.host | 3 +
hw/arm/Kconfig | 33 +-
meson_options.txt | 5 +
rust/.gitignore | 3 +
rust/Kconfig | 1 +
rust/hw/Kconfig | 2 +
rust/hw/char/Kconfig | 3 +
rust/hw/char/meson.build | 1 +
rust/hw/char/pl011/.gitignore | 2 +
rust/hw/char/pl011/Cargo.lock | 123 +
rust/hw/char/pl011/Cargo.toml | 26 +
rust/hw/char/pl011/README.md | 31 +
rust/hw/char/pl011/meson.build | 24 +
rust/hw/char/pl011/rustfmt.toml | 1 +
rust/hw/char/pl011/src/definitions.rs | 48 +
rust/hw/char/pl011/src/device.rs | 541 ++
rust/hw/char/pl011/src/device_class.rs | 58 +
rust/hw/char/pl011/src/lib.rs | 584 ++
rust/hw/char/pl011/src/memory_ops.rs | 45 +
.../vendor/arbitrary-int/.cargo-checksum.json | 1 +
.../pl011/vendor/arbitrary-int/CHANGELOG.md | 47 +
.../pl011/vendor/arbitrary-int/Cargo.toml | 54 +
.../pl011/vendor/arbitrary-int/LICENSE.txt | 21 +
.../char/pl011/vendor/arbitrary-int/README.md | 72 +
.../pl011/vendor/arbitrary-int/meson.build | 14 +
.../pl011/vendor/arbitrary-int/src/lib.rs | 1489 +++++
.../pl011/vendor/arbitrary-int/tests/tests.rs | 1913 ++++++
.../vendor/bilge-impl/.cargo-checksum.json | 1 +
.../char/pl011/vendor/bilge-impl/Cargo.toml | 54 +
.../hw/char/pl011/vendor/bilge-impl/README.md | 327 ++
.../char/pl011/vendor/bilge-impl/meson.build | 24 +
.../pl011/vendor/bilge-impl/src/bitsize.rs | 187 +
.../vendor/bilge-impl/src/bitsize/split.rs | 185 +
.../vendor/bilge-impl/src/bitsize_internal.rs | 235 +
.../src/bitsize_internal/struct_gen.rs | 402 ++
.../pl011/vendor/bilge-impl/src/debug_bits.rs | 55 +
.../vendor/bilge-impl/src/default_bits.rs | 92 +
.../pl011/vendor/bilge-impl/src/fmt_bits.rs | 112 +
.../pl011/vendor/bilge-impl/src/from_bits.rs | 222 +
.../char/pl011/vendor/bilge-impl/src/lib.rs | 79 +
.../pl011/vendor/bilge-impl/src/shared.rs | 196 +
.../src/shared/discriminant_assigner.rs | 56 +
.../vendor/bilge-impl/src/shared/fallback.rs | 92 +
.../vendor/bilge-impl/src/shared/util.rs | 91 +
.../vendor/bilge-impl/src/try_from_bits.rs | 143 +
.../pl011/vendor/bilge/.cargo-checksum.json | 1 +
rust/hw/char/pl011/vendor/bilge/Cargo.toml | 69 +
.../hw/char/pl011/vendor/bilge/LICENSE-APACHE | 176 +
rust/hw/char/pl011/vendor/bilge/LICENSE-MIT | 17 +
rust/hw/char/pl011/vendor/bilge/README.md | 327 ++
rust/hw/char/pl011/vendor/bilge/meson.build | 17 +
rust/hw/char/pl011/vendor/bilge/src/lib.rs | 80 +
.../pl011/vendor/either/.cargo-checksum.json | 1 +
rust/hw/char/pl011/vendor/either/Cargo.toml | 54 +
.../char/pl011/vendor/either/LICENSE-APACHE | 201 +
rust/hw/char/pl011/vendor/either/LICENSE-MIT | 25 +
.../pl011/vendor/either/README-crates.io.md | 10 +
rust/hw/char/pl011/vendor/either/meson.build | 16 +
.../pl011/vendor/either/src/into_either.rs | 64 +
.../char/pl011/vendor/either/src/iterator.rs | 315 +
rust/hw/char/pl011/vendor/either/src/lib.rs | 1519 +++++
.../pl011/vendor/either/src/serde_untagged.rs | 69 +
.../either/src/serde_untagged_optional.rs | 74 +
.../vendor/itertools/.cargo-checksum.json | 1 +
.../char/pl011/vendor/itertools/CHANGELOG.md | 409 ++
.../hw/char/pl011/vendor/itertools/Cargo.lock | 681 +++
.../hw/char/pl011/vendor/itertools/Cargo.toml | 101 +
.../pl011/vendor/itertools/LICENSE-APACHE | 201 +
.../char/pl011/vendor/itertools/LICENSE-MIT | 25 +
rust/hw/char/pl011/vendor/itertools/README.md | 44 +
.../pl011/vendor/itertools/benches/bench1.rs | 877 +++
.../vendor/itertools/benches/combinations.rs | 125 +
.../benches/combinations_with_replacement.rs | 40 +
.../vendor/itertools/benches/extra/mod.rs | 2 +
.../itertools/benches/extra/zipslices.rs | 188 +
.../itertools/benches/fold_specialization.rs | 73 +
.../vendor/itertools/benches/powerset.rs | 44 +
.../vendor/itertools/benches/tree_fold1.rs | 144 +
.../itertools/benches/tuple_combinations.rs | 113 +
.../pl011/vendor/itertools/benches/tuples.rs | 213 +
.../pl011/vendor/itertools/examples/iris.data | 150 +
.../pl011/vendor/itertools/examples/iris.rs | 137 +
.../char/pl011/vendor/itertools/meson.build | 18 +
.../vendor/itertools/src/adaptors/coalesce.rs | 235 +
.../vendor/itertools/src/adaptors/map.rs | 124 +
.../vendor/itertools/src/adaptors/mod.rs | 1151 ++++
.../itertools/src/adaptors/multi_product.rs | 230 +
.../vendor/itertools/src/combinations.rs | 128 +
.../src/combinations_with_replacement.rs | 109 +
.../pl011/vendor/itertools/src/concat_impl.rs | 23 +
.../vendor/itertools/src/cons_tuples_impl.rs | 64 +
.../char/pl011/vendor/itertools/src/diff.rs | 61 +
.../vendor/itertools/src/duplicates_impl.rs | 216 +
.../vendor/itertools/src/either_or_both.rs | 495 ++
.../vendor/itertools/src/exactly_one_err.rs | 110 +
.../pl011/vendor/itertools/src/extrema_set.rs | 48 +
.../pl011/vendor/itertools/src/flatten_ok.rs | 165 +
.../char/pl011/vendor/itertools/src/format.rs | 168 +
.../char/pl011/vendor/itertools/src/free.rs | 286 +
.../pl011/vendor/itertools/src/group_map.rs | 32 +
.../pl011/vendor/itertools/src/groupbylazy.rs | 579 ++
.../vendor/itertools/src/grouping_map.rs | 535 ++
.../pl011/vendor/itertools/src/impl_macros.rs | 29 +
.../pl011/vendor/itertools/src/intersperse.rs | 118 +
.../pl011/vendor/itertools/src/k_smallest.rs | 20 +
.../pl011/vendor/itertools/src/kmerge_impl.rs | 227 +
.../pl011/vendor/itertools/src/lazy_buffer.rs | 63 +
.../hw/char/pl011/vendor/itertools/src/lib.rs | 3967 +++++++++++++
.../pl011/vendor/itertools/src/merge_join.rs | 220 +
.../char/pl011/vendor/itertools/src/minmax.rs | 115 +
.../vendor/itertools/src/multipeek_impl.rs | 101 +
.../pl011/vendor/itertools/src/pad_tail.rs | 96 +
.../pl011/vendor/itertools/src/peek_nth.rs | 102 +
.../itertools/src/peeking_take_while.rs | 177 +
.../vendor/itertools/src/permutations.rs | 277 +
.../pl011/vendor/itertools/src/powerset.rs | 90 +
.../itertools/src/process_results_impl.rs | 68 +
.../vendor/itertools/src/put_back_n_impl.rs | 61 +
.../pl011/vendor/itertools/src/rciter_impl.rs | 99 +
.../pl011/vendor/itertools/src/repeatn.rs | 59 +
.../pl011/vendor/itertools/src/size_hint.rs | 119 +
.../pl011/vendor/itertools/src/sources.rs | 183 +
.../itertools/src/take_while_inclusive.rs | 68 +
.../hw/char/pl011/vendor/itertools/src/tee.rs | 78 +
.../pl011/vendor/itertools/src/tuple_impl.rs | 331 ++
.../pl011/vendor/itertools/src/unique_impl.rs | 179 +
.../pl011/vendor/itertools/src/unziptuple.rs | 80 +
.../vendor/itertools/src/with_position.rs | 88 +
.../pl011/vendor/itertools/src/zip_eq_impl.rs | 60 +
.../pl011/vendor/itertools/src/zip_longest.rs | 83 +
.../pl011/vendor/itertools/src/ziptuple.rs | 138 +
.../itertools/tests/adaptors_no_collect.rs | 46 +
.../vendor/itertools/tests/flatten_ok.rs | 76 +
.../vendor/itertools/tests/macros_hygiene.rs | 13 +
.../vendor/itertools/tests/merge_join.rs | 108 +
.../itertools/tests/peeking_take_while.rs | 69 +
.../pl011/vendor/itertools/tests/quick.rs | 1849 ++++++
.../vendor/itertools/tests/specializations.rs | 153 +
.../pl011/vendor/itertools/tests/test_core.rs | 317 +
.../pl011/vendor/itertools/tests/test_std.rs | 1184 ++++
.../pl011/vendor/itertools/tests/tuples.rs | 86 +
.../char/pl011/vendor/itertools/tests/zip.rs | 77 +
rust/hw/char/pl011/vendor/meson.build | 18 +
.../.cargo-checksum.json | 1 +
.../vendor/proc-macro-error-attr/Cargo.toml | 33 +
.../proc-macro-error-attr/LICENSE-APACHE | 201 +
.../vendor/proc-macro-error-attr/LICENSE-MIT | 21 +
.../vendor/proc-macro-error-attr/build.rs | 5 +
.../vendor/proc-macro-error-attr/meson.build | 20 +
.../vendor/proc-macro-error-attr/src/lib.rs | 121 +
.../vendor/proc-macro-error-attr/src/parse.rs | 89 +
.../proc-macro-error-attr/src/settings.rs | 72 +
.../proc-macro-error/.cargo-checksum.json | 1 +
.../vendor/proc-macro-error/CHANGELOG.md | 162 +
.../pl011/vendor/proc-macro-error/Cargo.toml | 56 +
.../vendor/proc-macro-error/LICENSE-APACHE | 201 +
.../pl011/vendor/proc-macro-error/LICENSE-MIT | 21 +
.../pl011/vendor/proc-macro-error/README.md | 258 +
.../pl011/vendor/proc-macro-error/build.rs | 11 +
.../pl011/vendor/proc-macro-error/meson.build | 22 +
.../vendor/proc-macro-error/src/diagnostic.rs | 349 ++
.../vendor/proc-macro-error/src/dummy.rs | 150 +
.../proc-macro-error/src/imp/delegate.rs | 69 +
.../proc-macro-error/src/imp/fallback.rs | 30 +
.../pl011/vendor/proc-macro-error/src/lib.rs | 560 ++
.../vendor/proc-macro-error/src/macros.rs | 288 +
.../vendor/proc-macro-error/src/sealed.rs | 3 +
.../proc-macro-error/tests/macro-errors.rs | 8 +
.../pl011/vendor/proc-macro-error/tests/ok.rs | 10 +
.../proc-macro-error/tests/runtime-errors.rs | 13 +
.../vendor/proc-macro-error/tests/ui/abort.rs | 11 +
.../proc-macro-error/tests/ui/abort.stderr | 48 +
.../proc-macro-error/tests/ui/append_dummy.rs | 13 +
.../tests/ui/append_dummy.stderr | 5 +
.../tests/ui/children_messages.rs | 6 +
.../tests/ui/children_messages.stderr | 23 +
.../vendor/proc-macro-error/tests/ui/dummy.rs | 13 +
.../proc-macro-error/tests/ui/dummy.stderr | 5 +
.../vendor/proc-macro-error/tests/ui/emit.rs | 7 +
.../proc-macro-error/tests/ui/emit.stderr | 48 +
.../tests/ui/explicit_span_range.rs | 6 +
.../tests/ui/explicit_span_range.stderr | 5 +
.../proc-macro-error/tests/ui/misuse.rs | 11 +
.../proc-macro-error/tests/ui/misuse.stderr | 13 +
.../tests/ui/multiple_tokens.rs | 6 +
.../tests/ui/multiple_tokens.stderr | 5 +
.../tests/ui/not_proc_macro.rs | 4 +
.../tests/ui/not_proc_macro.stderr | 10 +
.../proc-macro-error/tests/ui/option_ext.rs | 6 +
.../tests/ui/option_ext.stderr | 7 +
.../tests/ui/proc_macro_hack.rs | 10 +
.../tests/ui/proc_macro_hack.stderr | 26 +
.../proc-macro-error/tests/ui/result_ext.rs | 7 +
.../tests/ui/result_ext.stderr | 11 +
.../tests/ui/to_tokens_span.rs | 6 +
.../tests/ui/to_tokens_span.stderr | 11 +
.../tests/ui/unknown_setting.rs | 4 +
.../tests/ui/unknown_setting.stderr | 5 +
.../tests/ui/unrelated_panic.rs | 6 +
.../tests/ui/unrelated_panic.stderr | 7 +
.../vendor/proc-macro2/.cargo-checksum.json | 1 +
.../char/pl011/vendor/proc-macro2/Cargo.toml | 104 +
.../pl011/vendor/proc-macro2/LICENSE-APACHE | 176 +
.../char/pl011/vendor/proc-macro2/LICENSE-MIT | 23 +
.../char/pl011/vendor/proc-macro2/README.md | 94 +
.../hw/char/pl011/vendor/proc-macro2/build.rs | 227 +
.../pl011/vendor/proc-macro2/build/probe.rs | 25 +
.../char/pl011/vendor/proc-macro2/meson.build | 19 +
.../vendor/proc-macro2/rust-toolchain.toml | 2 +
.../pl011/vendor/proc-macro2/src/detection.rs | 75 +
.../pl011/vendor/proc-macro2/src/extra.rs | 151 +
.../pl011/vendor/proc-macro2/src/fallback.rs | 1226 ++++
.../char/pl011/vendor/proc-macro2/src/lib.rs | 1369 +++++
.../pl011/vendor/proc-macro2/src/location.rs | 29 +
.../pl011/vendor/proc-macro2/src/marker.rs | 17 +
.../pl011/vendor/proc-macro2/src/parse.rs | 996 ++++
.../pl011/vendor/proc-macro2/src/rcvec.rs | 145 +
.../pl011/vendor/proc-macro2/src/wrapper.rs | 993 ++++
.../vendor/proc-macro2/tests/comments.rs | 105 +
.../vendor/proc-macro2/tests/features.rs | 8 +
.../pl011/vendor/proc-macro2/tests/marker.rs | 100 +
.../pl011/vendor/proc-macro2/tests/test.rs | 905 +++
.../vendor/proc-macro2/tests/test_fmt.rs | 28 +
.../vendor/proc-macro2/tests/test_size.rs | 73 +
.../pl011/vendor/quote/.cargo-checksum.json | 1 +
rust/hw/char/pl011/vendor/quote/Cargo.toml | 50 +
.../hw/char/pl011/vendor/quote/LICENSE-APACHE | 176 +
rust/hw/char/pl011/vendor/quote/LICENSE-MIT | 23 +
rust/hw/char/pl011/vendor/quote/README.md | 272 +
rust/hw/char/pl011/vendor/quote/meson.build | 17 +
.../pl011/vendor/quote/rust-toolchain.toml | 2 +
rust/hw/char/pl011/vendor/quote/src/ext.rs | 110 +
rust/hw/char/pl011/vendor/quote/src/format.rs | 168 +
.../pl011/vendor/quote/src/ident_fragment.rs | 88 +
rust/hw/char/pl011/vendor/quote/src/lib.rs | 1464 +++++
.../hw/char/pl011/vendor/quote/src/runtime.rs | 530 ++
.../hw/char/pl011/vendor/quote/src/spanned.rs | 50 +
.../char/pl011/vendor/quote/src/to_tokens.rs | 209 +
.../pl011/vendor/quote/tests/compiletest.rs | 7 +
rust/hw/char/pl011/vendor/quote/tests/test.rs | 549 ++
.../ui/does-not-have-iter-interpolated-dup.rs | 9 +
...does-not-have-iter-interpolated-dup.stderr | 11 +
.../ui/does-not-have-iter-interpolated.rs | 9 +
.../ui/does-not-have-iter-interpolated.stderr | 11 +
.../tests/ui/does-not-have-iter-separated.rs | 5 +
.../ui/does-not-have-iter-separated.stderr | 10 +
.../quote/tests/ui/does-not-have-iter.rs | 5 +
.../quote/tests/ui/does-not-have-iter.stderr | 10 +
.../vendor/quote/tests/ui/not-quotable.rs | 7 +
.../vendor/quote/tests/ui/not-quotable.stderr | 20 +
.../vendor/quote/tests/ui/not-repeatable.rs | 8 +
.../quote/tests/ui/not-repeatable.stderr | 34 +
.../vendor/quote/tests/ui/wrong-type-span.rs | 7 +
.../quote/tests/ui/wrong-type-span.stderr | 10 +
.../pl011/vendor/syn/.cargo-checksum.json | 1 +
rust/hw/char/pl011/vendor/syn/Cargo.toml | 260 +
rust/hw/char/pl011/vendor/syn/LICENSE-APACHE | 176 +
rust/hw/char/pl011/vendor/syn/LICENSE-MIT | 23 +
rust/hw/char/pl011/vendor/syn/README.md | 284 +
rust/hw/char/pl011/vendor/syn/benches/file.rs | 57 +
rust/hw/char/pl011/vendor/syn/benches/rust.rs | 182 +
rust/hw/char/pl011/vendor/syn/meson.build | 24 +
rust/hw/char/pl011/vendor/syn/src/attr.rs | 793 +++
rust/hw/char/pl011/vendor/syn/src/bigint.rs | 66 +
rust/hw/char/pl011/vendor/syn/src/buffer.rs | 434 ++
rust/hw/char/pl011/vendor/syn/src/classify.rs | 377 ++
.../pl011/vendor/syn/src/custom_keyword.rs | 260 +
.../vendor/syn/src/custom_punctuation.rs | 304 +
rust/hw/char/pl011/vendor/syn/src/data.rs | 423 ++
rust/hw/char/pl011/vendor/syn/src/derive.rs | 259 +
.../char/pl011/vendor/syn/src/discouraged.rs | 225 +
rust/hw/char/pl011/vendor/syn/src/drops.rs | 58 +
rust/hw/char/pl011/vendor/syn/src/error.rs | 467 ++
rust/hw/char/pl011/vendor/syn/src/export.rs | 73 +
rust/hw/char/pl011/vendor/syn/src/expr.rs | 3960 +++++++++++++
rust/hw/char/pl011/vendor/syn/src/ext.rs | 136 +
rust/hw/char/pl011/vendor/syn/src/file.rs | 130 +
rust/hw/char/pl011/vendor/syn/src/fixup.rs | 218 +
.../hw/char/pl011/vendor/syn/src/gen/clone.rs | 2209 +++++++
.../hw/char/pl011/vendor/syn/src/gen/debug.rs | 3160 ++++++++++
rust/hw/char/pl011/vendor/syn/src/gen/eq.rs | 2242 +++++++
rust/hw/char/pl011/vendor/syn/src/gen/fold.rs | 3779 ++++++++++++
rust/hw/char/pl011/vendor/syn/src/gen/hash.rs | 2807 +++++++++
.../hw/char/pl011/vendor/syn/src/gen/visit.rs | 3858 ++++++++++++
.../pl011/vendor/syn/src/gen/visit_mut.rs | 3855 ++++++++++++
rust/hw/char/pl011/vendor/syn/src/generics.rs | 1286 ++++
rust/hw/char/pl011/vendor/syn/src/group.rs | 291 +
rust/hw/char/pl011/vendor/syn/src/ident.rs | 108 +
rust/hw/char/pl011/vendor/syn/src/item.rs | 3441 +++++++++++
rust/hw/char/pl011/vendor/syn/src/lib.rs | 1019 ++++
rust/hw/char/pl011/vendor/syn/src/lifetime.rs | 156 +
rust/hw/char/pl011/vendor/syn/src/lit.rs | 1830 ++++++
.../hw/char/pl011/vendor/syn/src/lookahead.rs | 169 +
rust/hw/char/pl011/vendor/syn/src/mac.rs | 223 +
rust/hw/char/pl011/vendor/syn/src/macros.rs | 166 +
rust/hw/char/pl011/vendor/syn/src/meta.rs | 427 ++
rust/hw/char/pl011/vendor/syn/src/op.rs | 219 +
rust/hw/char/pl011/vendor/syn/src/parse.rs | 1397 +++++
.../pl011/vendor/syn/src/parse_macro_input.rs | 128 +
.../char/pl011/vendor/syn/src/parse_quote.rs | 210 +
rust/hw/char/pl011/vendor/syn/src/pat.rs | 953 +++
rust/hw/char/pl011/vendor/syn/src/path.rs | 886 +++
.../char/pl011/vendor/syn/src/precedence.rs | 163 +
rust/hw/char/pl011/vendor/syn/src/print.rs | 16 +
.../char/pl011/vendor/syn/src/punctuated.rs | 1132 ++++
.../char/pl011/vendor/syn/src/restriction.rs | 176 +
rust/hw/char/pl011/vendor/syn/src/sealed.rs | 4 +
rust/hw/char/pl011/vendor/syn/src/span.rs | 63 +
rust/hw/char/pl011/vendor/syn/src/spanned.rs | 118 +
rust/hw/char/pl011/vendor/syn/src/stmt.rs | 481 ++
rust/hw/char/pl011/vendor/syn/src/thread.rs | 60 +
rust/hw/char/pl011/vendor/syn/src/token.rs | 1138 ++++
rust/hw/char/pl011/vendor/syn/src/tt.rs | 107 +
rust/hw/char/pl011/vendor/syn/src/ty.rs | 1216 ++++
rust/hw/char/pl011/vendor/syn/src/verbatim.rs | 33 +
.../char/pl011/vendor/syn/src/whitespace.rs | 65 +
.../char/pl011/vendor/syn/tests/common/eq.rs | 900 +++
.../char/pl011/vendor/syn/tests/common/mod.rs | 28 +
.../pl011/vendor/syn/tests/common/parse.rs | 49 +
.../char/pl011/vendor/syn/tests/debug/gen.rs | 5163 +++++++++++++++++
.../char/pl011/vendor/syn/tests/debug/mod.rs | 147 +
.../char/pl011/vendor/syn/tests/macros/mod.rs | 93 +
.../char/pl011/vendor/syn/tests/regression.rs | 5 +
.../vendor/syn/tests/regression/issue1108.rs | 5 +
.../vendor/syn/tests/regression/issue1235.rs | 32 +
.../char/pl011/vendor/syn/tests/repo/mod.rs | 461 ++
.../pl011/vendor/syn/tests/repo/progress.rs | 37 +
.../pl011/vendor/syn/tests/test_asyncness.rs | 43 +
.../pl011/vendor/syn/tests/test_attribute.rs | 225 +
.../vendor/syn/tests/test_derive_input.rs | 781 +++
.../char/pl011/vendor/syn/tests/test_expr.rs | 692 +++
.../pl011/vendor/syn/tests/test_generics.rs | 282 +
.../pl011/vendor/syn/tests/test_grouping.rs | 53 +
.../char/pl011/vendor/syn/tests/test_ident.rs | 87 +
.../char/pl011/vendor/syn/tests/test_item.rs | 332 ++
.../pl011/vendor/syn/tests/test_iterators.rs | 70 +
.../char/pl011/vendor/syn/tests/test_lit.rs | 331 ++
.../char/pl011/vendor/syn/tests/test_meta.rs | 154 +
.../vendor/syn/tests/test_parse_buffer.rs | 103 +
.../vendor/syn/tests/test_parse_quote.rs | 166 +
.../vendor/syn/tests/test_parse_stream.rs | 187 +
.../char/pl011/vendor/syn/tests/test_pat.rs | 152 +
.../char/pl011/vendor/syn/tests/test_path.rs | 130 +
.../pl011/vendor/syn/tests/test_precedence.rs | 537 ++
.../pl011/vendor/syn/tests/test_receiver.rs | 321 +
.../pl011/vendor/syn/tests/test_round_trip.rs | 253 +
.../pl011/vendor/syn/tests/test_shebang.rs | 67 +
.../char/pl011/vendor/syn/tests/test_size.rs | 36 +
.../char/pl011/vendor/syn/tests/test_stmt.rs | 322 +
.../vendor/syn/tests/test_token_trees.rs | 32 +
.../hw/char/pl011/vendor/syn/tests/test_ty.rs | 397 ++
.../pl011/vendor/syn/tests/test_visibility.rs | 185 +
.../char/pl011/vendor/syn/tests/zzz_stable.rs | 33 +
.../vendor/unicode-ident/.cargo-checksum.json | 1 +
.../pl011/vendor/unicode-ident/Cargo.toml | 63 +
.../pl011/vendor/unicode-ident/LICENSE-APACHE | 176 +
.../pl011/vendor/unicode-ident/LICENSE-MIT | 23 +
.../vendor/unicode-ident/LICENSE-UNICODE | 46 +
.../char/pl011/vendor/unicode-ident/README.md | 283 +
.../pl011/vendor/unicode-ident/benches/xid.rs | 124 +
.../pl011/vendor/unicode-ident/meson.build | 14 +
.../pl011/vendor/unicode-ident/src/lib.rs | 269 +
.../pl011/vendor/unicode-ident/src/tables.rs | 651 +++
.../vendor/unicode-ident/tests/compare.rs | 67 +
.../vendor/unicode-ident/tests/fst/mod.rs | 11 +
.../unicode-ident/tests/fst/xid_continue.fst | Bin 0 -> 73249 bytes
.../unicode-ident/tests/fst/xid_start.fst | Bin 0 -> 65487 bytes
.../vendor/unicode-ident/tests/roaring/mod.rs | 21 +
.../vendor/unicode-ident/tests/static_size.rs | 95 +
.../vendor/unicode-ident/tests/tables/mod.rs | 7 +
.../unicode-ident/tests/tables/tables.rs | 347 ++
.../vendor/unicode-ident/tests/trie/mod.rs | 7 +
.../vendor/unicode-ident/tests/trie/trie.rs | 445 ++
.../vendor/version_check/.cargo-checksum.json | 1 +
.../pl011/vendor/version_check/Cargo.toml | 24 +
.../pl011/vendor/version_check/LICENSE-APACHE | 201 +
.../pl011/vendor/version_check/LICENSE-MIT | 19 +
.../char/pl011/vendor/version_check/README.md | 80 +
.../pl011/vendor/version_check/meson.build | 14 +
.../pl011/vendor/version_check/src/channel.rs | 193 +
.../pl011/vendor/version_check/src/date.rs | 203 +
.../pl011/vendor/version_check/src/lib.rs | 493 ++
.../pl011/vendor/version_check/src/version.rs | 316 +
rust/hw/meson.build | 1 +
rust/meson.build | 15 +
rust/qemu-api/.gitignore | 2 +
rust/qemu-api/Cargo.lock | 7 +
rust/qemu-api/Cargo.toml | 23 +
rust/qemu-api/README.md | 17 +
rust/qemu-api/build.rs | 13 +
rust/qemu-api/meson.build | 19 +
rust/qemu-api/rustfmt.toml | 1 +
rust/qemu-api/src/bindings.rs | 7 +
rust/qemu-api/src/definitions.rs | 107 +
rust/qemu-api/src/device_class.rs | 128 +
rust/qemu-api/src/lib.rs | 100 +
rust/qemu-api/src/tests.rs | 48 +
rust/rustfmt.toml | 7 +
.../ci/setup/ubuntu/ubuntu-2204-aarch64.yaml | 3 +
.../ci/setup/ubuntu/ubuntu-2204-s390x.yaml | 3 +
scripts/meson-buildoptions.sh | 3 +
scripts/rustc_args.py | 84 +
tests/docker/dockerfiles/alpine.docker | 3 +
tests/docker/dockerfiles/centos9.docker | 3 +
.../dockerfiles/debian-amd64-cross.docker | 4 +
.../dockerfiles/debian-arm64-cross.docker | 4 +
.../dockerfiles/debian-armel-cross.docker | 4 +
.../dockerfiles/debian-armhf-cross.docker | 4 +
.../dockerfiles/debian-i686-cross.docker | 4 +
.../dockerfiles/debian-mips64el-cross.docker | 4 +
.../dockerfiles/debian-mipsel-cross.docker | 4 +
.../dockerfiles/debian-ppc64el-cross.docker | 4 +
.../dockerfiles/debian-s390x-cross.docker | 4 +
tests/docker/dockerfiles/debian.docker | 3 +
.../dockerfiles/fedora-win64-cross.docker | 3 +
tests/docker/dockerfiles/fedora.docker | 3 +
tests/docker/dockerfiles/opensuse-leap.docker | 2 +
tests/docker/dockerfiles/ubuntu2204.docker | 3 +
tests/lcitool/libvirt-ci | 2 +-
tests/lcitool/projects/qemu.yml | 3 +
tests/vm/generated/freebsd.json | 2 +
432 files changed, 111104 insertions(+), 16 deletions(-)
create mode 100644 rust/hw/char/pl011/vendor/either/README.rst
create mode 100644 rust/wrapper.h
create mode 100644 rust/.gitignore
create mode 100644 rust/Kconfig
create mode 100644 rust/hw/Kconfig
create mode 100644 rust/hw/char/Kconfig
create mode 100644 rust/hw/char/meson.build
create mode 100644 rust/hw/char/pl011/.gitignore
create mode 100644 rust/hw/char/pl011/Cargo.lock
create mode 100644 rust/hw/char/pl011/Cargo.toml
create mode 100644 rust/hw/char/pl011/README.md
create mode 100644 rust/hw/char/pl011/meson.build
create mode 120000 rust/hw/char/pl011/rustfmt.toml
create mode 100644 rust/hw/char/pl011/src/definitions.rs
create mode 100644 rust/hw/char/pl011/src/device.rs
create mode 100644 rust/hw/char/pl011/src/device_class.rs
create mode 100644 rust/hw/char/pl011/src/lib.rs
create mode 100644 rust/hw/char/pl011/src/memory_ops.rs
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/CHANGELOG.md
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/LICENSE.txt
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/README.md
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/meson.build
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/tests/tests.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/README.md
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/meson.build
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize/split.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal/struct_gen.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/debug_bits.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/default_bits.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/fmt_bits.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/from_bits.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared/discriminant_assigner.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared/fallback.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared/util.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/try_from_bits.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/bilge/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/bilge/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/bilge/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/bilge/README.md
create mode 100644 rust/hw/char/pl011/vendor/bilge/meson.build
create mode 100644 rust/hw/char/pl011/vendor/bilge/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/either/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/either/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/either/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/either/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/either/README-crates.io.md
create mode 100644 rust/hw/char/pl011/vendor/either/meson.build
create mode 100644 rust/hw/char/pl011/vendor/either/src/into_either.rs
create mode 100644 rust/hw/char/pl011/vendor/either/src/iterator.rs
create mode 100644 rust/hw/char/pl011/vendor/either/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/either/src/serde_untagged.rs
create mode 100644 rust/hw/char/pl011/vendor/either/src/serde_untagged_optional.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/itertools/CHANGELOG.md
create mode 100644 rust/hw/char/pl011/vendor/itertools/Cargo.lock
create mode 100644 rust/hw/char/pl011/vendor/itertools/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/itertools/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/itertools/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/itertools/README.md
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/bench1.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/combinations.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/combinations_with_replacement.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/extra/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/extra/zipslices.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/fold_specialization.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/powerset.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/tree_fold1.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/tuple_combinations.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/tuples.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/examples/iris.data
create mode 100644 rust/hw/char/pl011/vendor/itertools/examples/iris.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/meson.build
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/coalesce.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/map.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/multi_product.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/combinations.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/combinations_with_replacement.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/concat_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/cons_tuples_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/diff.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/duplicates_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/either_or_both.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/exactly_one_err.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/extrema_set.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/flatten_ok.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/format.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/free.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/group_map.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/groupbylazy.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/grouping_map.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/impl_macros.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/intersperse.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/k_smallest.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/kmerge_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/lazy_buffer.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/merge_join.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/minmax.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/multipeek_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/pad_tail.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/peek_nth.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/peeking_take_while.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/permutations.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/powerset.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/process_results_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/put_back_n_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/rciter_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/repeatn.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/size_hint.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/sources.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/take_while_inclusive.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/tee.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/tuple_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/unique_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/unziptuple.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/with_position.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/zip_eq_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/zip_longest.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/ziptuple.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/adaptors_no_collect.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/flatten_ok.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/macros_hygiene.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/merge_join.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/peeking_take_while.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/quick.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/specializations.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/test_core.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/test_std.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/tuples.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/zip.rs
create mode 100644 rust/hw/char/pl011/vendor/meson.build
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/build.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/meson.build
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/src/parse.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/src/settings.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/CHANGELOG.md
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/README.md
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/build.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/meson.build
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/diagnostic.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/dummy.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/imp/delegate.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/imp/fallback.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/macros.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/sealed.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/macro-errors.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ok.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/runtime-errors.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/README.md
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/build.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/build/probe.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/meson.build
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/rust-toolchain.toml
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/detection.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/extra.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/fallback.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/location.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/marker.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/parse.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/rcvec.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/wrapper.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/comments.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/features.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/marker.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/test.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/test_fmt.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/test_size.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/quote/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/quote/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/quote/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/quote/README.md
create mode 100644 rust/hw/char/pl011/vendor/quote/meson.build
create mode 100644 rust/hw/char/pl011/vendor/quote/rust-toolchain.toml
create mode 100644 rust/hw/char/pl011/vendor/quote/src/ext.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/src/format.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/src/ident_fragment.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/src/runtime.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/src/spanned.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/src/to_tokens.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/compiletest.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/test.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.stderr
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.stderr
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.stderr
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.stderr
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.stderr
create mode 100644 rust/hw/char/pl011/vendor/syn/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/syn/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/syn/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/syn/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/syn/README.md
create mode 100644 rust/hw/char/pl011/vendor/syn/benches/file.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/benches/rust.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/meson.build
create mode 100644 rust/hw/char/pl011/vendor/syn/src/attr.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/bigint.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/buffer.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/classify.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/custom_keyword.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/custom_punctuation.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/data.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/derive.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/discouraged.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/drops.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/error.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/export.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/expr.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/ext.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/file.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/fixup.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/clone.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/debug.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/eq.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/fold.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/hash.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/visit.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/visit_mut.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/generics.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/group.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/ident.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/item.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/lifetime.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/lit.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/lookahead.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/mac.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/macros.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/meta.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/op.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/parse.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/parse_macro_input.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/parse_quote.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/pat.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/path.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/precedence.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/print.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/punctuated.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/restriction.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/sealed.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/span.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/spanned.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/stmt.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/thread.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/token.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/tt.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/ty.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/verbatim.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/whitespace.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/common/eq.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/common/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/common/parse.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/debug/gen.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/debug/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/macros/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/regression.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/regression/issue1108.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/regression/issue1235.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/repo/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/repo/progress.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_asyncness.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_attribute.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_derive_input.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_expr.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_generics.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_grouping.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_ident.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_item.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_iterators.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_lit.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_meta.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_parse_buffer.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_parse_quote.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_parse_stream.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_pat.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_path.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_precedence.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_receiver.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_round_trip.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_shebang.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_size.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_stmt.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_token_trees.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_ty.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_visibility.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/zzz_stable.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/LICENSE-UNICODE
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/README.md
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/benches/xid.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/meson.build
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/src/tables.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/compare.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/fst/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/fst/xid_continue.fst
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/fst/xid_start.fst
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/roaring/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/static_size.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/tables/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/tables/tables.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/trie/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/trie/trie.rs
create mode 100644 rust/hw/char/pl011/vendor/version_check/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/version_check/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/version_check/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/version_check/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/version_check/README.md
create mode 100644 rust/hw/char/pl011/vendor/version_check/meson.build
create mode 100644 rust/hw/char/pl011/vendor/version_check/src/channel.rs
create mode 100644 rust/hw/char/pl011/vendor/version_check/src/date.rs
create mode 100644 rust/hw/char/pl011/vendor/version_check/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/version_check/src/version.rs
create mode 100644 rust/hw/meson.build
create mode 100644 rust/meson.build
create mode 100644 rust/qemu-api/.gitignore
create mode 100644 rust/qemu-api/Cargo.lock
create mode 100644 rust/qemu-api/Cargo.toml
create mode 100644 rust/qemu-api/README.md
create mode 100644 rust/qemu-api/build.rs
create mode 100644 rust/qemu-api/meson.build
create mode 120000 rust/qemu-api/rustfmt.toml
create mode 100644 rust/qemu-api/src/bindings.rs
create mode 100644 rust/qemu-api/src/definitions.rs
create mode 100644 rust/qemu-api/src/device_class.rs
create mode 100644 rust/qemu-api/src/lib.rs
create mode 100644 rust/qemu-api/src/tests.rs
create mode 100644 rust/rustfmt.toml
create mode 100644 scripts/rustc_args.py
base-commit: a7ddb48bd1363c8bcdf42776d320289c42191f01
--
γαῖα πυρί μιχθήτω
^ permalink raw reply [flat|nested] 35+ messages in thread
* [RFC PATCH v5 1/8] build-sys: Add rust feature option
2024-07-22 11:43 [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Manos Pitsidianakis
@ 2024-07-22 11:43 ` Manos Pitsidianakis
2024-07-23 6:37 ` Zhao Liu
2024-07-22 11:43 ` [RFC PATCH v5 2/8] build deps: update lcitool to include rust bits Manos Pitsidianakis
` (7 subsequent siblings)
8 siblings, 1 reply; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-22 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: Stefan Hajnoczi, Mads Ynddal, Peter Maydell, Alex Bennée,
Daniel P. Berrangé, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé, Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson,
Paolo Bonzini
Add rust feature in meson.build, configure, to prepare for adding Rust
code in the followup commits.
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
MAINTAINERS | 5 +++++
configure | 12 ++++++++++++
meson.build | 17 ++++++++++++++++-
Kconfig | 1 +
Kconfig.host | 3 +++
meson_options.txt | 5 +++++
rust/Kconfig | 0
scripts/meson-buildoptions.sh | 3 +++
8 files changed, 45 insertions(+), 1 deletion(-)
create mode 100644 rust/Kconfig
diff --git a/MAINTAINERS b/MAINTAINERS
index 7d9811458c..d427f13b79 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4228,6 +4228,11 @@ F: docs/sphinx/
F: docs/_templates/
F: docs/devel/docs.rst
+Rust build system integration
+M: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+S: Maintained
+F: rust/Kconfig
+
Miscellaneous
-------------
Performance Tools and Tests
diff --git a/configure b/configure
index 019fcbd0ef..8476968b96 100755
--- a/configure
+++ b/configure
@@ -173,6 +173,7 @@ fi
# default parameters
container_engine="auto"
+have_rust="no"
cpu=""
cross_compile="no"
cross_prefix=""
@@ -757,6 +758,15 @@ for opt do
;;
--gdb=*) gdb_bin="$optarg"
;;
+ --enable-rust)
+ have_rust="yes" ;
+ meson_option_add -Dhave_rust=true
+ ;;
+ --disable-rust)
+ have_rust="no" ;
+ meson_option_add -Dhave_rust=false
+ meson_option_add -Ddisable_rust=true
+ ;;
# everything else has the same name in configure and meson
--*) meson_option_parse "$opt" "$optarg"
;;
@@ -874,6 +884,8 @@ Advanced options (experts only):
start the emulator (only use if you are including
desired devices in configs/devices/)
--with-devices-ARCH=NAME override default configs/devices
+ --enable-rust enable compilation of Rust code
+ --disable-rust disable compilation of Rust code
--enable-debug enable common debug build options
--cpu=CPU Build for host CPU [$cpu]
--disable-containers don't use containers for cross-building
diff --git a/meson.build b/meson.build
index a1e51277b0..a3f346ab3c 100644
--- a/meson.build
+++ b/meson.build
@@ -70,6 +70,14 @@ if host_os == 'darwin' and \
all_languages += ['objc']
objc = meson.get_compiler('objc')
endif
+if get_option('have_rust') and meson.version().version_compare('<1.0.0')
+ error('Rust support requires Meson version >=1.0.0')
+endif
+have_rust = false
+if not get_option('disable_rust') and add_languages('rust', required: get_option('have_rust'), native: false)
+ rustc = meson.get_compiler('rust')
+ have_rust = true
+endif
dtrace = not_found
stap = not_found
@@ -2119,6 +2127,7 @@ endif
config_host_data = configuration_data()
+config_host_data.set('CONFIG_HAVE_RUST', have_rust)
audio_drivers_selected = []
if have_system
audio_drivers_available = {
@@ -3038,7 +3047,8 @@ host_kconfig = \
(host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
(multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
(vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \
- (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : [])
+ (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : []) + \
+ (have_rust ? ['CONFIG_HAVE_RUST=y'] : [])
ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
@@ -4242,6 +4252,11 @@ if 'objc' in all_languages
else
summary_info += {'Objective-C compiler': false}
endif
+summary_info += {'Rust support': have_rust}
+if have_rust
+ summary_info += {'rustc version': rustc.version()}
+ summary_info += {'rustc': ' '.join(rustc.cmd_array())}
+endif
option_cflags = (get_option('debug') ? ['-g'] : [])
if get_option('optimization') != 'plain'
option_cflags += ['-O' + get_option('optimization')]
diff --git a/Kconfig b/Kconfig
index fb6a24a2de..63ca7f46df 100644
--- a/Kconfig
+++ b/Kconfig
@@ -4,3 +4,4 @@ source accel/Kconfig
source target/Kconfig
source hw/Kconfig
source semihosting/Kconfig
+source rust/Kconfig
diff --git a/Kconfig.host b/Kconfig.host
index 17f405004b..4ade7899d6 100644
--- a/Kconfig.host
+++ b/Kconfig.host
@@ -52,3 +52,6 @@ config VFIO_USER_SERVER_ALLOWED
config HV_BALLOON_POSSIBLE
bool
+
+config HAVE_RUST
+ bool
diff --git a/meson_options.txt b/meson_options.txt
index 0269fa0f16..9eef45f85b 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -371,3 +371,8 @@ option('hexagon_idef_parser', type : 'boolean', value : true,
option('x86_version', type : 'combo', choices : ['0', '1', '2', '3', '4'], value: '1',
description: 'tweak required x86_64 architecture version beyond compiler default')
+
+option('have_rust', type: 'boolean', value: false,
+ description: 'Have Rust support')
+option('disable_rust', type: 'boolean', value: false,
+ description: 'Disable Rust support')
diff --git a/rust/Kconfig b/rust/Kconfig
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index c97079a38c..bb5854115a 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -170,6 +170,7 @@ meson_options_help() {
printf "%s\n" ' rbd Ceph block device driver'
printf "%s\n" ' rdma Enable RDMA-based migration'
printf "%s\n" ' replication replication support'
+ printf "%s\n" ' rust Rust support'
printf "%s\n" ' rutabaga-gfx rutabaga_gfx support'
printf "%s\n" ' sdl SDL user interface'
printf "%s\n" ' sdl-image SDL Image support for icons'
@@ -556,6 +557,8 @@ _meson_option_parse() {
--enable-whpx) printf "%s" -Dwhpx=enabled ;;
--disable-whpx) printf "%s" -Dwhpx=disabled ;;
--x86-version=*) quote_sh "-Dx86_version=$2" ;;
+ --enable-with-rust) printf "%s" -Dhave_rust=true ;;
+ --disable-with-rust) printf "%s" -Dhave_rust=false ;;
--enable-xen) printf "%s" -Dxen=enabled ;;
--disable-xen) printf "%s" -Dxen=disabled ;;
--enable-xen-pci-passthrough) printf "%s" -Dxen_pci_passthrough=enabled ;;
--
γαῖα πυρί μιχθήτω
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [RFC PATCH v5 2/8] build deps: update lcitool to include rust bits
2024-07-22 11:43 [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 1/8] build-sys: Add rust feature option Manos Pitsidianakis
@ 2024-07-22 11:43 ` Manos Pitsidianakis
2024-07-23 8:31 ` Richard Henderson
2024-07-22 11:43 ` [RFC PATCH v5 3/8] CI: Add build-system-rust-debian job Manos Pitsidianakis
` (6 subsequent siblings)
8 siblings, 1 reply; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-22 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: Stefan Hajnoczi, Mads Ynddal, Peter Maydell, Alex Bennée,
Daniel P. Berrangé, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé, Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson,
Ed Maste, Li-Wen Hsu, Wainer dos Santos Moschetta, Beraldo Leal
From: Alex Bennée <alex.bennee@linaro.org>
For rust development we need cargo, rustc and bindgen in our various
development environments. Update the libvirt-ci project to (!495) and
regenerate the containers and other dependency lists.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
.gitlab-ci.d/cirrus/freebsd-13.vars | 2 +-
.gitlab-ci.d/cirrus/macos-13.vars | 2 +-
.gitlab-ci.d/cirrus/macos-14.vars | 2 +-
scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml | 3 +++
scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml | 3 +++
tests/docker/dockerfiles/alpine.docker | 3 +++
tests/docker/dockerfiles/centos9.docker | 3 +++
tests/docker/dockerfiles/debian-amd64-cross.docker | 4 ++++
tests/docker/dockerfiles/debian-arm64-cross.docker | 4 ++++
tests/docker/dockerfiles/debian-armel-cross.docker | 4 ++++
tests/docker/dockerfiles/debian-armhf-cross.docker | 4 ++++
tests/docker/dockerfiles/debian-i686-cross.docker | 4 ++++
tests/docker/dockerfiles/debian-mips64el-cross.docker | 4 ++++
tests/docker/dockerfiles/debian-mipsel-cross.docker | 4 ++++
tests/docker/dockerfiles/debian-ppc64el-cross.docker | 4 ++++
tests/docker/dockerfiles/debian-s390x-cross.docker | 4 ++++
tests/docker/dockerfiles/debian.docker | 3 +++
tests/docker/dockerfiles/fedora-win64-cross.docker | 3 +++
tests/docker/dockerfiles/fedora.docker | 3 +++
tests/docker/dockerfiles/opensuse-leap.docker | 2 ++
tests/docker/dockerfiles/ubuntu2204.docker | 3 +++
tests/lcitool/libvirt-ci | 2 +-
tests/lcitool/projects/qemu.yml | 3 +++
tests/vm/generated/freebsd.json | 2 ++
24 files changed, 71 insertions(+), 4 deletions(-)
diff --git a/.gitlab-ci.d/cirrus/freebsd-13.vars b/.gitlab-ci.d/cirrus/freebsd-13.vars
index 3785afca36..8c3b02d089 100644
--- a/.gitlab-ci.d/cirrus/freebsd-13.vars
+++ b/.gitlab-ci.d/cirrus/freebsd-13.vars
@@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake'
NINJA='/usr/local/bin/ninja'
PACKAGING_COMMAND='pkg'
PIP3='/usr/local/bin/pip-3.8'
-PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson mtools ncurses nettle ninja opencv pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-tomli py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio socat spice-protocol tesseract usbredir virglrenderer vte3 xorriso zstd'
+PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson mtools ncurses nettle ninja opencv pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-tomli py39-yaml python3 rpm2cpio rust rust-bindgen-cli sdl2 sdl2_image snappy sndio socat spice-protocol tesseract usbredir virglrenderer vte3 xorriso zstd'
PYPI_PKGS=''
PYTHON='/usr/local/bin/python3'
diff --git a/.gitlab-ci.d/cirrus/macos-13.vars b/.gitlab-ci.d/cirrus/macos-13.vars
index 534f029956..3c8ba1a277 100644
--- a/.gitlab-ci.d/cirrus/macos-13.vars
+++ b/.gitlab-ci.d/cirrus/macos-13.vars
@@ -11,6 +11,6 @@ MAKE='/opt/homebrew/bin/gmake'
NINJA='/opt/homebrew/bin/ninja'
PACKAGING_COMMAND='brew'
PIP3='/opt/homebrew/bin/pip3'
-PKGS='bash bc bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy socat sparse spice-protocol swtpm tesseract usbredir vde vte3 xorriso zlib zstd'
+PKGS='bash bc bindgen bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio rust sdl2 sdl2_image snappy socat sparse spice-protocol swtpm tesseract usbredir vde vte3 xorriso zlib zstd'
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme tomli'
PYTHON='/opt/homebrew/bin/python3'
diff --git a/.gitlab-ci.d/cirrus/macos-14.vars b/.gitlab-ci.d/cirrus/macos-14.vars
index 43070f4a26..d227c5deca 100644
--- a/.gitlab-ci.d/cirrus/macos-14.vars
+++ b/.gitlab-ci.d/cirrus/macos-14.vars
@@ -11,6 +11,6 @@ MAKE='/opt/homebrew/bin/gmake'
NINJA='/opt/homebrew/bin/ninja'
PACKAGING_COMMAND='brew'
PIP3='/opt/homebrew/bin/pip3'
-PKGS='bash bc bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio sdl2 sdl2_image snappy socat sparse spice-protocol swtpm tesseract usbredir vde vte3 xorriso zlib zstd'
+PKGS='bash bc bindgen bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 jemalloc jpeg-turbo json-c libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio rust sdl2 sdl2_image snappy socat sparse spice-protocol swtpm tesseract usbredir vde vte3 xorriso zlib zstd'
PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme tomli'
PYTHON='/opt/homebrew/bin/python3'
diff --git a/scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml b/scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml
index fd5489cd82..6f856a5da2 100644
--- a/scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml
+++ b/scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml
@@ -7,10 +7,12 @@
packages:
- bash
- bc
+ - bindgen
- bison
- bsdextrautils
- bzip2
- ca-certificates
+ - cargo
- ccache
- clang
- dbus
@@ -112,6 +114,7 @@ packages:
- python3-venv
- python3-yaml
- rpm2cpio
+ - rustc
- sed
- socat
- sparse
diff --git a/scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml b/scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml
index afa04502cf..217515f90d 100644
--- a/scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml
+++ b/scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml
@@ -7,10 +7,12 @@
packages:
- bash
- bc
+ - bindgen
- bison
- bsdextrautils
- bzip2
- ca-certificates
+ - cargo
- ccache
- clang
- dbus
@@ -110,6 +112,7 @@ packages:
- python3-venv
- python3-yaml
- rpm2cpio
+ - rustc
- sed
- socat
- sparse
diff --git a/tests/docker/dockerfiles/alpine.docker b/tests/docker/dockerfiles/alpine.docker
index b079a83fe2..fc488c94ac 100644
--- a/tests/docker/dockerfiles/alpine.docker
+++ b/tests/docker/dockerfiles/alpine.docker
@@ -18,6 +18,7 @@ RUN apk update && \
bzip2-dev \
ca-certificates \
capstone-dev \
+ cargo \
ccache \
ceph-dev \
clang \
@@ -89,6 +90,8 @@ RUN apk update && \
py3-yaml \
python3 \
rpm2cpio \
+ rust \
+ rust-bindgen \
samurai \
sdl2-dev \
sdl2_image-dev \
diff --git a/tests/docker/dockerfiles/centos9.docker b/tests/docker/dockerfiles/centos9.docker
index 0256865b9e..e6a69c56f8 100644
--- a/tests/docker/dockerfiles/centos9.docker
+++ b/tests/docker/dockerfiles/centos9.docker
@@ -16,12 +16,14 @@ RUN dnf distro-sync -y && \
alsa-lib-devel \
bash \
bc \
+ bindgen-cli \
bison \
brlapi-devel \
bzip2 \
bzip2-devel \
ca-certificates \
capstone-devel \
+ cargo \
ccache \
clang \
ctags \
@@ -102,6 +104,7 @@ RUN dnf distro-sync -y && \
python3-sphinx_rtd_theme \
python3-tomli \
rdma-core-devel \
+ rust \
sed \
snappy-devel \
socat \
diff --git a/tests/docker/dockerfiles/debian-amd64-cross.docker b/tests/docker/dockerfiles/debian-amd64-cross.docker
index 8058695979..62f8c000ed 100644
--- a/tests/docker/dockerfiles/debian-amd64-cross.docker
+++ b/tests/docker/dockerfiles/debian-amd64-cross.docker
@@ -13,10 +13,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
bsdextrautils \
bzip2 \
ca-certificates \
+ cargo \
ccache \
dbus \
debianutils \
@@ -52,6 +54,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-venv \
python3-yaml \
rpm2cpio \
+ rustc \
sed \
socat \
sparse \
@@ -169,6 +172,7 @@ endian = 'little'\n" > /usr/local/share/meson/cross/x86_64-linux-gnu && \
ENV ABI "x86_64-linux-gnu"
ENV MESON_OPTS "--cross-file=x86_64-linux-gnu"
+ENV RUST_TARGET "x86_64-unknown-linux-gnu"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=x86_64-linux-gnu-
ENV DEF_TARGET_LIST x86_64-softmmu,x86_64-linux-user,i386-softmmu,i386-linux-user
# As a final step configure the user (if env is defined)
diff --git a/tests/docker/dockerfiles/debian-arm64-cross.docker b/tests/docker/dockerfiles/debian-arm64-cross.docker
index 15457d7657..42523e9113 100644
--- a/tests/docker/dockerfiles/debian-arm64-cross.docker
+++ b/tests/docker/dockerfiles/debian-arm64-cross.docker
@@ -13,10 +13,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
bsdextrautils \
bzip2 \
ca-certificates \
+ cargo \
ccache \
dbus \
debianutils \
@@ -52,6 +54,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-venv \
python3-yaml \
rpm2cpio \
+ rustc \
sed \
socat \
sparse \
@@ -168,6 +171,7 @@ endian = 'little'\n" > /usr/local/share/meson/cross/aarch64-linux-gnu && \
ENV ABI "aarch64-linux-gnu"
ENV MESON_OPTS "--cross-file=aarch64-linux-gnu"
+ENV RUST_TARGET "aarch64-unknown-linux-gnu"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=aarch64-linux-gnu-
ENV DEF_TARGET_LIST aarch64-softmmu,aarch64-linux-user
# As a final step configure the user (if env is defined)
diff --git a/tests/docker/dockerfiles/debian-armel-cross.docker b/tests/docker/dockerfiles/debian-armel-cross.docker
index c26ffc2e9e..35d42dba97 100644
--- a/tests/docker/dockerfiles/debian-armel-cross.docker
+++ b/tests/docker/dockerfiles/debian-armel-cross.docker
@@ -13,10 +13,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
bsdextrautils \
bzip2 \
ca-certificates \
+ cargo \
ccache \
dbus \
debianutils \
@@ -54,6 +56,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-wheel \
python3-yaml \
rpm2cpio \
+ rustc \
sed \
socat \
sparse \
@@ -169,6 +172,7 @@ endian = 'little'\n" > /usr/local/share/meson/cross/arm-linux-gnueabi && \
ENV ABI "arm-linux-gnueabi"
ENV MESON_OPTS "--cross-file=arm-linux-gnueabi"
+ENV RUST_TARGET "armv5te-unknown-linux-gnueabi"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=arm-linux-gnueabi-
ENV DEF_TARGET_LIST arm-softmmu,arm-linux-user,armeb-linux-user
# As a final step configure the user (if env is defined)
diff --git a/tests/docker/dockerfiles/debian-armhf-cross.docker b/tests/docker/dockerfiles/debian-armhf-cross.docker
index 8f87656d89..1b2c260e5a 100644
--- a/tests/docker/dockerfiles/debian-armhf-cross.docker
+++ b/tests/docker/dockerfiles/debian-armhf-cross.docker
@@ -13,10 +13,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
bsdextrautils \
bzip2 \
ca-certificates \
+ cargo \
ccache \
dbus \
debianutils \
@@ -52,6 +54,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-venv \
python3-yaml \
rpm2cpio \
+ rustc \
sed \
socat \
sparse \
@@ -168,6 +171,7 @@ endian = 'little'\n" > /usr/local/share/meson/cross/arm-linux-gnueabihf && \
ENV ABI "arm-linux-gnueabihf"
ENV MESON_OPTS "--cross-file=arm-linux-gnueabihf"
+ENV RUST_TARGET "armv7-unknown-linux-gnueabihf"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=arm-linux-gnueabihf-
ENV DEF_TARGET_LIST arm-softmmu,arm-linux-user
# As a final step configure the user (if env is defined)
diff --git a/tests/docker/dockerfiles/debian-i686-cross.docker b/tests/docker/dockerfiles/debian-i686-cross.docker
index f4ef054a2e..50ad6179a2 100644
--- a/tests/docker/dockerfiles/debian-i686-cross.docker
+++ b/tests/docker/dockerfiles/debian-i686-cross.docker
@@ -13,10 +13,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
bsdextrautils \
bzip2 \
ca-certificates \
+ cargo \
ccache \
dbus \
debianutils \
@@ -54,6 +56,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-wheel \
python3-yaml \
rpm2cpio \
+ rustc \
sed \
socat \
sparse \
@@ -169,6 +172,7 @@ endian = 'little'\n" > /usr/local/share/meson/cross/i686-linux-gnu && \
ENV ABI "i686-linux-gnu"
ENV MESON_OPTS "--cross-file=i686-linux-gnu"
+ENV RUST_TARGET "i686-unknown-linux-gnu"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=i686-linux-gnu-
ENV DEF_TARGET_LIST x86_64-softmmu,x86_64-linux-user,i386-softmmu,i386-linux-user
# As a final step configure the user (if env is defined)
diff --git a/tests/docker/dockerfiles/debian-mips64el-cross.docker b/tests/docker/dockerfiles/debian-mips64el-cross.docker
index 59c4c68dce..27db4509b6 100644
--- a/tests/docker/dockerfiles/debian-mips64el-cross.docker
+++ b/tests/docker/dockerfiles/debian-mips64el-cross.docker
@@ -13,10 +13,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
bsdextrautils \
bzip2 \
ca-certificates \
+ cargo \
ccache \
dbus \
debianutils \
@@ -54,6 +56,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-wheel \
python3-yaml \
rpm2cpio \
+ rustc \
sed \
socat \
sparse \
@@ -167,6 +170,7 @@ endian = 'little'\n" > /usr/local/share/meson/cross/mips64el-linux-gnuabi64 && \
ENV ABI "mips64el-linux-gnuabi64"
ENV MESON_OPTS "--cross-file=mips64el-linux-gnuabi64"
+ENV RUST_TARGET "mips64el-unknown-linux-gnuabi64"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=mips64el-linux-gnuabi64-
ENV DEF_TARGET_LIST mips64el-softmmu,mips64el-linux-user
# As a final step configure the user (if env is defined)
diff --git a/tests/docker/dockerfiles/debian-mipsel-cross.docker b/tests/docker/dockerfiles/debian-mipsel-cross.docker
index 880c774f1c..725a632e4b 100644
--- a/tests/docker/dockerfiles/debian-mipsel-cross.docker
+++ b/tests/docker/dockerfiles/debian-mipsel-cross.docker
@@ -13,10 +13,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
bsdextrautils \
bzip2 \
ca-certificates \
+ cargo \
ccache \
dbus \
debianutils \
@@ -54,6 +56,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-wheel \
python3-yaml \
rpm2cpio \
+ rustc \
sed \
socat \
sparse \
@@ -167,6 +170,7 @@ endian = 'little'\n" > /usr/local/share/meson/cross/mipsel-linux-gnu && \
ENV ABI "mipsel-linux-gnu"
ENV MESON_OPTS "--cross-file=mipsel-linux-gnu"
+ENV RUST_TARGET "mipsel-unknown-linux-gnu"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=mipsel-linux-gnu-
ENV DEF_TARGET_LIST mipsel-softmmu,mipsel-linux-user
# As a final step configure the user (if env is defined)
diff --git a/tests/docker/dockerfiles/debian-ppc64el-cross.docker b/tests/docker/dockerfiles/debian-ppc64el-cross.docker
index 1d55b9514c..c85b43704c 100644
--- a/tests/docker/dockerfiles/debian-ppc64el-cross.docker
+++ b/tests/docker/dockerfiles/debian-ppc64el-cross.docker
@@ -13,10 +13,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
bsdextrautils \
bzip2 \
ca-certificates \
+ cargo \
ccache \
dbus \
debianutils \
@@ -52,6 +54,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-venv \
python3-yaml \
rpm2cpio \
+ rustc \
sed \
socat \
sparse \
@@ -167,6 +170,7 @@ endian = 'little'\n" > /usr/local/share/meson/cross/powerpc64le-linux-gnu && \
ENV ABI "powerpc64le-linux-gnu"
ENV MESON_OPTS "--cross-file=powerpc64le-linux-gnu"
+ENV RUST_TARGET "powerpc64le-unknown-linux-gnu"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=powerpc64le-linux-gnu-
ENV DEF_TARGET_LIST ppc64-softmmu,ppc64-linux-user
# As a final step configure the user (if env is defined)
diff --git a/tests/docker/dockerfiles/debian-s390x-cross.docker b/tests/docker/dockerfiles/debian-s390x-cross.docker
index 62ccda6ab1..022c84b0da 100644
--- a/tests/docker/dockerfiles/debian-s390x-cross.docker
+++ b/tests/docker/dockerfiles/debian-s390x-cross.docker
@@ -13,10 +13,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
bsdextrautils \
bzip2 \
ca-certificates \
+ cargo \
ccache \
dbus \
debianutils \
@@ -52,6 +54,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-venv \
python3-yaml \
rpm2cpio \
+ rustc \
sed \
socat \
sparse \
@@ -166,6 +169,7 @@ endian = 'big'\n" > /usr/local/share/meson/cross/s390x-linux-gnu && \
ENV ABI "s390x-linux-gnu"
ENV MESON_OPTS "--cross-file=s390x-linux-gnu"
+ENV RUST_TARGET "s390x-unknown-linux-gnu"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=s390x-linux-gnu-
ENV DEF_TARGET_LIST s390x-softmmu,s390x-linux-user
# As a final step configure the user (if env is defined)
diff --git a/tests/docker/dockerfiles/debian.docker b/tests/docker/dockerfiles/debian.docker
index 0d1d401eb8..c30fab88f7 100644
--- a/tests/docker/dockerfiles/debian.docker
+++ b/tests/docker/dockerfiles/debian.docker
@@ -13,10 +13,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
bsdextrautils \
bzip2 \
ca-certificates \
+ cargo \
ccache \
clang \
dbus \
@@ -119,6 +121,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-venv \
python3-yaml \
rpm2cpio \
+ rustc \
sed \
socat \
sparse \
diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker b/tests/docker/dockerfiles/fedora-win64-cross.docker
index 007e1574bd..d1a1922b35 100644
--- a/tests/docker/dockerfiles/fedora-win64-cross.docker
+++ b/tests/docker/dockerfiles/fedora-win64-cross.docker
@@ -20,9 +20,11 @@ exec "$@"\n' > /usr/bin/nosync && \
nosync dnf install -y \
bash \
bc \
+ bindgen-cli \
bison \
bzip2 \
ca-certificates \
+ cargo \
ccache \
ctags \
dbus-daemon \
@@ -52,6 +54,7 @@ exec "$@"\n' > /usr/bin/nosync && \
python3-sphinx \
python3-sphinx_rtd_theme \
python3-zombie-imp \
+ rust \
sed \
socat \
sparse \
diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker
index 44f239c088..bb05ca4172 100644
--- a/tests/docker/dockerfiles/fedora.docker
+++ b/tests/docker/dockerfiles/fedora.docker
@@ -23,12 +23,14 @@ exec "$@"\n' > /usr/bin/nosync && \
alsa-lib-devel \
bash \
bc \
+ bindgen-cli \
bison \
brlapi-devel \
bzip2 \
bzip2-devel \
ca-certificates \
capstone-devel \
+ cargo \
ccache \
clang \
ctags \
@@ -112,6 +114,7 @@ exec "$@"\n' > /usr/bin/nosync && \
python3-sphinx_rtd_theme \
python3-zombie-imp \
rdma-core-devel \
+ rust \
sed \
snappy-devel \
socat \
diff --git a/tests/docker/dockerfiles/opensuse-leap.docker b/tests/docker/dockerfiles/opensuse-leap.docker
index 836f531ac1..3e8bc8447e 100644
--- a/tests/docker/dockerfiles/opensuse-leap.docker
+++ b/tests/docker/dockerfiles/opensuse-leap.docker
@@ -16,6 +16,7 @@ RUN zypper update -y && \
brlapi-devel \
bzip2 \
ca-certificates \
+ cargo \
ccache \
clang \
ctags \
@@ -94,6 +95,7 @@ RUN zypper update -y && \
python311-pip \
python311-setuptools \
rdma-core-devel \
+ rust \
sed \
snappy-devel \
sndio-devel \
diff --git a/tests/docker/dockerfiles/ubuntu2204.docker b/tests/docker/dockerfiles/ubuntu2204.docker
index beeb44fc28..98ee55f7e0 100644
--- a/tests/docker/dockerfiles/ubuntu2204.docker
+++ b/tests/docker/dockerfiles/ubuntu2204.docker
@@ -13,10 +13,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
bsdextrautils \
bzip2 \
ca-certificates \
+ cargo \
ccache \
clang \
dbus \
@@ -119,6 +121,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-venv \
python3-yaml \
rpm2cpio \
+ rustc \
sed \
socat \
sparse \
diff --git a/tests/lcitool/libvirt-ci b/tests/lcitool/libvirt-ci
index 0e9490cebc..9b2b2ceb80 160000
--- a/tests/lcitool/libvirt-ci
+++ b/tests/lcitool/libvirt-ci
@@ -1 +1 @@
-Subproject commit 0e9490cebc726ef772b6c9e27dac32e7ae99f9b2
+Subproject commit 9b2b2ceb80a7a215bdfb9000bcc2c1a30457ec69
diff --git a/tests/lcitool/projects/qemu.yml b/tests/lcitool/projects/qemu.yml
index 0c85784259..7e85b27b66 100644
--- a/tests/lcitool/projects/qemu.yml
+++ b/tests/lcitool/projects/qemu.yml
@@ -3,11 +3,13 @@ packages:
- alsa
- bash
- bc
+ - bindgen
- bison
- brlapi
- bzip2
- bzip2-libs
- capstone
+ - cargo
- ccache
- clang
- cmocka
@@ -100,6 +102,7 @@ packages:
- python3-tomli
- python3-venv
- rpm2cpio
+ - rust
- sdl2
- sdl2-image
- sed
diff --git a/tests/vm/generated/freebsd.json b/tests/vm/generated/freebsd.json
index 2d5895ebed..3d36c8af7c 100644
--- a/tests/vm/generated/freebsd.json
+++ b/tests/vm/generated/freebsd.json
@@ -60,6 +60,8 @@
"py39-yaml",
"python3",
"rpm2cpio",
+ "rust",
+ "rust-bindgen-cli",
"sdl2",
"sdl2_image",
"snappy",
--
γαῖα πυρί μιχθήτω
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [RFC PATCH v5 3/8] CI: Add build-system-rust-debian job
2024-07-22 11:43 [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 1/8] build-sys: Add rust feature option Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 2/8] build deps: update lcitool to include rust bits Manos Pitsidianakis
@ 2024-07-22 11:43 ` Manos Pitsidianakis
2024-07-23 8:32 ` Richard Henderson
2024-07-23 8:39 ` Daniel P. Berrangé
2024-07-22 11:43 ` [RFC PATCH v5 4/8] rust: add bindgen step as a meson dependency Manos Pitsidianakis
` (5 subsequent siblings)
8 siblings, 2 replies; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-22 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: Stefan Hajnoczi, Mads Ynddal, Peter Maydell, Alex Bennée,
Daniel P. Berrangé, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé, Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson,
Wainer dos Santos Moschetta, Beraldo Leal
Add job that builds with rust support enabled on debian.
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
.gitlab-ci.d/buildtest.yml | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
index e3a0758bd9..e025e2cbf6 100644
--- a/.gitlab-ci.d/buildtest.yml
+++ b/.gitlab-ci.d/buildtest.yml
@@ -107,6 +107,17 @@ crash-test-debian:
- make NINJA=":" check-venv
- pyvenv/bin/python3 scripts/device-crash-test -q --tcg-only ./qemu-system-i386
+build-system-rust-debian:
+ extends:
+ - .native_build_job_template
+ - .native_build_artifact_template
+ needs:
+ job: amd64-debian-container
+ variables:
+ IMAGE: debian
+ CONFIGURE_ARGS: --enable-rust
+ TARGETS: aarch64-softmmu
+
build-system-fedora:
extends:
- .native_build_job_template
--
γαῖα πυρί μιχθήτω
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [RFC PATCH v5 4/8] rust: add bindgen step as a meson dependency
2024-07-22 11:43 [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Manos Pitsidianakis
` (2 preceding siblings ...)
2024-07-22 11:43 ` [RFC PATCH v5 3/8] CI: Add build-system-rust-debian job Manos Pitsidianakis
@ 2024-07-22 11:43 ` Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 5/8] .gitattributes: add Rust diff and merge attributes Manos Pitsidianakis
` (4 subsequent siblings)
8 siblings, 0 replies; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-22 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: Stefan Hajnoczi, Mads Ynddal, Peter Maydell, Alex Bennée,
Daniel P. Berrangé, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé, Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson,
Paolo Bonzini, John Snow, Cleber Rosa
Add bindings_rs target for generating rust bindings to target-independent
qemu C APIs.
The bindings need be created before any rust crate that uses them is
compiled.
The bindings.rs file will end up in BUILDDIR/bindings.rs and have the
same name as a target:
ninja bindings.rs
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
MAINTAINERS | 4 +++
meson.build | 56 +++++++++++++++++++++++++++++
rust/wrapper.h | 39 ++++++++++++++++++++
rust/.gitignore | 3 ++
rust/meson.build | 0
scripts/rustc_args.py | 84 +++++++++++++++++++++++++++++++++++++++++++
6 files changed, 186 insertions(+)
create mode 100644 rust/wrapper.h
create mode 100644 rust/.gitignore
create mode 100644 rust/meson.build
create mode 100644 scripts/rustc_args.py
diff --git a/MAINTAINERS b/MAINTAINERS
index d427f13b79..5f0b586dd4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4231,7 +4231,11 @@ F: docs/devel/docs.rst
Rust build system integration
M: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
S: Maintained
+F: scripts/rustc_args.py
+F: rust/.gitignore
F: rust/Kconfig
+F: rust/meson.build
+F: rust/wrapper.h
Miscellaneous
-------------
diff --git a/meson.build b/meson.build
index a3f346ab3c..a34c5ebb4a 100644
--- a/meson.build
+++ b/meson.build
@@ -298,6 +298,20 @@ foreach lang : all_languages
endif
endforeach
+if have_rust
+ rust_args = []
+
+ if rustc.version().version_compare('<1.77.2')
+ error('rustc version ' + rustc.version() + ' is unsupported: Please upgrade to at least 1.77.2')
+ endif
+
+ if get_option('debug')
+ rust_args += ['-g']
+ endif
+ if get_option('optimization') not in ['0', '1', 'g']
+ rust_args += ['-O']
+ endif
+endif
# default flags for all hosts
# We use -fwrapv to tell the compiler that we require a C dialect where
# left shift of signed integers is well defined and has the expected
@@ -3828,6 +3842,48 @@ common_all = static_library('common',
implicit_include_directories: false,
dependencies: common_ss.all_dependencies())
+if have_rust and have_system
+ rust_args += run_command(
+ meson.global_source_root() / 'scripts/rustc_args.py',
+ '--config-headers', meson.project_build_root() / 'config-host.h',
+ capture : true,
+ check: true).stdout().strip().split()
+
+ bindings_rs = import('rust').bindgen(
+ input: 'rust/wrapper.h',
+ dependencies: common_ss.all_dependencies(),
+ output: 'bindings.rs',
+ include_directories: include_directories('.', 'include'),
+ bindgen_version: ['>=0.69.4'],
+ args: [
+ '--raw-line', '#![allow(non_camel_case_types)]',
+ '--raw-line', '#![allow(non_snake_case)]',
+ '--raw-line', '#![allow(non_upper_case_globals)]',
+ '--raw-line', '#![allow(improper_ctypes_definitions)]',
+ '--raw-line', '#![allow(improper_ctypes)]',
+ '--raw-line', 'unsafe impl Send for Property {}',
+ '--raw-line', 'unsafe impl Sync for Property {}',
+ '--raw-line', 'unsafe impl Sync for TypeInfo {}',
+ '--raw-line', 'unsafe impl Sync for VMStateDescription {}',
+ '--ctypes-prefix', 'core::ffi',
+ '--formatter', 'rustfmt',
+ '--generate-block',
+ '--generate-cstr',
+ '--impl-debug',
+ '--merge-extern-blocks',
+ '--no-doc-comments',
+ '--no-include-path-detection',
+ '--use-core',
+ '--with-derive-default',
+ '--allowlist-file', meson.project_source_root() + '/include/.*',
+ '--allowlist-file', meson.project_source_root() + '/.*',
+ '--allowlist-file', meson.project_build_root() + '/.*'
+ ],
+ )
+ subdir('rust')
+endif
+
+
feature_to_c = find_program('scripts/feature_to_c.py')
if host_os == 'darwin'
diff --git a/rust/wrapper.h b/rust/wrapper.h
new file mode 100644
index 0000000000..51985f0ef1
--- /dev/null
+++ b/rust/wrapper.h
@@ -0,0 +1,39 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright 2024 Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+ *
+ * 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.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "qemu-io.h"
+#include "sysemu/sysemu.h"
+#include "hw/sysbus.h"
+#include "exec/memory.h"
+#include "chardev/char-fe.h"
+#include "hw/clock.h"
+#include "hw/qdev-clock.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
+#include "hw/irq.h"
+#include "qapi/error.h"
+#include "migration/vmstate.h"
+#include "chardev/char-serial.h"
diff --git a/rust/.gitignore b/rust/.gitignore
new file mode 100644
index 0000000000..1bf71b1f68
--- /dev/null
+++ b/rust/.gitignore
@@ -0,0 +1,3 @@
+# Ignore any cargo development build artifacts; for qemu-wide builds, all build
+# artifacts will go to the meson build directory.
+target
diff --git a/rust/meson.build b/rust/meson.build
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/scripts/rustc_args.py b/scripts/rustc_args.py
new file mode 100644
index 0000000000..e4cc9720e1
--- /dev/null
+++ b/scripts/rustc_args.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python3
+
+"""Generate rustc arguments for meson rust builds.
+
+This program generates --cfg compile flags for the configuration headers passed
+as arguments.
+
+Copyright (c) 2024 Linaro Ltd.
+
+Authors:
+ Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import argparse
+import logging
+
+from typing import List
+
+
+def generate_cfg_flags(header: str) -> List[str]:
+ """Converts defines from config[..].h headers to rustc --cfg flags."""
+
+ def cfg_name(name: str) -> str:
+ """Filter function for C #defines"""
+ if (
+ name.startswith("CONFIG_")
+ or name.startswith("TARGET_")
+ or name.startswith("HAVE_")
+ ):
+ return name
+ return ""
+
+ with open(header, encoding="utf-8") as cfg:
+ config = [l.split()[1:] for l in cfg if l.startswith("#define")]
+
+ cfg_list = []
+ for cfg in config:
+ name = cfg_name(cfg[0])
+ if not name:
+ continue
+ if len(cfg) >= 2 and cfg[1] != "1":
+ continue
+ cfg_list.append("--cfg")
+ cfg_list.append(name)
+ return cfg_list
+
+
+def main() -> None:
+ # pylint: disable=missing-function-docstring
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-v", "--verbose", action="store_true")
+ parser.add_argument(
+ "--config-headers",
+ metavar="CONFIG_HEADER",
+ action="append",
+ dest="config_headers",
+ help="paths to any configuration C headers (*.h files), if any",
+ required=False,
+ default=[],
+ )
+ args = parser.parse_args()
+ if args.verbose:
+ logging.basicConfig(level=logging.DEBUG)
+ logging.debug("args: %s", args)
+ for header in args.config_headers:
+ for tok in generate_cfg_flags(header):
+ print(tok)
+
+
+if __name__ == "__main__":
+ main()
--
γαῖα πυρί μιχθήτω
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [RFC PATCH v5 5/8] .gitattributes: add Rust diff and merge attributes
2024-07-22 11:43 [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Manos Pitsidianakis
` (3 preceding siblings ...)
2024-07-22 11:43 ` [RFC PATCH v5 4/8] rust: add bindgen step as a meson dependency Manos Pitsidianakis
@ 2024-07-22 11:43 ` Manos Pitsidianakis
2024-07-23 8:38 ` Zhao Liu
2024-07-22 11:43 ` [RFC PATCH v5 6/8] rust: add crate to expose bindings and interfaces Manos Pitsidianakis
` (3 subsequent siblings)
8 siblings, 1 reply; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-22 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: Stefan Hajnoczi, Mads Ynddal, Peter Maydell, Alex Bennée,
Daniel P. Berrangé, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé, Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson
Set rust source code to diff=rust (built-in with new git versions)
and merge=binary for Cargo.lock files (they should not be merged but
auto-generated by cargo)
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
.gitattributes | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.gitattributes b/.gitattributes
index a217cb7bfe..6dc6383d3d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2,3 +2,6 @@
*.h.inc diff=c
*.m diff=objc
*.py diff=python
+*.rs diff=rust
+*.rs.inc diff=rust
+Cargo.lock diff=toml merge=binary
--
γαῖα πυρί μιχθήτω
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [RFC PATCH v5 6/8] rust: add crate to expose bindings and interfaces
2024-07-22 11:43 [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Manos Pitsidianakis
` (4 preceding siblings ...)
2024-07-22 11:43 ` [RFC PATCH v5 5/8] .gitattributes: add Rust diff and merge attributes Manos Pitsidianakis
@ 2024-07-22 11:43 ` Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 7/8] rust: add PL011 device model Manos Pitsidianakis
` (2 subsequent siblings)
8 siblings, 0 replies; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-22 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: Stefan Hajnoczi, Mads Ynddal, Peter Maydell, Alex Bennée,
Daniel P. Berrangé, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé, Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson
Add rust/qemu-api, which exposes rust-bindgen generated FFI bindings and
provides some declaration macros for symbols visible to the rest of
QEMU.
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
MAINTAINERS | 6 ++
rust/meson.build | 13 +++
rust/qemu-api/.gitignore | 2 +
rust/qemu-api/Cargo.lock | 7 ++
rust/qemu-api/Cargo.toml | 23 ++++++
rust/qemu-api/README.md | 17 ++++
rust/qemu-api/build.rs | 13 +++
rust/qemu-api/meson.build | 19 +++++
rust/qemu-api/rustfmt.toml | 1 +
rust/qemu-api/src/bindings.rs | 7 ++
rust/qemu-api/src/definitions.rs | 107 +++++++++++++++++++++++++
rust/qemu-api/src/device_class.rs | 128 ++++++++++++++++++++++++++++++
rust/qemu-api/src/lib.rs | 100 +++++++++++++++++++++++
rust/qemu-api/src/tests.rs | 48 +++++++++++
rust/rustfmt.toml | 7 ++
15 files changed, 498 insertions(+)
create mode 100644 rust/qemu-api/.gitignore
create mode 100644 rust/qemu-api/Cargo.lock
create mode 100644 rust/qemu-api/Cargo.toml
create mode 100644 rust/qemu-api/README.md
create mode 100644 rust/qemu-api/build.rs
create mode 100644 rust/qemu-api/meson.build
create mode 120000 rust/qemu-api/rustfmt.toml
create mode 100644 rust/qemu-api/src/bindings.rs
create mode 100644 rust/qemu-api/src/definitions.rs
create mode 100644 rust/qemu-api/src/device_class.rs
create mode 100644 rust/qemu-api/src/lib.rs
create mode 100644 rust/qemu-api/src/tests.rs
create mode 100644 rust/rustfmt.toml
diff --git a/MAINTAINERS b/MAINTAINERS
index 5f0b586dd4..1789bcfd9b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3342,6 +3342,12 @@ F: hw/core/register.c
F: include/hw/register.h
F: include/hw/registerfields.h
+Rust
+M: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+S: Maintained
+F: rust/qemu-api
+F: rust/rustfmt.toml
+
SLIRP
M: Samuel Thibault <samuel.thibault@ens-lyon.org>
S: Maintained
diff --git a/rust/meson.build b/rust/meson.build
index e69de29bb2..a903c7c602 100644
--- a/rust/meson.build
+++ b/rust/meson.build
@@ -0,0 +1,13 @@
+add_languages('rust', required: true)
+
+_lib_bindings_rs = static_library(
+ '_bindings_rs',
+ bindings_rs,
+ gnu_symbol_visibility: 'hidden',
+ rust_abi: 'rust',
+ rust_args: rust_args + [
+ '--edition', '2021',
+ ],
+)
+
+subdir('qemu-api')
diff --git a/rust/qemu-api/.gitignore b/rust/qemu-api/.gitignore
new file mode 100644
index 0000000000..71eaff2035
--- /dev/null
+++ b/rust/qemu-api/.gitignore
@@ -0,0 +1,2 @@
+# Ignore generated bindings file overrides.
+src/bindings.rs.inc
diff --git a/rust/qemu-api/Cargo.lock b/rust/qemu-api/Cargo.lock
new file mode 100644
index 0000000000..e9c51a243a
--- /dev/null
+++ b/rust/qemu-api/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "qemu_api"
+version = "0.1.0"
diff --git a/rust/qemu-api/Cargo.toml b/rust/qemu-api/Cargo.toml
new file mode 100644
index 0000000000..51260cbe42
--- /dev/null
+++ b/rust/qemu-api/Cargo.toml
@@ -0,0 +1,23 @@
+[package]
+name = "qemu_api"
+version = "0.1.0"
+edition = "2021"
+authors = ["Manos Pitsidianakis <manos.pitsidianakis@linaro.org>"]
+license = "GPL-2.0 OR GPL-3.0-or-later"
+readme = "README.md"
+homepage = "https://www.qemu.org"
+description = "Rust bindings for QEMU"
+repository = "https://gitlab.com/qemu-project/qemu/"
+resolver = "2"
+publish = false
+keywords = []
+categories = []
+
+[dependencies]
+
+[features]
+default = ["allocator"]
+allocator = []
+
+# Do not include in any global workspace
+[workspace]
diff --git a/rust/qemu-api/README.md b/rust/qemu-api/README.md
new file mode 100644
index 0000000000..7588fa29ef
--- /dev/null
+++ b/rust/qemu-api/README.md
@@ -0,0 +1,17 @@
+# QEMU bindings and API wrappers
+
+This library exports helper Rust types, Rust macros and C FFI bindings for internal QEMU APIs.
+
+The C bindings can be generated with `bindgen`, using this build target:
+
+```console
+$ ninja bindings.rs
+```
+
+## Generate Rust documentation
+
+To generate docs for this crate, including private items:
+
+```sh
+cargo doc --no-deps --document-private-items
+```
diff --git a/rust/qemu-api/build.rs b/rust/qemu-api/build.rs
new file mode 100644
index 0000000000..2f57c2b3d4
--- /dev/null
+++ b/rust/qemu-api/build.rs
@@ -0,0 +1,13 @@
+// Copyright 2024 Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0 OR GPL-3.0-or-later
+
+use std::path::Path;
+
+fn main() {
+ if !Path::new("src/bindings.rs.inc").exists() {
+ panic!(
+ "No generated C bindings found! Either build them manually with bindgen or with meson \
+ (`ninja bindings.rs`) and copy them to src/bindings.rs.inc, or build through meson."
+ );
+ }
+}
diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build
new file mode 100644
index 0000000000..7992dc64ce
--- /dev/null
+++ b/rust/qemu-api/meson.build
@@ -0,0 +1,19 @@
+add_languages('rust', required: true)
+
+_qemu_api_rs = static_library(
+ 'qemu_api',
+ [files('src/lib.rs')],
+ gnu_symbol_visibility: 'hidden',
+ rust_abi: 'rust',
+ rust_args: rust_args + [
+ '--edition', '2021',
+ '--cfg', 'MESON_BINDINGS_RS',
+ ],
+ link_with: [
+ _lib_bindings_rs,
+ ],
+)
+
+qemu_api = declare_dependency(
+ link_with: _qemu_api_rs,
+)
diff --git a/rust/qemu-api/rustfmt.toml b/rust/qemu-api/rustfmt.toml
new file mode 120000
index 0000000000..39f97b043b
--- /dev/null
+++ b/rust/qemu-api/rustfmt.toml
@@ -0,0 +1 @@
+../rustfmt.toml
\ No newline at end of file
diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs
new file mode 100644
index 0000000000..fb595f1469
--- /dev/null
+++ b/rust/qemu-api/src/bindings.rs
@@ -0,0 +1,7 @@
+// Copyright 2024 Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0 OR GPL-3.0-or-later
+#[cfg(not(MESON_BINDINGS_RS))]
+include!("bindings.rs.inc");
+
+#[cfg(MESON_BINDINGS_RS)]
+pub use ::_bindings_rs::*;
diff --git a/rust/qemu-api/src/definitions.rs b/rust/qemu-api/src/definitions.rs
new file mode 100644
index 0000000000..5b9e92fda8
--- /dev/null
+++ b/rust/qemu-api/src/definitions.rs
@@ -0,0 +1,107 @@
+// Copyright 2024 Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0 OR GPL-3.0-or-later
+
+//! Definitions required by QEMU when registering a device.
+
+#[macro_export]
+macro_rules! module_init {
+ ($func:expr, $type:expr) => {
+ #[used]
+ #[cfg_attr(target_os = "linux", link_section = ".ctors")]
+ #[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
+ #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
+ pub static LOAD_MODULE: extern "C" fn() = {
+ assert!($type < $crate::bindings::module_init_type_MODULE_INIT_MAX);
+
+ extern "C" fn __load() {
+ // ::std::panic::set_hook(::std::boxed::Box::new(|_| {}));
+
+ unsafe {
+ $crate::bindings::register_module_init(Some($func), $type);
+ }
+ }
+
+ __load
+ };
+ };
+ (qom: $func:ident => $body:block) => {
+ // NOTE: To have custom identifiers for the ctor func we need to either supply
+ // them directly as a macro argument or create them with a proc macro.
+ #[used]
+ #[cfg_attr(target_os = "linux", link_section = ".ctors")]
+ #[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
+ #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
+ pub static LOAD_MODULE: extern "C" fn() = {
+ extern "C" fn __load() {
+ // ::std::panic::set_hook(::std::boxed::Box::new(|_| {}));
+ #[no_mangle]
+ unsafe extern "C" fn $func() {
+ $body
+ }
+
+ unsafe {
+ $crate::bindings::register_module_init(
+ Some($func),
+ $crate::bindings::module_init_type_MODULE_INIT_QOM,
+ );
+ }
+ }
+
+ __load
+ };
+ };
+}
+
+#[macro_export]
+macro_rules! type_info {
+ ($(#[$outer:meta])*
+ $name:ident: $t:ty,
+ $(name: $tname:expr,)*
+ $(parent: $pname:expr,)*
+ $(instance_init: $ii_fn:expr,)*
+ $(instance_post_init: $ipi_fn:expr,)*
+ $(instance_finalize: $if_fn:expr,)*
+ $(abstract_: $a_val:expr,)*
+ $(class_init: $ci_fn:expr,)*
+ $(class_base_init: $cbi_fn:expr,)*
+ ) => {
+ #[used]
+ $(#[$outer])*
+ pub static $name: $crate::bindings::TypeInfo = $crate::bindings::TypeInfo {
+ $(name: {
+ #[used]
+ static TYPE_NAME: &::core::ffi::CStr = $tname;
+ $tname.as_ptr()
+ },)*
+ $(parent: {
+ #[used]
+ static PARENT_TYPE_NAME: &::core::ffi::CStr = $pname;
+ $pname.as_ptr()
+ },)*
+ instance_size: ::core::mem::size_of::<$t>(),
+ instance_align: ::core::mem::align_of::<$t>(),
+ $(
+ instance_init: $ii_fn,
+ )*
+ $(
+ instance_post_init: $ipi_fn,
+ )*
+ $(
+ instance_finalize: $if_fn,
+ )*
+ $(
+ abstract_: $a_val,
+ )*
+ class_size: 0,
+ $(
+ class_init: $ci_fn,
+ )*
+ $(
+ class_base_init: $cbi_fn,
+ )*
+ class_data: core::ptr::null_mut(),
+ interfaces: core::ptr::null_mut(),
+ ..unsafe { MaybeUninit::<$crate::bindings::TypeInfo>::zeroed().assume_init() }
+ };
+ }
+}
diff --git a/rust/qemu-api/src/device_class.rs b/rust/qemu-api/src/device_class.rs
new file mode 100644
index 0000000000..f8d4c04e03
--- /dev/null
+++ b/rust/qemu-api/src/device_class.rs
@@ -0,0 +1,128 @@
+// Copyright 2024 Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0 OR GPL-3.0-or-later
+
+use std::sync::OnceLock;
+
+use crate::bindings::Property;
+
+#[macro_export]
+macro_rules! device_class_init {
+ ($func:ident, props => $props:ident, realize_fn => $realize_fn:expr, reset_fn => $reset_fn:expr, vmsd => $vmsd:ident$(,)*) => {
+ #[no_mangle]
+ pub unsafe extern "C" fn $func(
+ klass: *mut $crate::bindings::ObjectClass,
+ _: *mut ::core::ffi::c_void,
+ ) {
+ let mut dc =
+ ::core::ptr::NonNull::new(klass.cast::<$crate::bindings::DeviceClass>()).unwrap();
+ dc.as_mut().realize = $realize_fn;
+ dc.as_mut().reset = $reset_fn;
+ dc.as_mut().vmsd = &$vmsd;
+ $crate::bindings::device_class_set_props(dc.as_mut(), $props.as_mut_ptr());
+ }
+ };
+}
+
+#[macro_export]
+macro_rules! define_property {
+ ($name:expr, $state:ty, $field:expr, $prop:expr, $type:expr, default = $defval:expr$(,)*) => {
+ $crate::bindings::Property {
+ name: {
+ #[used]
+ static _TEMP: &::core::ffi::CStr = $name;
+ _TEMP.as_ptr()
+ },
+ info: $prop,
+ offset: ::core::mem::offset_of!($state, $field)
+ .try_into()
+ .expect("Could not fit offset value to type"),
+ bitnr: 0,
+ bitmask: 0,
+ set_default: true,
+ defval: $crate::bindings::Property__bindgen_ty_1 { u: $defval.into() },
+ arrayoffset: 0,
+ arrayinfo: ::core::ptr::null(),
+ arrayfieldsize: 0,
+ link_type: ::core::ptr::null(),
+ }
+ };
+ ($name:expr, $state:ty, $field:expr, $prop:expr, $type:expr$(,)*) => {
+ $crate::bindings::Property {
+ name: {
+ #[used]
+ static _TEMP: &::core::ffi::CStr = $name;
+ _TEMP.as_ptr()
+ },
+ info: $prop,
+ offset: ::core::mem::offset_of!($state, $field)
+ .try_into()
+ .expect("Could not fit offset value to type"),
+ bitnr: 0,
+ bitmask: 0,
+ set_default: false,
+ defval: $crate::bindings::Property__bindgen_ty_1 { i: 0 },
+ arrayoffset: 0,
+ arrayinfo: ::core::ptr::null(),
+ arrayfieldsize: 0,
+ link_type: ::core::ptr::null(),
+ }
+ };
+}
+
+#[repr(C)]
+pub struct Properties<const N: usize>(pub OnceLock<[Property; N]>, pub fn() -> [Property; N]);
+
+impl<const N: usize> Properties<N> {
+ pub fn as_mut_ptr(&mut self) -> *mut Property {
+ _ = self.0.get_or_init(self.1);
+ self.0.get_mut().unwrap().as_mut_ptr()
+ }
+}
+
+#[macro_export]
+macro_rules! declare_properties {
+ ($ident:ident, $($prop:expr),*$(,)*) => {
+
+ const fn _calc_prop_len() -> usize {
+ let mut len = 1;
+ $({
+ _ = stringify!($prop);
+ len += 1;
+ })*
+ len
+ }
+ const PROP_LEN: usize = _calc_prop_len();
+
+ #[no_mangle]
+ fn _make_properties() -> [$crate::bindings::Property; PROP_LEN] {
+ [
+ $($prop),*,
+ unsafe { ::core::mem::MaybeUninit::<$crate::bindings::Property>::zeroed().assume_init() },
+ ]
+ }
+
+ #[no_mangle]
+ pub static mut $ident: $crate::device_class::Properties<PROP_LEN> = $crate::device_class::Properties(::std::sync::OnceLock::new(), _make_properties);
+ };
+}
+
+#[macro_export]
+macro_rules! vm_state_description {
+ ($(#[$outer:meta])*
+ $name:ident,
+ $(name: $vname:expr,)*
+ $(unmigratable: $um_val:expr,)*
+ ) => {
+ #[used]
+ $(#[$outer])*
+ pub static $name: $crate::bindings::VMStateDescription = $crate::bindings::VMStateDescription {
+ $(name: {
+ #[used]
+ static VMSTATE_NAME: &::core::ffi::CStr = $vname;
+ $vname.as_ptr()
+ },)*
+ unmigratable: true,
+ ..unsafe { ::core::mem::MaybeUninit::<$crate::bindings::VMStateDescription>::zeroed().assume_init() }
+ };
+ }
+}
diff --git a/rust/qemu-api/src/lib.rs b/rust/qemu-api/src/lib.rs
new file mode 100644
index 0000000000..6f02ac45e2
--- /dev/null
+++ b/rust/qemu-api/src/lib.rs
@@ -0,0 +1,100 @@
+// Copyright 2024 Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0 OR GPL-3.0-or-later
+
+#![doc = include_str!("../README.md")]
+
+#[cfg(MESON_BINDINGS_RS)]
+extern crate _bindings_rs;
+
+#[cfg_attr(not(MESON_BINDINGS_RS), allow(
+ improper_ctypes_definitions,
+ improper_ctypes,
+ non_camel_case_types,
+ non_snake_case,
+ non_upper_case_globals
+))]
+#[cfg_attr(not(MESON_BINDINGS_RS), allow(
+ clippy::missing_const_for_fn,
+ clippy::too_many_arguments,
+ clippy::approx_constant,
+ clippy::use_self,
+ clippy::useless_transmute,
+ clippy::missing_safety_doc,
+))]
+#[cfg_attr(not(MESON_BINDINGS_RS), rustfmt::skip)]
+pub mod bindings;
+
+pub mod definitions;
+pub mod device_class;
+
+#[cfg(test)]
+mod tests;
+
+use std::alloc::{GlobalAlloc, Layout};
+
+extern "C" {
+ pub fn g_aligned_alloc0(
+ n_blocks: bindings::gsize,
+ n_block_bytes: bindings::gsize,
+ alignment: bindings::gsize,
+ ) -> bindings::gpointer;
+ pub fn g_aligned_free(mem: bindings::gpointer);
+ pub fn g_malloc0(n_bytes: bindings::gsize) -> bindings::gpointer;
+ pub fn g_free(mem: bindings::gpointer);
+}
+
+/// An allocator that uses the same allocator as QEMU in C.
+///
+/// It is enabled by default with the `allocator` feature.
+///
+/// To set it up manually as a global allocator in your crate:
+///
+/// ```ignore
+/// use qemu_api::QemuAllocator;
+///
+/// #[global_allocator]
+/// static GLOBAL: QemuAllocator = QemuAllocator::new();
+/// ```
+#[derive(Clone, Copy, Debug)]
+#[repr(C)]
+pub struct QemuAllocator {
+ _unused: [u8; 0],
+}
+
+#[cfg_attr(feature = "allocator", global_allocator)]
+pub static GLOBAL: QemuAllocator = QemuAllocator::new();
+
+impl QemuAllocator {
+ pub const fn new() -> Self {
+ Self { _unused: [] }
+ }
+}
+
+impl Default for QemuAllocator {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+unsafe impl GlobalAlloc for QemuAllocator {
+ unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+ if layout.align() == 0 {
+ g_malloc0(layout.size().try_into().unwrap()).cast::<u8>()
+ } else {
+ g_aligned_alloc0(
+ layout.size().try_into().unwrap(),
+ 1,
+ layout.align().try_into().unwrap(),
+ )
+ .cast::<u8>()
+ }
+ }
+
+ unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+ if layout.align() == 0 {
+ g_free(ptr.cast::<_>())
+ } else {
+ g_aligned_free(ptr.cast::<_>())
+ }
+ }
+}
diff --git a/rust/qemu-api/src/tests.rs b/rust/qemu-api/src/tests.rs
new file mode 100644
index 0000000000..88c26308ee
--- /dev/null
+++ b/rust/qemu-api/src/tests.rs
@@ -0,0 +1,48 @@
+// Copyright 2024 Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0 OR GPL-3.0-or-later
+
+use crate::{
+ bindings::*, declare_properties, define_property, device_class_init, vm_state_description,
+};
+
+#[test]
+fn test_device_decl_macros() {
+ // Test that macros can compile.
+ vm_state_description! {
+ VMSTATE,
+ name: c"name",
+ unmigratable: true,
+ }
+
+ #[repr(C)]
+ pub struct DummyState {
+ pub char_backend: CharBackend,
+ pub migrate_clock: bool,
+ }
+
+ declare_properties! {
+ DUMMY_PROPERTIES,
+ define_property!(
+ c"chardev",
+ DummyState,
+ char_backend,
+ unsafe { &qdev_prop_chr },
+ CharBackend
+ ),
+ define_property!(
+ c"migrate-clk",
+ DummyState,
+ migrate_clock,
+ unsafe { &qdev_prop_bool },
+ bool
+ ),
+ }
+
+ device_class_init! {
+ dummy_class_init,
+ props => DUMMY_PROPERTIES,
+ realize_fn => None,
+ reset_fn => None,
+ vmsd => VMSTATE,
+ }
+}
diff --git a/rust/rustfmt.toml b/rust/rustfmt.toml
new file mode 100644
index 0000000000..ebecb99fe0
--- /dev/null
+++ b/rust/rustfmt.toml
@@ -0,0 +1,7 @@
+edition = "2021"
+format_generated_files = false
+format_code_in_doc_comments = true
+format_strings = true
+imports_granularity = "Crate"
+group_imports = "StdExternalCrate"
+wrap_comments = true
--
γαῖα πυρί μιχθήτω
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [RFC PATCH v5 7/8] rust: add PL011 device model
2024-07-22 11:43 [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Manos Pitsidianakis
` (5 preceding siblings ...)
2024-07-22 11:43 ` [RFC PATCH v5 6/8] rust: add crate to expose bindings and interfaces Manos Pitsidianakis
@ 2024-07-22 11:43 ` Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 8/8] rust/pl011: vendor dependencies Manos Pitsidianakis
2024-07-23 15:07 ` [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Paolo Bonzini
8 siblings, 0 replies; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-22 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: Stefan Hajnoczi, Mads Ynddal, Peter Maydell, Alex Bennée,
Daniel P. Berrangé, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé, Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson,
Paolo Bonzini, qemu-arm
This commit adds a re-implementation of hw/char/pl011.c in Rust.
How to build:
1. Configure a QEMU build with:
--enable-system --target-list=aarch64-softmmu --enable-rust
2. Launching a VM with qemu-system-aarch64 should use the Rust version
of the pl011 device
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
MAINTAINERS | 5 +
hw/arm/Kconfig | 33 +-
rust/Kconfig | 1 +
rust/hw/Kconfig | 2 +
rust/hw/char/Kconfig | 3 +
rust/hw/char/meson.build | 1 +
rust/hw/char/pl011/.gitignore | 2 +
rust/hw/char/pl011/Cargo.lock | 123 ++++++
rust/hw/char/pl011/Cargo.toml | 26 ++
rust/hw/char/pl011/README.md | 31 ++
rust/hw/char/pl011/meson.build | 24 +
rust/hw/char/pl011/rustfmt.toml | 1 +
rust/hw/char/pl011/src/definitions.rs | 48 ++
rust/hw/char/pl011/src/device.rs | 541 +++++++++++++++++++++++
rust/hw/char/pl011/src/device_class.rs | 58 +++
rust/hw/char/pl011/src/lib.rs | 584 +++++++++++++++++++++++++
rust/hw/char/pl011/src/memory_ops.rs | 45 ++
rust/hw/meson.build | 1 +
rust/meson.build | 2 +
19 files changed, 1520 insertions(+), 11 deletions(-)
create mode 100644 rust/hw/Kconfig
create mode 100644 rust/hw/char/Kconfig
create mode 100644 rust/hw/char/meson.build
create mode 100644 rust/hw/char/pl011/.gitignore
create mode 100644 rust/hw/char/pl011/Cargo.lock
create mode 100644 rust/hw/char/pl011/Cargo.toml
create mode 100644 rust/hw/char/pl011/README.md
create mode 100644 rust/hw/char/pl011/meson.build
create mode 120000 rust/hw/char/pl011/rustfmt.toml
create mode 100644 rust/hw/char/pl011/src/definitions.rs
create mode 100644 rust/hw/char/pl011/src/device.rs
create mode 100644 rust/hw/char/pl011/src/device_class.rs
create mode 100644 rust/hw/char/pl011/src/lib.rs
create mode 100644 rust/hw/char/pl011/src/memory_ops.rs
create mode 100644 rust/hw/meson.build
diff --git a/MAINTAINERS b/MAINTAINERS
index 1789bcfd9b..0af4ef58ed 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1187,6 +1187,11 @@ F: include/hw/*/microbit*.h
F: tests/qtest/microbit-test.c
F: docs/system/arm/nrf.rst
+ARM PL011 Rust device
+M: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+S: Maintained
+F: rust/hw/char/pl011/
+
AVR Machines
-------------
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 1ad60da7aa..45438c1bc4 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -20,7 +20,8 @@ config ARM_VIRT
select PCI_EXPRESS
select PCI_EXPRESS_GENERIC_BRIDGE
select PFLASH_CFI01
- select PL011 # UART
+ select PL011 if !HAVE_RUST # UART
+ select X_PL011_RUST if HAVE_RUST # UART
select PL031 # RTC
select PL061 # GPIO
select GPIO_PWR
@@ -80,7 +81,8 @@ config HIGHBANK
select AHCI
select ARM_TIMER # sp804
select ARM_V7M
- select PL011 # UART
+ select PL011 if !HAVE_RUST # UART
+ select X_PL011_RUST if HAVE_RUST # UART
select PL022 # SPI
select PL031 # RTC
select PL061 # GPIO
@@ -93,7 +95,8 @@ config INTEGRATOR
depends on TCG && ARM
select ARM_TIMER
select INTEGRATOR_DEBUG
- select PL011 # UART
+ select PL011 if !HAVE_RUST # UART
+ select X_PL011_RUST if HAVE_RUST # UART
select PL031 # RTC
select PL041 # audio
select PL050 # keyboard/mouse
@@ -119,7 +122,8 @@ config MUSCA
default y
depends on TCG && ARM
select ARMSSE
- select PL011
+ select PL011 if !HAVE_RUST # UART
+ select X_PL011_RUST if HAVE_RUST # UART
select PL031
select SPLIT_IRQ
select UNIMP
@@ -228,7 +232,8 @@ config Z2
depends on TCG && ARM
select PFLASH_CFI01
select WM8750
- select PL011 # UART
+ select PL011 if !HAVE_RUST # UART
+ select X_PL011_RUST if HAVE_RUST # UART
select PXA2XX
config REALVIEW
@@ -248,7 +253,8 @@ config REALVIEW
select WM8750 # audio codec
select LSI_SCSI_PCI
select PCI
- select PL011 # UART
+ select PL011 if !HAVE_RUST # UART
+ select X_PL011_RUST if HAVE_RUST # UART
select PL031 # RTC
select PL041 # audio codec
select PL050 # keyboard/mouse
@@ -273,7 +279,8 @@ config SBSA_REF
select PCI_EXPRESS
select PCI_EXPRESS_GENERIC_BRIDGE
select PFLASH_CFI01
- select PL011 # UART
+ select PL011 if !HAVE_RUST # UART
+ select X_PL011_RUST if HAVE_RUST # UART
select PL031 # RTC
select PL061 # GPIO
select USB_XHCI_SYSBUS
@@ -297,7 +304,8 @@ config STELLARIS
select ARM_V7M
select CMSDK_APB_WATCHDOG
select I2C
- select PL011 # UART
+ select PL011 if !HAVE_RUST # UART
+ select X_PL011_RUST if HAVE_RUST # UART
select PL022 # SPI
select PL061 # GPIO
select SSD0303 # OLED display
@@ -356,7 +364,8 @@ config VEXPRESS
select ARM_TIMER # sp804
select LAN9118
select PFLASH_CFI01
- select PL011 # UART
+ select PL011 if !HAVE_RUST # UART
+ select X_PL011_RUST if HAVE_RUST # UART
select PL041 # audio codec
select PL181 # display
select REALVIEW
@@ -440,7 +449,8 @@ config RASPI
default y
depends on TCG && ARM
select FRAMEBUFFER
- select PL011 # UART
+ select PL011 if !HAVE_RUST # UART
+ select X_PL011_RUST if HAVE_RUST # UART
select SDHCI
select USB_DWC2
select BCM2835_SPI
@@ -515,7 +525,8 @@ config XLNX_VERSAL
select ARM_GIC
select CPU_CLUSTER
select DEVICE_TREE
- select PL011
+ select PL011 if !HAVE_RUST # UART
+ select X_PL011_RUST if HAVE_RUST # UART
select CADENCE
select VIRTIO_MMIO
select UNIMP
diff --git a/rust/Kconfig b/rust/Kconfig
index e69de29bb2..f9f5c39098 100644
--- a/rust/Kconfig
+++ b/rust/Kconfig
@@ -0,0 +1 @@
+source hw/Kconfig
diff --git a/rust/hw/Kconfig b/rust/hw/Kconfig
new file mode 100644
index 0000000000..4d934f30af
--- /dev/null
+++ b/rust/hw/Kconfig
@@ -0,0 +1,2 @@
+# devices Kconfig
+source char/Kconfig
diff --git a/rust/hw/char/Kconfig b/rust/hw/char/Kconfig
new file mode 100644
index 0000000000..a1732a9e97
--- /dev/null
+++ b/rust/hw/char/Kconfig
@@ -0,0 +1,3 @@
+config X_PL011_RUST
+ bool
+ default y if HAVE_RUST
diff --git a/rust/hw/char/meson.build b/rust/hw/char/meson.build
new file mode 100644
index 0000000000..5716dc43ef
--- /dev/null
+++ b/rust/hw/char/meson.build
@@ -0,0 +1 @@
+subdir('pl011')
diff --git a/rust/hw/char/pl011/.gitignore b/rust/hw/char/pl011/.gitignore
new file mode 100644
index 0000000000..71eaff2035
--- /dev/null
+++ b/rust/hw/char/pl011/.gitignore
@@ -0,0 +1,2 @@
+# Ignore generated bindings file overrides.
+src/bindings.rs.inc
diff --git a/rust/hw/char/pl011/Cargo.lock b/rust/hw/char/pl011/Cargo.lock
new file mode 100644
index 0000000000..1af92fb16b
--- /dev/null
+++ b/rust/hw/char/pl011/Cargo.lock
@@ -0,0 +1,123 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "arbitrary-int"
+version = "1.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c84fc003e338a6f69fbd4f7fe9f92b535ff13e9af8997f3b14b6ddff8b1df46d"
+
+[[package]]
+name = "bilge"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc707ed8ebf81de5cd6c7f48f54b4c8621760926cdf35a57000747c512e67b57"
+dependencies = [
+ "arbitrary-int",
+ "bilge-impl",
+]
+
+[[package]]
+name = "bilge-impl"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "feb11e002038ad243af39c2068c8a72bcf147acf05025dcdb916fcc000adb2d8"
+dependencies = [
+ "itertools",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "either"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
+
+[[package]]
+name = "itertools"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "pl011"
+version = "0.1.0"
+dependencies = [
+ "bilge",
+ "qemu_api",
+]
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.84"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "qemu_api"
+version = "0.1.0"
+
+[[package]]
+name = "quote"
+version = "1.0.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.66"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
diff --git a/rust/hw/char/pl011/Cargo.toml b/rust/hw/char/pl011/Cargo.toml
new file mode 100644
index 0000000000..67a6973da6
--- /dev/null
+++ b/rust/hw/char/pl011/Cargo.toml
@@ -0,0 +1,26 @@
+[package]
+name = "pl011"
+version = "0.1.0"
+edition = "2021"
+authors = ["Manos Pitsidianakis <manos.pitsidianakis@linaro.org>"]
+license = "GPL-2.0 OR GPL-3.0-or-later"
+readme = "README.md"
+homepage = "https://www.qemu.org"
+description = "pl011 device model for QEMU"
+repository = "https://gitlab.com/epilys/rust-for-qemu"
+resolver = "2"
+publish = false
+keywords = []
+categories = []
+
+[lib]
+crate-type = ["staticlib"]
+
+[dependencies]
+arbitrary-int = { version = "1.2.7" }
+bilge = { version = "0.2.0" }
+bilge-impl = { version = "0.2.0" }
+qemu_api = { path = "../../../qemu-api" }
+
+# Do not include in any global workspace
+[workspace]
diff --git a/rust/hw/char/pl011/README.md b/rust/hw/char/pl011/README.md
new file mode 100644
index 0000000000..cd7dea3163
--- /dev/null
+++ b/rust/hw/char/pl011/README.md
@@ -0,0 +1,31 @@
+# PL011 QEMU Device Model
+
+This library implements a device model for the PrimeCell® UART (PL011)
+device in QEMU.
+
+## Build static lib
+
+Host build target must be explicitly specified:
+
+```sh
+cargo build --target x86_64-unknown-linux-gnu
+```
+
+Replace host target triplet if necessary.
+
+## Generate Rust documentation
+
+To generate docs for this crate, including private items:
+
+```sh
+cargo doc --no-deps --document-private-items --target x86_64-unknown-linux-gnu
+```
+
+To include direct dependencies like `bilge` (bitmaps for register types):
+
+```sh
+cargo tree --depth 1 -e normal --prefix none \
+ | cut -d' ' -f1 \
+ | xargs printf -- '-p %s\n' \
+ | xargs cargo doc --no-deps --document-private-items --target x86_64-unknown-linux-gnu
+```
diff --git a/rust/hw/char/pl011/meson.build b/rust/hw/char/pl011/meson.build
new file mode 100644
index 0000000000..427788da6e
--- /dev/null
+++ b/rust/hw/char/pl011/meson.build
@@ -0,0 +1,24 @@
+if not config_host_data.get('CONFIG_HAVE_RUST')
+ subdir_done()
+endif
+
+add_languages('rust', required: true)
+subdir('vendor')
+
+_libpl011_rs = static_library(
+ 'pl011',
+ files('src/lib.rs'),
+ rust_abi: 'c',
+ rust_args: rust_args + [
+ '--edition', '2021',
+ ],
+ dependencies: [
+ dep_bilge,
+ dep_bilge_impl,
+ qemu_api,
+ ],
+)
+
+specific_ss.add(when: 'CONFIG_X_PL011_RUST', if_true: [declare_dependency(
+ link_whole: [_libpl011_rs],
+)])
diff --git a/rust/hw/char/pl011/rustfmt.toml b/rust/hw/char/pl011/rustfmt.toml
new file mode 120000
index 0000000000..39f97b043b
--- /dev/null
+++ b/rust/hw/char/pl011/rustfmt.toml
@@ -0,0 +1 @@
+../rustfmt.toml
\ No newline at end of file
diff --git a/rust/hw/char/pl011/src/definitions.rs b/rust/hw/char/pl011/src/definitions.rs
new file mode 100644
index 0000000000..d7958baa83
--- /dev/null
+++ b/rust/hw/char/pl011/src/definitions.rs
@@ -0,0 +1,48 @@
+// Copyright 2024 Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0 OR GPL-3.0-or-later
+
+//! Definitions required by QEMU when registering the device.
+
+use core::{mem::MaybeUninit, ptr::NonNull};
+
+use qemu_api::bindings::*;
+
+use crate::{device::PL011State, device_class::pl011_class_init};
+
+#[used]
+#[no_mangle]
+pub static TYPE_PL011: &std::ffi::CStr = c"pl011";
+
+qemu_api::type_info! {
+ PL011_ARM_INFO: PL011State,
+ name: c"pl011",
+ parent: TYPE_SYS_BUS_DEVICE,
+ instance_init: Some(pl011_init),
+ abstract_: false,
+ class_init: Some(pl011_class_init),
+}
+
+#[used]
+pub static VMSTATE_PL011: VMStateDescription = VMStateDescription {
+ name: PL011_ARM_INFO.name,
+ unmigratable: true,
+ ..unsafe { MaybeUninit::<VMStateDescription>::zeroed().assume_init() }
+};
+
+/// # Safety
+///
+/// We expect the FFI user of this function to pass a valid pointer, that has
+/// the same size as [`PL011State`]. We also expect the device is
+/// readable/writeable from one thread at any time.
+#[no_mangle]
+pub unsafe extern "C" fn pl011_init(obj: *mut Object) {
+ assert!(!obj.is_null());
+ let mut state = NonNull::new_unchecked(obj.cast::<PL011State>());
+ state.as_mut().init();
+}
+
+qemu_api::module_init! {
+ qom: register_type => {
+ type_register_static(&PL011_ARM_INFO);
+ }
+}
diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs
new file mode 100644
index 0000000000..3643b7bdee
--- /dev/null
+++ b/rust/hw/char/pl011/src/device.rs
@@ -0,0 +1,541 @@
+// Copyright 2024 Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0 OR GPL-3.0-or-later
+
+use core::{
+ ffi::{c_int, c_uchar, c_uint, c_void, CStr},
+ ptr::{addr_of, addr_of_mut, NonNull},
+};
+
+use qemu_api::bindings::{self, *};
+
+use crate::{
+ definitions::PL011_ARM_INFO,
+ memory_ops::PL011_OPS,
+ registers::{self, Interrupt},
+ RegisterOffset,
+};
+
+static PL011_ID_ARM: [c_uchar; 8] = [0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1];
+
+const DATA_BREAK: u32 = 1 << 10;
+
+/// QEMU sourced constant.
+pub const PL011_FIFO_DEPTH: usize = 16_usize;
+
+#[repr(C)]
+#[derive(Debug)]
+/// PL011 Device Model in QEMU
+pub struct PL011State {
+ pub parent_obj: SysBusDevice,
+ pub iomem: MemoryRegion,
+ pub readbuff: u32,
+ #[doc(alias = "fr")]
+ pub flags: registers::Flags,
+ #[doc(alias = "lcr")]
+ pub line_control: registers::LineControl,
+ #[doc(alias = "rsr")]
+ pub receive_status_error_clear: registers::ReceiveStatusErrorClear,
+ #[doc(alias = "cr")]
+ pub control: registers::Control,
+ pub dmacr: u32,
+ pub int_enabled: u32,
+ pub int_level: u32,
+ pub read_fifo: [u32; PL011_FIFO_DEPTH],
+ pub ilpr: u32,
+ pub ibrd: u32,
+ pub fbrd: u32,
+ pub ifl: u32,
+ pub read_pos: usize,
+ pub read_count: usize,
+ pub read_trigger: usize,
+ #[doc(alias = "chr")]
+ pub char_backend: CharBackend,
+ /// QEMU interrupts
+ ///
+ /// ```text
+ /// * sysbus MMIO region 0: device registers
+ /// * sysbus IRQ 0: `UARTINTR` (combined interrupt line)
+ /// * sysbus IRQ 1: `UARTRXINTR` (receive FIFO interrupt line)
+ /// * sysbus IRQ 2: `UARTTXINTR` (transmit FIFO interrupt line)
+ /// * sysbus IRQ 3: `UARTRTINTR` (receive timeout interrupt line)
+ /// * sysbus IRQ 4: `UARTMSINTR` (momem status interrupt line)
+ /// * sysbus IRQ 5: `UARTEINTR` (error interrupt line)
+ /// ```
+ #[doc(alias = "irq")]
+ pub interrupts: [qemu_irq; 6usize],
+ #[doc(alias = "clk")]
+ pub clock: NonNull<Clock>,
+ #[doc(alias = "migrate_clk")]
+ pub migrate_clock: bool,
+}
+
+#[used]
+pub static CLK_NAME: &CStr = c"clk";
+
+impl PL011State {
+ pub fn init(&mut self) {
+ // SAFETY:
+ //
+ // self and self.iomem are guaranteed to be valid at this point since callers
+ // must make sure the `self` reference is valid.
+ unsafe {
+ memory_region_init_io(
+ addr_of_mut!(self.iomem),
+ addr_of_mut!(*self).cast::<Object>(),
+ &PL011_OPS,
+ addr_of_mut!(*self).cast::<c_void>(),
+ PL011_ARM_INFO.name,
+ 0x1000,
+ );
+ let sbd = addr_of_mut!(*self).cast::<SysBusDevice>();
+ let dev = addr_of_mut!(*self).cast::<DeviceState>();
+ sysbus_init_mmio(sbd, addr_of_mut!(self.iomem));
+ for irq in self.interrupts.iter_mut() {
+ sysbus_init_irq(sbd, irq);
+ }
+ self.clock = NonNull::new(qdev_init_clock_in(
+ dev,
+ CLK_NAME.as_ptr(),
+ None, /* pl011_clock_update */
+ addr_of_mut!(*self).cast::<c_void>(),
+ ClockEvent_ClockUpdate,
+ ))
+ .unwrap();
+ }
+ }
+
+ pub fn read(&mut self, offset: hwaddr, _size: core::ffi::c_uint) -> u64 {
+ use RegisterOffset::*;
+
+ match RegisterOffset::try_from(offset) {
+ Err(v) if (0x3f8..0x400).contains(&v) => {
+ u64::from(PL011_ID_ARM[((offset - 0xfe0) >> 2) as usize])
+ }
+ Err(_) => {
+ // qemu_log_mask(LOG_GUEST_ERROR, "pl011_read: Bad offset 0x%x\n", (int)offset);
+ 0
+ }
+ Ok(DR) => {
+ // s->flags &= ~PL011_FLAG_RXFF;
+ self.flags.set_receive_fifo_full(false);
+ let c = self.read_fifo[self.read_pos];
+ if self.read_count > 0 {
+ self.read_count -= 1;
+ self.read_pos = (self.read_pos + 1) & (self.fifo_depth() - 1);
+ }
+ if self.read_count == 0 {
+ // self.flags |= PL011_FLAG_RXFE;
+ self.flags.set_receive_fifo_empty(true);
+ }
+ if self.read_count + 1 == self.read_trigger {
+ //self.int_level &= ~ INT_RX;
+ self.int_level &= !registers::INT_RX;
+ }
+ // Update error bits.
+ self.receive_status_error_clear = c.to_be_bytes()[3].into();
+ self.update();
+ // SAFETY: self.char_backend is a valid CharBackend instance after it's been
+ // initialized in realize().
+ unsafe { qemu_chr_fe_accept_input(&mut self.char_backend) };
+ c.into()
+ }
+ Ok(RSR) => u8::from(self.receive_status_error_clear).into(),
+ Ok(FR) => u16::from(self.flags).into(),
+ Ok(FBRD) => self.fbrd.into(),
+ Ok(ILPR) => self.ilpr.into(),
+ Ok(IBRD) => self.ibrd.into(),
+ Ok(LCR_H) => u16::from(self.line_control).into(),
+ Ok(CR) => {
+ // We exercise our self-control.
+ u16::from(self.control).into()
+ }
+ Ok(FLS) => self.ifl.into(),
+ Ok(IMSC) => self.int_enabled.into(),
+ Ok(RIS) => self.int_level.into(),
+ Ok(MIS) => u64::from(self.int_level & self.int_enabled),
+ Ok(ICR) => {
+ // "The UARTICR Register is the interrupt clear register and is write-only"
+ // Source: ARM DDI 0183G 3.3.13 Interrupt Clear Register, UARTICR
+ 0
+ }
+ Ok(DMACR) => self.dmacr.into(),
+ }
+ }
+
+ pub fn write(&mut self, offset: hwaddr, value: u64) {
+ // eprintln!("write offset {offset} value {value}");
+ use RegisterOffset::*;
+ let value: u32 = value as u32;
+ match RegisterOffset::try_from(offset) {
+ Err(_bad_offset) => {
+ eprintln!("write bad offset {offset} value {value}");
+ }
+ Ok(DR) => {
+ // ??? Check if transmitter is enabled.
+ let ch: u8 = value as u8;
+ // XXX this blocks entire thread. Rewrite to use
+ // qemu_chr_fe_write and background I/O callbacks
+
+ // SAFETY: self.char_backend is a valid CharBackend instance after it's been
+ // initialized in realize().
+ unsafe {
+ qemu_chr_fe_write_all(addr_of_mut!(self.char_backend), &ch, 1);
+ }
+ self.loopback_tx(value);
+ self.int_level |= registers::INT_TX;
+ self.update();
+ }
+ Ok(RSR) => {
+ self.receive_status_error_clear = 0.into();
+ }
+ Ok(FR) => {
+ // flag writes are ignored
+ }
+ Ok(ILPR) => {
+ self.ilpr = value;
+ }
+ Ok(IBRD) => {
+ self.ibrd = value;
+ }
+ Ok(FBRD) => {
+ self.fbrd = value;
+ }
+ Ok(LCR_H) => {
+ let value = value as u16;
+ let new_val: registers::LineControl = value.into();
+ // Reset the FIFO state on FIFO enable or disable
+ if bool::from(self.line_control.fifos_enabled())
+ ^ bool::from(new_val.fifos_enabled())
+ {
+ self.reset_fifo();
+ }
+ if self.line_control.send_break() ^ new_val.send_break() {
+ let mut break_enable: c_int = new_val.send_break().into();
+ // SAFETY: self.char_backend is a valid CharBackend instance after it's been
+ // initialized in realize().
+ unsafe {
+ qemu_chr_fe_ioctl(
+ addr_of_mut!(self.char_backend),
+ CHR_IOCTL_SERIAL_SET_BREAK as i32,
+ addr_of_mut!(break_enable).cast::<c_void>(),
+ );
+ }
+ self.loopback_break(break_enable > 0);
+ }
+ self.line_control = new_val;
+ self.set_read_trigger();
+ }
+ Ok(CR) => {
+ // ??? Need to implement the enable bit.
+ let value = value as u16;
+ self.control = value.into();
+ self.loopback_mdmctrl();
+ }
+ Ok(FLS) => {
+ self.ifl = value;
+ self.set_read_trigger();
+ }
+ Ok(IMSC) => {
+ self.int_enabled = value;
+ self.update();
+ }
+ Ok(RIS) => {}
+ Ok(MIS) => {}
+ Ok(ICR) => {
+ self.int_level &= !value;
+ self.update();
+ }
+ Ok(DMACR) => {
+ self.dmacr = value;
+ if value & 3 > 0 {
+ // qemu_log_mask(LOG_UNIMP, "pl011: DMA not implemented\n");
+ eprintln!("pl011: DMA not implemented");
+ }
+ }
+ }
+ }
+
+ #[inline]
+ fn loopback_tx(&mut self, value: u32) {
+ if !self.loopback_enabled() {
+ return;
+ }
+
+ // Caveat:
+ //
+ // In real hardware, TX loopback happens at the serial-bit level
+ // and then reassembled by the RX logics back into bytes and placed
+ // into the RX fifo. That is, loopback happens after TX fifo.
+ //
+ // Because the real hardware TX fifo is time-drained at the frame
+ // rate governed by the configured serial format, some loopback
+ // bytes in TX fifo may still be able to get into the RX fifo
+ // that could be full at times while being drained at software
+ // pace.
+ //
+ // In such scenario, the RX draining pace is the major factor
+ // deciding which loopback bytes get into the RX fifo, unless
+ // hardware flow-control is enabled.
+ //
+ // For simplicity, the above described is not emulated.
+ self.put_fifo(value);
+ }
+
+ fn loopback_mdmctrl(&mut self) {
+ if !self.loopback_enabled() {
+ return;
+ }
+
+ /*
+ * Loopback software-driven modem control outputs to modem status inputs:
+ * FR.RI <= CR.Out2
+ * FR.DCD <= CR.Out1
+ * FR.CTS <= CR.RTS
+ * FR.DSR <= CR.DTR
+ *
+ * The loopback happens immediately even if this call is triggered
+ * by setting only CR.LBE.
+ *
+ * CTS/RTS updates due to enabled hardware flow controls are not
+ * dealt with here.
+ */
+
+ //fr = s->flags & ~(PL011_FLAG_RI | PL011_FLAG_DCD |
+ // PL011_FLAG_DSR | PL011_FLAG_CTS);
+ //fr |= (cr & CR_OUT2) ? PL011_FLAG_RI : 0;
+ //fr |= (cr & CR_OUT1) ? PL011_FLAG_DCD : 0;
+ //fr |= (cr & CR_RTS) ? PL011_FLAG_CTS : 0;
+ //fr |= (cr & CR_DTR) ? PL011_FLAG_DSR : 0;
+ //
+ self.flags.set_ring_indicator(self.control.out_2());
+ self.flags.set_data_carrier_detect(self.control.out_1());
+ self.flags.set_clear_to_send(self.control.request_to_send());
+ self.flags
+ .set_data_set_ready(self.control.data_transmit_ready());
+
+ // Change interrupts based on updated FR
+ let mut il = self.int_level;
+
+ il &= !Interrupt::MS;
+ //il |= (fr & PL011_FLAG_DSR) ? INT_DSR : 0;
+ //il |= (fr & PL011_FLAG_DCD) ? INT_DCD : 0;
+ //il |= (fr & PL011_FLAG_CTS) ? INT_CTS : 0;
+ //il |= (fr & PL011_FLAG_RI) ? INT_RI : 0;
+
+ if self.flags.data_set_ready() {
+ il |= Interrupt::DSR as u32;
+ }
+ if self.flags.data_carrier_detect() {
+ il |= Interrupt::DCD as u32;
+ }
+ if self.flags.clear_to_send() {
+ il |= Interrupt::CTS as u32;
+ }
+ if self.flags.ring_indicator() {
+ il |= Interrupt::RI as u32;
+ }
+ self.int_level = il;
+ self.update();
+ }
+
+ fn loopback_break(&mut self, enable: bool) {
+ if enable {
+ self.loopback_tx(DATA_BREAK);
+ }
+ }
+
+ fn set_read_trigger(&mut self) {
+ //#if 0
+ // /* The docs say the RX interrupt is triggered when the FIFO exceeds
+ // the threshold. However linux only reads the FIFO in response to an
+ // interrupt. Triggering the interrupt when the FIFO is non-empty seems
+ // to make things work. */
+ // if (s->lcr & LCR_FEN)
+ // s->read_trigger = (s->ifl >> 1) & 0x1c;
+ // else
+ //#endif
+ self.read_trigger = 1;
+ }
+
+ pub fn realize(&mut self) {
+ // SAFETY: self.char_backend has the correct size and alignment for a
+ // CharBackend object, and its callbacks are of the correct types.
+ unsafe {
+ qemu_chr_fe_set_handlers(
+ addr_of_mut!(self.char_backend),
+ Some(pl011_can_receive),
+ Some(pl011_receive),
+ Some(pl011_event),
+ None,
+ addr_of_mut!(*self).cast::<c_void>(),
+ core::ptr::null_mut(),
+ true,
+ );
+ }
+ }
+
+ pub fn reset(&mut self) {
+ self.line_control.reset();
+ self.receive_status_error_clear.reset();
+ self.dmacr = 0;
+ self.int_enabled = 0;
+ self.int_level = 0;
+ self.ilpr = 0;
+ self.ibrd = 0;
+ self.fbrd = 0;
+ self.read_trigger = 1;
+ self.ifl = 0x12;
+ self.control.reset();
+ self.flags = 0.into();
+ self.reset_fifo();
+ }
+
+ pub fn reset_fifo(&mut self) {
+ self.read_count = 0;
+ self.read_pos = 0;
+
+ /* Reset FIFO flags */
+ self.flags.reset();
+ }
+
+ pub fn can_receive(&self) -> bool {
+ // trace_pl011_can_receive(s->lcr, s->read_count, r);
+ self.read_count < self.fifo_depth()
+ }
+
+ pub fn event(&mut self, event: QEMUChrEvent) {
+ if event == bindings::QEMUChrEvent_CHR_EVENT_BREAK && !self.fifo_enabled() {
+ self.put_fifo(DATA_BREAK);
+ self.receive_status_error_clear.set_break_error(true);
+ }
+ }
+
+ #[inline]
+ pub fn fifo_enabled(&self) -> bool {
+ matches!(self.line_control.fifos_enabled(), registers::Mode::FIFO)
+ }
+
+ #[inline]
+ pub fn loopback_enabled(&self) -> bool {
+ self.control.enable_loopback()
+ }
+
+ #[inline]
+ pub fn fifo_depth(&self) -> usize {
+ // Note: FIFO depth is expected to be power-of-2
+ if self.fifo_enabled() {
+ return PL011_FIFO_DEPTH;
+ }
+ 1
+ }
+
+ pub fn put_fifo(&mut self, value: c_uint) {
+ let depth = self.fifo_depth();
+ assert!(depth > 0);
+ let slot = (self.read_pos + self.read_count) & (depth - 1);
+ self.read_fifo[slot] = value;
+ self.read_count += 1;
+ // s->flags &= ~PL011_FLAG_RXFE;
+ self.flags.set_receive_fifo_empty(false);
+ if self.read_count == depth {
+ //s->flags |= PL011_FLAG_RXFF;
+ self.flags.set_receive_fifo_full(true);
+ }
+
+ if self.read_count == self.read_trigger {
+ self.int_level |= registers::INT_RX;
+ self.update();
+ }
+ }
+
+ pub fn update(&mut self) {
+ let flags = self.int_level & self.int_enabled;
+ for (irq, i) in self.interrupts.iter().zip(IRQMASK) {
+ // SAFETY: self.interrupts have been initialized in init().
+ unsafe { qemu_set_irq(*irq, i32::from(flags & i != 0)) };
+ }
+ }
+}
+
+/// Which bits in the interrupt status matter for each outbound IRQ line ?
+pub const IRQMASK: [u32; 6] = [
+ /* combined IRQ */
+ Interrupt::E
+ | Interrupt::MS
+ | Interrupt::RT as u32
+ | Interrupt::TX as u32
+ | Interrupt::RX as u32,
+ Interrupt::RX as u32,
+ Interrupt::TX as u32,
+ Interrupt::RT as u32,
+ Interrupt::MS,
+ Interrupt::E,
+];
+
+/// # Safety
+///
+/// We expect the FFI user of this function to pass a valid pointer, that has
+/// the same size as [`PL011State`]. We also expect the device is
+/// readable/writeable from one thread at any time.
+#[no_mangle]
+pub unsafe extern "C" fn pl011_can_receive(opaque: *mut c_void) -> c_int {
+ assert!(!opaque.is_null());
+ let state = NonNull::new_unchecked(opaque.cast::<PL011State>());
+ state.as_ref().can_receive().into()
+}
+
+/// # Safety
+///
+/// We expect the FFI user of this function to pass a valid pointer, that has
+/// the same size as [`PL011State`]. We also expect the device is
+/// readable/writeable from one thread at any time.
+///
+/// The buffer and size arguments must also be valid.
+#[no_mangle]
+pub unsafe extern "C" fn pl011_receive(
+ opaque: *mut core::ffi::c_void,
+ buf: *const u8,
+ size: core::ffi::c_int,
+) {
+ assert!(!opaque.is_null());
+ let mut state = NonNull::new_unchecked(opaque.cast::<PL011State>());
+ if state.as_ref().loopback_enabled() {
+ return;
+ }
+ if size > 0 {
+ assert!(!buf.is_null());
+ state.as_mut().put_fifo(*buf.cast::<c_uint>())
+ }
+}
+
+/// # Safety
+///
+/// We expect the FFI user of this function to pass a valid pointer, that has
+/// the same size as [`PL011State`]. We also expect the device is
+/// readable/writeable from one thread at any time.
+#[no_mangle]
+pub unsafe extern "C" fn pl011_event(opaque: *mut core::ffi::c_void, event: QEMUChrEvent) {
+ assert!(!opaque.is_null());
+ let mut state = NonNull::new_unchecked(opaque.cast::<PL011State>());
+ state.as_mut().event(event)
+}
+
+/// # Safety
+///
+/// We expect the FFI user of this function to pass a valid pointer for `chr`.
+#[no_mangle]
+pub unsafe extern "C" fn pl011_create(
+ addr: u64,
+ irq: qemu_irq,
+ chr: *mut Chardev,
+) -> *mut DeviceState {
+ let dev: *mut DeviceState = unsafe { qdev_new(PL011_ARM_INFO.name) };
+ assert!(!dev.is_null());
+ let sysbus: *mut SysBusDevice = dev as *mut SysBusDevice;
+
+ qdev_prop_set_chr(dev, bindings::TYPE_CHARDEV.as_ptr(), chr);
+ sysbus_realize_and_unref(sysbus, addr_of!(error_fatal) as *mut *mut Error);
+ sysbus_mmio_map(sysbus, 0, addr);
+ sysbus_connect_irq(sysbus, 0, irq);
+ dev
+}
diff --git a/rust/hw/char/pl011/src/device_class.rs b/rust/hw/char/pl011/src/device_class.rs
new file mode 100644
index 0000000000..6b99239133
--- /dev/null
+++ b/rust/hw/char/pl011/src/device_class.rs
@@ -0,0 +1,58 @@
+// Copyright 2024 Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0 OR GPL-3.0-or-later
+
+use core::ptr::NonNull;
+
+use qemu_api::bindings::*;
+
+use crate::{definitions::VMSTATE_PL011, device::PL011State};
+
+qemu_api::declare_properties! {
+ PL011_PROPERTIES,
+ qemu_api::define_property!(
+ c"chardev",
+ PL011State,
+ char_backend,
+ unsafe { &qdev_prop_chr },
+ CharBackend
+ ),
+ qemu_api::define_property!(
+ c"migrate-clk",
+ PL011State,
+ migrate_clock,
+ unsafe { &qdev_prop_bool },
+ bool
+ ),
+}
+
+qemu_api::device_class_init! {
+ pl011_class_init,
+ props => PL011_PROPERTIES,
+ realize_fn => Some(pl011_realize),
+ reset_fn => Some(pl011_reset),
+ vmsd => VMSTATE_PL011,
+}
+
+/// # Safety
+///
+/// We expect the FFI user of this function to pass a valid pointer, that has
+/// the same size as [`PL011State`]. We also expect the device is
+/// readable/writeable from one thread at any time.
+#[no_mangle]
+pub unsafe extern "C" fn pl011_realize(dev: *mut DeviceState, _errp: *mut *mut Error) {
+ assert!(!dev.is_null());
+ let mut state = NonNull::new_unchecked(dev.cast::<PL011State>());
+ state.as_mut().realize();
+}
+
+/// # Safety
+///
+/// We expect the FFI user of this function to pass a valid pointer, that has
+/// the same size as [`PL011State`]. We also expect the device is
+/// readable/writeable from one thread at any time.
+#[no_mangle]
+pub unsafe extern "C" fn pl011_reset(dev: *mut DeviceState) {
+ assert!(!dev.is_null());
+ let mut state = NonNull::new_unchecked(dev.cast::<PL011State>());
+ state.as_mut().reset();
+}
diff --git a/rust/hw/char/pl011/src/lib.rs b/rust/hw/char/pl011/src/lib.rs
new file mode 100644
index 0000000000..697d2ef5a6
--- /dev/null
+++ b/rust/hw/char/pl011/src/lib.rs
@@ -0,0 +1,584 @@
+// Copyright 2024 Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0 OR GPL-3.0-or-later
+//
+// PL011 QEMU Device Model
+//
+// This library implements a device model for the PrimeCell® UART (PL011)
+// device in QEMU.
+//
+#![doc = include_str!("../README.md")]
+//! # Library crate
+//!
+//! See [`PL011State`](crate::device::PL011State) for the device model type and
+//! the [`registers`] module for register types.
+
+#![deny(
+ rustdoc::broken_intra_doc_links,
+ rustdoc::redundant_explicit_links,
+ clippy::correctness,
+ clippy::suspicious,
+ clippy::complexity,
+ clippy::perf,
+ clippy::cargo,
+ clippy::nursery,
+ clippy::style,
+ // restriction group
+ clippy::dbg_macro,
+ clippy::as_underscore,
+ clippy::assertions_on_result_states,
+ // pedantic group
+ clippy::doc_markdown,
+ clippy::borrow_as_ptr,
+ clippy::cast_lossless,
+ clippy::option_if_let_else,
+ clippy::missing_const_for_fn,
+ clippy::cognitive_complexity,
+ clippy::missing_safety_doc,
+ )]
+
+extern crate bilge;
+extern crate bilge_impl;
+extern crate qemu_api;
+
+pub mod definitions;
+pub mod device;
+pub mod device_class;
+pub mod memory_ops;
+
+/// Offset of each register from the base memory address of the device.
+///
+/// # Source
+/// ARM DDI 0183G, Table 3-1 p.3-3
+#[doc(alias = "offset")]
+#[allow(non_camel_case_types)]
+#[repr(u64)]
+#[derive(Debug)]
+pub enum RegisterOffset {
+ /// Data Register
+ ///
+ /// A write to this register initiates the actual data transmission
+ #[doc(alias = "UARTDR")]
+ DR = 0x000,
+ /// Receive Status Register or Error Clear Register
+ #[doc(alias = "UARTRSR")]
+ #[doc(alias = "UARTECR")]
+ RSR = 0x004,
+ /// Flag Register
+ ///
+ /// A read of this register shows if transmission is complete
+ #[doc(alias = "UARTFR")]
+ FR = 0x018,
+ /// Fractional Baud Rate Register
+ ///
+ /// responsible for baud rate speed
+ #[doc(alias = "UARTFBRD")]
+ FBRD = 0x028,
+ /// `IrDA` Low-Power Counter Register
+ #[doc(alias = "UARTILPR")]
+ ILPR = 0x020,
+ /// Integer Baud Rate Register
+ ///
+ /// Responsible for baud rate speed
+ #[doc(alias = "UARTIBRD")]
+ IBRD = 0x024,
+ /// line control register (data frame format)
+ #[doc(alias = "UARTLCR_H")]
+ LCR_H = 0x02C,
+ /// Toggle UART, transmission or reception
+ #[doc(alias = "UARTCR")]
+ CR = 0x030,
+ /// Interrupt FIFO Level Select Register
+ #[doc(alias = "UARTIFLS")]
+ FLS = 0x034,
+ /// Interrupt Mask Set/Clear Register
+ #[doc(alias = "UARTIMSC")]
+ IMSC = 0x038,
+ /// Raw Interrupt Status Register
+ #[doc(alias = "UARTRIS")]
+ RIS = 0x03C,
+ /// Masked Interrupt Status Register
+ #[doc(alias = "UARTMIS")]
+ MIS = 0x040,
+ /// Interrupt Clear Register
+ #[doc(alias = "UARTICR")]
+ ICR = 0x044,
+ /// DMA control Register
+ #[doc(alias = "UARTDMACR")]
+ DMACR = 0x048,
+ ///// Reserved, offsets `0x04C` to `0x07C`.
+ //Reserved = 0x04C,
+}
+
+impl core::convert::TryFrom<u64> for RegisterOffset {
+ type Error = u64;
+
+ fn try_from(value: u64) -> Result<Self, Self::Error> {
+ macro_rules! case {
+ ($($discriminant:ident),*$(,)*) => {
+ /* check that matching on all macro arguments compiles, which means we are not
+ * missing any enum value; if the type definition ever changes this will stop
+ * compiling.
+ */
+ const fn _assert_exhaustive(val: RegisterOffset) {
+ match val {
+ $(RegisterOffset::$discriminant => (),)*
+ }
+ }
+
+ match value {
+ $(x if x == Self::$discriminant as u64 => Ok(Self::$discriminant),)*
+ _ => Err(value),
+ }
+ }
+ }
+ case! { DR, RSR, FR, FBRD, ILPR, IBRD, LCR_H, CR, FLS, IMSC, RIS, MIS, ICR, DMACR }
+ }
+}
+
+pub mod registers {
+ //! Device registers exposed as typed structs which are backed by arbitrary
+ //! integer bitmaps. [`Data`], [`Control`], [`LineControl`], etc.
+ //!
+ //! All PL011 registers are essentially 32-bit wide, but are typed here as
+ //! bitmaps with only the necessary width. That is, if a struct bitmap
+ //! in this module is for example 16 bits long, it should be conceived
+ //! as a 32-bit register where the unmentioned higher bits are always
+ //! unused thus treated as zero when read or written.
+ use bilge::prelude::*;
+
+ // TODO: FIFO Mode has different semantics
+ /// Data Register, `UARTDR`
+ ///
+ /// The `UARTDR` register is the data register.
+ ///
+ /// For words to be transmitted:
+ ///
+ /// - if the FIFOs are enabled, data written to this location is pushed onto
+ /// the transmit
+ /// FIFO
+ /// - if the FIFOs are not enabled, data is stored in the transmitter
+ /// holding register (the
+ /// bottom word of the transmit FIFO).
+ ///
+ /// The write operation initiates transmission from the UART. The data is
+ /// prefixed with a start bit, appended with the appropriate parity bit
+ /// (if parity is enabled), and a stop bit. The resultant word is then
+ /// transmitted.
+ ///
+ /// For received words:
+ ///
+ /// - if the FIFOs are enabled, the data byte and the 4-bit status (break,
+ /// frame, parity,
+ /// and overrun) is pushed onto the 12-bit wide receive FIFO
+ /// - if the FIFOs are not enabled, the data byte and status are stored in
+ /// the receiving
+ /// holding register (the bottom word of the receive FIFO).
+ ///
+ /// The received data byte is read by performing reads from the `UARTDR`
+ /// register along with the corresponding status information. The status
+ /// information can also be read by a read of the `UARTRSR/UARTECR`
+ /// register.
+ ///
+ /// # Note
+ ///
+ /// You must disable the UART before any of the control registers are
+ /// reprogrammed. When the UART is disabled in the middle of
+ /// transmission or reception, it completes the current character before
+ /// stopping.
+ ///
+ /// # Source
+ /// ARM DDI 0183G 3.3.1 Data Register, UARTDR
+ #[bitsize(16)]
+ #[derive(Clone, Copy, DebugBits, FromBits)]
+ #[doc(alias = "UARTDR")]
+ pub struct Data {
+ _reserved: u4,
+ pub data: u8,
+ pub framing_error: bool,
+ pub parity_error: bool,
+ pub break_error: bool,
+ pub overrun_error: bool,
+ }
+
+ // TODO: FIFO Mode has different semantics
+ /// Receive Status Register / Error Clear Register, `UARTRSR/UARTECR`
+ ///
+ /// The UARTRSR/UARTECR register is the receive status register/error clear
+ /// register. Receive status can also be read from the `UARTRSR`
+ /// register. If the status is read from this register, then the status
+ /// information for break, framing and parity corresponds to the
+ /// data character read from the [Data register](Data), `UARTDR` prior to
+ /// reading the UARTRSR register. The status information for overrun is
+ /// set immediately when an overrun condition occurs.
+ ///
+ ///
+ /// # Note
+ /// The received data character must be read first from the [Data
+ /// Register](Data), `UARTDR` before reading the error status associated
+ /// with that data character from the `UARTRSR` register. This read
+ /// sequence cannot be reversed, because the `UARTRSR` register is
+ /// updated only when a read occurs from the `UARTDR` register. However,
+ /// the status information can also be obtained by reading the `UARTDR`
+ /// register
+ ///
+ /// # Source
+ /// ARM DDI 0183G 3.3.2 Receive Status Register/Error Clear Register,
+ /// UARTRSR/UARTECR
+ #[bitsize(8)]
+ #[derive(Clone, Copy, DebugBits, FromBits)]
+ pub struct ReceiveStatusErrorClear {
+ pub framing_error: bool,
+ pub parity_error: bool,
+ pub break_error: bool,
+ pub overrun_error: bool,
+ _reserved_unpredictable: u4,
+ }
+
+ impl ReceiveStatusErrorClear {
+ pub fn reset(&mut self) {
+ // All the bits are cleared to 0 on reset.
+ *self = 0.into();
+ }
+ }
+
+ impl Default for ReceiveStatusErrorClear {
+ fn default() -> Self {
+ 0.into()
+ }
+ }
+
+ #[bitsize(16)]
+ #[derive(Clone, Copy, DebugBits, FromBits)]
+ /// Flag Register, `UARTFR`
+ #[doc(alias = "UARTFR")]
+ pub struct Flags {
+ /// CTS Clear to send. This bit is the complement of the UART clear to
+ /// send, `nUARTCTS`, modem status input. That is, the bit is 1
+ /// when `nUARTCTS` is LOW.
+ pub clear_to_send: bool,
+ /// DSR Data set ready. This bit is the complement of the UART data set
+ /// ready, `nUARTDSR`, modem status input. That is, the bit is 1 when
+ /// `nUARTDSR` is LOW.
+ pub data_set_ready: bool,
+ /// DCD Data carrier detect. This bit is the complement of the UART data
+ /// carrier detect, `nUARTDCD`, modem status input. That is, the bit is
+ /// 1 when `nUARTDCD` is LOW.
+ pub data_carrier_detect: bool,
+ /// BUSY UART busy. If this bit is set to 1, the UART is busy
+ /// transmitting data. This bit remains set until the complete
+ /// byte, including all the stop bits, has been sent from the
+ /// shift register. This bit is set as soon as the transmit FIFO
+ /// becomes non-empty, regardless of whether the UART is enabled
+ /// or not.
+ pub busy: bool,
+ /// RXFE Receive FIFO empty. The meaning of this bit depends on the
+ /// state of the FEN bit in the UARTLCR_H register. If the FIFO
+ /// is disabled, this bit is set when the receive holding
+ /// register is empty. If the FIFO is enabled, the RXFE bit is
+ /// set when the receive FIFO is empty.
+ pub receive_fifo_empty: bool,
+ /// TXFF Transmit FIFO full. The meaning of this bit depends on the
+ /// state of the FEN bit in the UARTLCR_H register. If the FIFO
+ /// is disabled, this bit is set when the transmit holding
+ /// register is full. If the FIFO is enabled, the TXFF bit is
+ /// set when the transmit FIFO is full.
+ pub transmit_fifo_full: bool,
+ /// RXFF Receive FIFO full. The meaning of this bit depends on the state
+ /// of the FEN bit in the UARTLCR_H register. If the FIFO is
+ /// disabled, this bit is set when the receive holding register
+ /// is full. If the FIFO is enabled, the RXFF bit is set when
+ /// the receive FIFO is full.
+ pub receive_fifo_full: bool,
+ /// Transmit FIFO empty. The meaning of this bit depends on the state of
+ /// the FEN bit in the [Line Control register](LineControl),
+ /// `UARTLCR_H`. If the FIFO is disabled, this bit is set when the
+ /// transmit holding register is empty. If the FIFO is enabled,
+ /// the TXFE bit is set when the transmit FIFO is empty. This
+ /// bit does not indicate if there is data in the transmit shift
+ /// register.
+ pub transmit_fifo_empty: bool,
+ /// `RI`, is `true` when `nUARTRI` is `LOW`.
+ pub ring_indicator: bool,
+ _reserved_zero_no_modify: u7,
+ }
+
+ impl Flags {
+ pub fn reset(&mut self) {
+ // After reset TXFF, RXFF, and BUSY are 0, and TXFE and RXFE are 1
+ self.set_receive_fifo_full(false);
+ self.set_transmit_fifo_full(false);
+ self.set_busy(false);
+ self.set_receive_fifo_empty(true);
+ self.set_transmit_fifo_empty(true);
+ }
+ }
+
+ impl Default for Flags {
+ fn default() -> Self {
+ let mut ret: Self = 0.into();
+ ret.reset();
+ ret
+ }
+ }
+
+ #[bitsize(16)]
+ #[derive(Clone, Copy, DebugBits, FromBits)]
+ /// Line Control Register, `UARTLCR_H`
+ #[doc(alias = "UARTLCR_H")]
+ pub struct LineControl {
+ /// 15:8 - Reserved, do not modify, read as zero.
+ _reserved_zero_no_modify: u8,
+ /// 7 SPS Stick parity select.
+ /// 0 = stick parity is disabled
+ /// 1 = either:
+ /// • if the EPS bit is 0 then the parity bit is transmitted and checked
+ /// as a 1 • if the EPS bit is 1 then the parity bit is
+ /// transmitted and checked as a 0. This bit has no effect when
+ /// the PEN bit disables parity checking and generation. See Table 3-11
+ /// on page 3-14 for the parity truth table.
+ pub sticky_parity: bool,
+ /// WLEN Word length. These bits indicate the number of data bits
+ /// transmitted or received in a frame as follows: b11 = 8 bits
+ /// b10 = 7 bits
+ /// b01 = 6 bits
+ /// b00 = 5 bits.
+ pub word_length: WordLength,
+ /// FEN Enable FIFOs:
+ /// 0 = FIFOs are disabled (character mode) that is, the FIFOs become
+ /// 1-byte-deep holding registers 1 = transmit and receive FIFO
+ /// buffers are enabled (FIFO mode).
+ pub fifos_enabled: Mode,
+ /// 3 STP2 Two stop bits select. If this bit is set to 1, two stop bits
+ /// are transmitted at the end of the frame. The receive
+ /// logic does not check for two stop bits being received.
+ pub two_stops_bits: bool,
+ /// EPS Even parity select. Controls the type of parity the UART uses
+ /// during transmission and reception:
+ /// - 0 = odd parity. The UART generates or checks for an odd number of
+ /// 1s in the data and parity bits.
+ /// - 1 = even parity. The UART generates or checks for an even number
+ /// of 1s in the data and parity bits.
+ /// This bit has no effect when the `PEN` bit disables parity checking
+ /// and generation. See Table 3-11 on page 3-14 for the parity
+ /// truth table.
+ pub parity: Parity,
+ /// 1 PEN Parity enable:
+ ///
+ /// - 0 = parity is disabled and no parity bit added to the data frame
+ /// - 1 = parity checking and generation is enabled.
+ ///
+ /// See Table 3-11 on page 3-14 for the parity truth table.
+ pub parity_enabled: bool,
+ /// BRK Send break.
+ ///
+ /// If this bit is set to `1`, a low-level is continually output on the
+ /// `UARTTXD` output, after completing transmission of the
+ /// current character. For the proper execution of the break command,
+ /// the software must set this bit for at least two complete
+ /// frames. For normal use, this bit must be cleared to `0`.
+ pub send_break: bool,
+ }
+
+ impl LineControl {
+ pub fn reset(&mut self) {
+ // All the bits are cleared to 0 when reset.
+ *self = 0.into();
+ }
+ }
+
+ impl Default for LineControl {
+ fn default() -> Self {
+ 0.into()
+ }
+ }
+
+ #[bitsize(1)]
+ #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)]
+ /// `EPS` "Even parity select", field of [Line Control
+ /// register](LineControl).
+ pub enum Parity {
+ /// - 0 = odd parity. The UART generates or checks for an odd number of
+ /// 1s in the data and parity bits.
+ Odd = 0,
+ /// - 1 = even parity. The UART generates or checks for an even number
+ /// of 1s in the data and parity bits.
+ Even = 1,
+ }
+
+ #[bitsize(1)]
+ #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)]
+ /// `FEN` "Enable FIFOs" or Device mode, field of [Line Control
+ /// register](LineControl).
+ pub enum Mode {
+ /// 0 = FIFOs are disabled (character mode) that is, the FIFOs become
+ /// 1-byte-deep holding registers
+ Character = 0,
+ /// 1 = transmit and receive FIFO buffers are enabled (FIFO mode).
+ FIFO = 1,
+ }
+
+ impl From<Mode> for bool {
+ fn from(val: Mode) -> Self {
+ matches!(val, Mode::FIFO)
+ }
+ }
+
+ #[bitsize(2)]
+ #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)]
+ /// `WLEN` Word length, field of [Line Control register](LineControl).
+ ///
+ /// These bits indicate the number of data bits transmitted or received in a
+ /// frame as follows:
+ pub enum WordLength {
+ /// b11 = 8 bits
+ _8Bits = 0b11,
+ /// b10 = 7 bits
+ _7Bits = 0b10,
+ /// b01 = 6 bits
+ _6Bits = 0b01,
+ /// b00 = 5 bits.
+ _5Bits = 0b00,
+ }
+
+ /// Control Register, `UARTCR`
+ ///
+ /// The `UARTCR` register is the control register. All the bits are cleared
+ /// to `0` on reset except for bits `9` and `8` that are set to `1`.
+ ///
+ /// # Source
+ /// ARM DDI 0183G, 3.3.8 Control Register, `UARTCR`, Table 3-12
+ #[bitsize(16)]
+ #[doc(alias = "UARTCR")]
+ #[derive(Clone, Copy, DebugBits, FromBits)]
+ pub struct Control {
+ /// `UARTEN` UART enable: 0 = UART is disabled. If the UART is disabled
+ /// in the middle of transmission or reception, it completes the current
+ /// character before stopping. 1 = the UART is enabled. Data
+ /// transmission and reception occurs for either UART signals or SIR
+ /// signals depending on the setting of the SIREN bit.
+ pub enable_uart: bool,
+ /// `SIREN` `SIR` enable: 0 = IrDA SIR ENDEC is disabled. `nSIROUT`
+ /// remains LOW (no light pulse generated), and signal transitions on
+ /// SIRIN have no effect. 1 = IrDA SIR ENDEC is enabled. Data is
+ /// transmitted and received on nSIROUT and SIRIN. UARTTXD remains HIGH,
+ /// in the marking state. Signal transitions on UARTRXD or modem status
+ /// inputs have no effect. This bit has no effect if the UARTEN bit
+ /// disables the UART.
+ pub enable_sir: bool,
+ /// `SIRLP` SIR low-power IrDA mode. This bit selects the IrDA encoding
+ /// mode. If this bit is cleared to 0, low-level bits are transmitted as
+ /// an active high pulse with a width of 3/ 16th of the bit period. If
+ /// this bit is set to 1, low-level bits are transmitted with a pulse
+ /// width that is 3 times the period of the IrLPBaud16 input signal,
+ /// regardless of the selected bit rate. Setting this bit uses less
+ /// power, but might reduce transmission distances.
+ pub sir_lowpower_irda_mode: u1,
+ /// Reserved, do not modify, read as zero.
+ _reserved_zero_no_modify: u4,
+ /// `LBE` Loopback enable. If this bit is set to 1 and the SIREN bit is
+ /// set to 1 and the SIRTEST bit in the Test Control register, UARTTCR
+ /// on page 4-5 is set to 1, then the nSIROUT path is inverted, and fed
+ /// through to the SIRIN path. The SIRTEST bit in the test register must
+ /// be set to 1 to override the normal half-duplex SIR operation. This
+ /// must be the requirement for accessing the test registers during
+ /// normal operation, and SIRTEST must be cleared to 0 when loopback
+ /// testing is finished. This feature reduces the amount of external
+ /// coupling required during system test. If this bit is set to 1, and
+ /// the SIRTEST bit is set to 0, the UARTTXD path is fed through to the
+ /// UARTRXD path. In either SIR mode or UART mode, when this bit is set,
+ /// the modem outputs are also fed through to the modem inputs. This bit
+ /// is cleared to 0 on reset, to disable loopback.
+ pub enable_loopback: bool,
+ /// `TXE` Transmit enable. If this bit is set to 1, the transmit section
+ /// of the UART is enabled. Data transmission occurs for either UART
+ /// signals, or SIR signals depending on the setting of the SIREN bit.
+ /// When the UART is disabled in the middle of transmission, it
+ /// completes the current character before stopping.
+ pub enable_transmit: bool,
+ /// `RXE` Receive enable. If this bit is set to 1, the receive section
+ /// of the UART is enabled. Data reception occurs for either UART
+ /// signals or SIR signals depending on the setting of the SIREN bit.
+ /// When the UART is disabled in the middle of reception, it completes
+ /// the current character before stopping.
+ pub enable_receive: bool,
+ /// `DTR` Data transmit ready. This bit is the complement of the UART
+ /// data transmit ready, `nUARTDTR`, modem status output. That is, when
+ /// the bit is programmed to a 1 then `nUARTDTR` is LOW.
+ pub data_transmit_ready: bool,
+ /// `RTS` Request to send. This bit is the complement of the UART
+ /// request to send, `nUARTRTS`, modem status output. That is, when the
+ /// bit is programmed to a 1 then `nUARTRTS` is LOW.
+ pub request_to_send: bool,
+ /// `Out1` This bit is the complement of the UART Out1 (`nUARTOut1`)
+ /// modem status output. That is, when the bit is programmed to a 1 the
+ /// output is 0. For DTE this can be used as Data Carrier Detect (DCD).
+ pub out_1: bool,
+ /// `Out2` This bit is the complement of the UART Out2 (`nUARTOut2`)
+ /// modem status output. That is, when the bit is programmed to a 1, the
+ /// output is 0. For DTE this can be used as Ring Indicator (RI).
+ pub out_2: bool,
+ /// `RTSEn` RTS hardware flow control enable. If this bit is set to 1,
+ /// RTS hardware flow control is enabled. Data is only requested when
+ /// there is space in the receive FIFO for it to be received.
+ pub rts_hardware_flow_control_enable: bool,
+ /// `CTSEn` CTS hardware flow control enable. If this bit is set to 1,
+ /// CTS hardware flow control is enabled. Data is only transmitted when
+ /// the `nUARTCTS` signal is asserted.
+ pub cts_hardware_flow_control_enable: bool,
+ }
+
+ impl Control {
+ pub fn reset(&mut self) {
+ *self = 0.into();
+ self.set_enable_receive(true);
+ self.set_enable_transmit(true);
+ }
+ }
+
+ impl Default for Control {
+ fn default() -> Self {
+ let mut ret: Self = 0.into();
+ ret.reset();
+ ret
+ }
+ }
+
+ /// Interrupt status bits in UARTRIS, UARTMIS, UARTIMSC
+ pub const INT_OE: u32 = 1 << 10;
+ pub const INT_BE: u32 = 1 << 9;
+ pub const INT_PE: u32 = 1 << 8;
+ pub const INT_FE: u32 = 1 << 7;
+ pub const INT_RT: u32 = 1 << 6;
+ pub const INT_TX: u32 = 1 << 5;
+ pub const INT_RX: u32 = 1 << 4;
+ pub const INT_DSR: u32 = 1 << 3;
+ pub const INT_DCD: u32 = 1 << 2;
+ pub const INT_CTS: u32 = 1 << 1;
+ pub const INT_RI: u32 = 1 << 0;
+ pub const INT_E: u32 = INT_OE | INT_BE | INT_PE | INT_FE;
+ pub const INT_MS: u32 = INT_RI | INT_DSR | INT_DCD | INT_CTS;
+
+ #[repr(u32)]
+ pub enum Interrupt {
+ OE = 1 << 10,
+ BE = 1 << 9,
+ PE = 1 << 8,
+ FE = 1 << 7,
+ RT = 1 << 6,
+ TX = 1 << 5,
+ RX = 1 << 4,
+ DSR = 1 << 3,
+ DCD = 1 << 2,
+ CTS = 1 << 1,
+ RI = 1 << 0,
+ }
+
+ impl Interrupt {
+ pub const E: u32 = INT_OE | INT_BE | INT_PE | INT_FE;
+ pub const MS: u32 = INT_RI | INT_DSR | INT_DCD | INT_CTS;
+ }
+}
+
+// TODO: You must disable the UART before any of the control registers are
+// reprogrammed. When the UART is disabled in the middle of transmission or
+// reception, it completes the current character before stopping
diff --git a/rust/hw/char/pl011/src/memory_ops.rs b/rust/hw/char/pl011/src/memory_ops.rs
new file mode 100644
index 0000000000..6144d28586
--- /dev/null
+++ b/rust/hw/char/pl011/src/memory_ops.rs
@@ -0,0 +1,45 @@
+// Copyright 2024 Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+// SPDX-License-Identifier: GPL-2.0 OR GPL-3.0-or-later
+
+use core::{mem::MaybeUninit, ptr::NonNull};
+
+use qemu_api::bindings::*;
+
+use crate::device::PL011State;
+
+pub static PL011_OPS: MemoryRegionOps = MemoryRegionOps {
+ read: Some(pl011_read),
+ write: Some(pl011_write),
+ read_with_attrs: None,
+ write_with_attrs: None,
+ endianness: device_endian_DEVICE_NATIVE_ENDIAN,
+ valid: unsafe { MaybeUninit::<MemoryRegionOps__bindgen_ty_1>::zeroed().assume_init() },
+ impl_: MemoryRegionOps__bindgen_ty_2 {
+ min_access_size: 4,
+ max_access_size: 4,
+ ..unsafe { MaybeUninit::<MemoryRegionOps__bindgen_ty_2>::zeroed().assume_init() }
+ },
+};
+
+#[no_mangle]
+unsafe extern "C" fn pl011_read(
+ opaque: *mut core::ffi::c_void,
+ addr: hwaddr,
+ size: core::ffi::c_uint,
+) -> u64 {
+ assert!(!opaque.is_null());
+ let mut state = NonNull::new_unchecked(opaque.cast::<PL011State>());
+ state.as_mut().read(addr, size)
+}
+
+#[no_mangle]
+unsafe extern "C" fn pl011_write(
+ opaque: *mut core::ffi::c_void,
+ addr: hwaddr,
+ data: u64,
+ _size: core::ffi::c_uint,
+) {
+ assert!(!opaque.is_null());
+ let mut state = NonNull::new_unchecked(opaque.cast::<PL011State>());
+ state.as_mut().write(addr, data)
+}
diff --git a/rust/hw/meson.build b/rust/hw/meson.build
new file mode 100644
index 0000000000..860196645e
--- /dev/null
+++ b/rust/hw/meson.build
@@ -0,0 +1 @@
+subdir('char')
diff --git a/rust/meson.build b/rust/meson.build
index a903c7c602..4c858e9d1f 100644
--- a/rust/meson.build
+++ b/rust/meson.build
@@ -11,3 +11,5 @@ _lib_bindings_rs = static_library(
)
subdir('qemu-api')
+
+subdir('hw')
--
γαῖα πυρί μιχθήτω
^ permalink raw reply related [flat|nested] 35+ messages in thread
* [RFC PATCH v5 8/8] rust/pl011: vendor dependencies
2024-07-22 11:43 [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Manos Pitsidianakis
` (6 preceding siblings ...)
2024-07-22 11:43 ` [RFC PATCH v5 7/8] rust: add PL011 device model Manos Pitsidianakis
@ 2024-07-22 11:43 ` Manos Pitsidianakis
2024-07-23 8:37 ` Zhao Liu
2024-07-23 15:07 ` [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Paolo Bonzini
8 siblings, 1 reply; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-22 11:43 UTC (permalink / raw)
To: qemu-devel
Cc: Stefan Hajnoczi, Mads Ynddal, Peter Maydell, Alex Bennée,
Daniel P. Berrangé, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé, Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
rust/hw/char/pl011/vendor/either/README.rst | 185 +
.../vendor/arbitrary-int/.cargo-checksum.json | 1 +
.../pl011/vendor/arbitrary-int/CHANGELOG.md | 47 +
.../pl011/vendor/arbitrary-int/Cargo.toml | 54 +
.../pl011/vendor/arbitrary-int/LICENSE.txt | 21 +
.../char/pl011/vendor/arbitrary-int/README.md | 72 +
.../pl011/vendor/arbitrary-int/meson.build | 14 +
.../pl011/vendor/arbitrary-int/src/lib.rs | 1489 +++++
.../pl011/vendor/arbitrary-int/tests/tests.rs | 1913 ++++++
.../vendor/bilge-impl/.cargo-checksum.json | 1 +
.../char/pl011/vendor/bilge-impl/Cargo.toml | 54 +
.../hw/char/pl011/vendor/bilge-impl/README.md | 327 ++
.../char/pl011/vendor/bilge-impl/meson.build | 24 +
.../pl011/vendor/bilge-impl/src/bitsize.rs | 187 +
.../vendor/bilge-impl/src/bitsize/split.rs | 185 +
.../vendor/bilge-impl/src/bitsize_internal.rs | 235 +
.../src/bitsize_internal/struct_gen.rs | 402 ++
.../pl011/vendor/bilge-impl/src/debug_bits.rs | 55 +
.../vendor/bilge-impl/src/default_bits.rs | 92 +
.../pl011/vendor/bilge-impl/src/fmt_bits.rs | 112 +
.../pl011/vendor/bilge-impl/src/from_bits.rs | 222 +
.../char/pl011/vendor/bilge-impl/src/lib.rs | 79 +
.../pl011/vendor/bilge-impl/src/shared.rs | 196 +
.../src/shared/discriminant_assigner.rs | 56 +
.../vendor/bilge-impl/src/shared/fallback.rs | 92 +
.../vendor/bilge-impl/src/shared/util.rs | 91 +
.../vendor/bilge-impl/src/try_from_bits.rs | 143 +
.../pl011/vendor/bilge/.cargo-checksum.json | 1 +
rust/hw/char/pl011/vendor/bilge/Cargo.toml | 69 +
.../hw/char/pl011/vendor/bilge/LICENSE-APACHE | 176 +
rust/hw/char/pl011/vendor/bilge/LICENSE-MIT | 17 +
rust/hw/char/pl011/vendor/bilge/README.md | 327 ++
rust/hw/char/pl011/vendor/bilge/meson.build | 17 +
rust/hw/char/pl011/vendor/bilge/src/lib.rs | 80 +
.../pl011/vendor/either/.cargo-checksum.json | 1 +
rust/hw/char/pl011/vendor/either/Cargo.toml | 54 +
.../char/pl011/vendor/either/LICENSE-APACHE | 201 +
rust/hw/char/pl011/vendor/either/LICENSE-MIT | 25 +
.../pl011/vendor/either/README-crates.io.md | 10 +
rust/hw/char/pl011/vendor/either/meson.build | 16 +
.../pl011/vendor/either/src/into_either.rs | 64 +
.../char/pl011/vendor/either/src/iterator.rs | 315 +
rust/hw/char/pl011/vendor/either/src/lib.rs | 1519 +++++
.../pl011/vendor/either/src/serde_untagged.rs | 69 +
.../either/src/serde_untagged_optional.rs | 74 +
.../vendor/itertools/.cargo-checksum.json | 1 +
.../char/pl011/vendor/itertools/CHANGELOG.md | 409 ++
.../hw/char/pl011/vendor/itertools/Cargo.lock | 681 +++
.../hw/char/pl011/vendor/itertools/Cargo.toml | 101 +
.../pl011/vendor/itertools/LICENSE-APACHE | 201 +
.../char/pl011/vendor/itertools/LICENSE-MIT | 25 +
rust/hw/char/pl011/vendor/itertools/README.md | 44 +
.../pl011/vendor/itertools/benches/bench1.rs | 877 +++
.../vendor/itertools/benches/combinations.rs | 125 +
.../benches/combinations_with_replacement.rs | 40 +
| 2 +
| 188 +
.../itertools/benches/fold_specialization.rs | 73 +
.../vendor/itertools/benches/powerset.rs | 44 +
.../vendor/itertools/benches/tree_fold1.rs | 144 +
.../itertools/benches/tuple_combinations.rs | 113 +
.../pl011/vendor/itertools/benches/tuples.rs | 213 +
.../pl011/vendor/itertools/examples/iris.data | 150 +
.../pl011/vendor/itertools/examples/iris.rs | 137 +
.../char/pl011/vendor/itertools/meson.build | 18 +
.../vendor/itertools/src/adaptors/coalesce.rs | 235 +
.../vendor/itertools/src/adaptors/map.rs | 124 +
.../vendor/itertools/src/adaptors/mod.rs | 1151 ++++
.../itertools/src/adaptors/multi_product.rs | 230 +
.../vendor/itertools/src/combinations.rs | 128 +
.../src/combinations_with_replacement.rs | 109 +
.../pl011/vendor/itertools/src/concat_impl.rs | 23 +
.../vendor/itertools/src/cons_tuples_impl.rs | 64 +
.../char/pl011/vendor/itertools/src/diff.rs | 61 +
.../vendor/itertools/src/duplicates_impl.rs | 216 +
.../vendor/itertools/src/either_or_both.rs | 495 ++
.../vendor/itertools/src/exactly_one_err.rs | 110 +
.../pl011/vendor/itertools/src/extrema_set.rs | 48 +
.../pl011/vendor/itertools/src/flatten_ok.rs | 165 +
.../char/pl011/vendor/itertools/src/format.rs | 168 +
.../char/pl011/vendor/itertools/src/free.rs | 286 +
.../pl011/vendor/itertools/src/group_map.rs | 32 +
.../pl011/vendor/itertools/src/groupbylazy.rs | 579 ++
.../vendor/itertools/src/grouping_map.rs | 535 ++
.../pl011/vendor/itertools/src/impl_macros.rs | 29 +
.../pl011/vendor/itertools/src/intersperse.rs | 118 +
.../pl011/vendor/itertools/src/k_smallest.rs | 20 +
.../pl011/vendor/itertools/src/kmerge_impl.rs | 227 +
.../pl011/vendor/itertools/src/lazy_buffer.rs | 63 +
.../hw/char/pl011/vendor/itertools/src/lib.rs | 3967 +++++++++++++
.../pl011/vendor/itertools/src/merge_join.rs | 220 +
.../char/pl011/vendor/itertools/src/minmax.rs | 115 +
.../vendor/itertools/src/multipeek_impl.rs | 101 +
.../pl011/vendor/itertools/src/pad_tail.rs | 96 +
.../pl011/vendor/itertools/src/peek_nth.rs | 102 +
.../itertools/src/peeking_take_while.rs | 177 +
.../vendor/itertools/src/permutations.rs | 277 +
.../pl011/vendor/itertools/src/powerset.rs | 90 +
.../itertools/src/process_results_impl.rs | 68 +
.../vendor/itertools/src/put_back_n_impl.rs | 61 +
.../pl011/vendor/itertools/src/rciter_impl.rs | 99 +
.../pl011/vendor/itertools/src/repeatn.rs | 59 +
.../pl011/vendor/itertools/src/size_hint.rs | 119 +
.../pl011/vendor/itertools/src/sources.rs | 183 +
.../itertools/src/take_while_inclusive.rs | 68 +
.../hw/char/pl011/vendor/itertools/src/tee.rs | 78 +
.../pl011/vendor/itertools/src/tuple_impl.rs | 331 ++
.../pl011/vendor/itertools/src/unique_impl.rs | 179 +
.../pl011/vendor/itertools/src/unziptuple.rs | 80 +
.../vendor/itertools/src/with_position.rs | 88 +
.../pl011/vendor/itertools/src/zip_eq_impl.rs | 60 +
.../pl011/vendor/itertools/src/zip_longest.rs | 83 +
.../pl011/vendor/itertools/src/ziptuple.rs | 138 +
.../itertools/tests/adaptors_no_collect.rs | 46 +
.../vendor/itertools/tests/flatten_ok.rs | 76 +
.../vendor/itertools/tests/macros_hygiene.rs | 13 +
.../vendor/itertools/tests/merge_join.rs | 108 +
.../itertools/tests/peeking_take_while.rs | 69 +
.../pl011/vendor/itertools/tests/quick.rs | 1849 ++++++
.../vendor/itertools/tests/specializations.rs | 153 +
.../pl011/vendor/itertools/tests/test_core.rs | 317 +
.../pl011/vendor/itertools/tests/test_std.rs | 1184 ++++
.../pl011/vendor/itertools/tests/tuples.rs | 86 +
.../char/pl011/vendor/itertools/tests/zip.rs | 77 +
rust/hw/char/pl011/vendor/meson.build | 18 +
.../.cargo-checksum.json | 1 +
.../vendor/proc-macro-error-attr/Cargo.toml | 33 +
.../proc-macro-error-attr/LICENSE-APACHE | 201 +
.../vendor/proc-macro-error-attr/LICENSE-MIT | 21 +
.../vendor/proc-macro-error-attr/build.rs | 5 +
.../vendor/proc-macro-error-attr/meson.build | 20 +
.../vendor/proc-macro-error-attr/src/lib.rs | 121 +
.../vendor/proc-macro-error-attr/src/parse.rs | 89 +
.../proc-macro-error-attr/src/settings.rs | 72 +
.../proc-macro-error/.cargo-checksum.json | 1 +
.../vendor/proc-macro-error/CHANGELOG.md | 162 +
.../pl011/vendor/proc-macro-error/Cargo.toml | 56 +
.../vendor/proc-macro-error/LICENSE-APACHE | 201 +
.../pl011/vendor/proc-macro-error/LICENSE-MIT | 21 +
.../pl011/vendor/proc-macro-error/README.md | 258 +
.../pl011/vendor/proc-macro-error/build.rs | 11 +
.../pl011/vendor/proc-macro-error/meson.build | 22 +
.../vendor/proc-macro-error/src/diagnostic.rs | 349 ++
.../vendor/proc-macro-error/src/dummy.rs | 150 +
.../proc-macro-error/src/imp/delegate.rs | 69 +
.../proc-macro-error/src/imp/fallback.rs | 30 +
.../pl011/vendor/proc-macro-error/src/lib.rs | 560 ++
.../vendor/proc-macro-error/src/macros.rs | 288 +
.../vendor/proc-macro-error/src/sealed.rs | 3 +
.../proc-macro-error/tests/macro-errors.rs | 8 +
.../pl011/vendor/proc-macro-error/tests/ok.rs | 10 +
.../proc-macro-error/tests/runtime-errors.rs | 13 +
.../vendor/proc-macro-error/tests/ui/abort.rs | 11 +
.../proc-macro-error/tests/ui/abort.stderr | 48 +
.../proc-macro-error/tests/ui/append_dummy.rs | 13 +
.../tests/ui/append_dummy.stderr | 5 +
.../tests/ui/children_messages.rs | 6 +
.../tests/ui/children_messages.stderr | 23 +
.../vendor/proc-macro-error/tests/ui/dummy.rs | 13 +
.../proc-macro-error/tests/ui/dummy.stderr | 5 +
.../vendor/proc-macro-error/tests/ui/emit.rs | 7 +
.../proc-macro-error/tests/ui/emit.stderr | 48 +
.../tests/ui/explicit_span_range.rs | 6 +
.../tests/ui/explicit_span_range.stderr | 5 +
.../proc-macro-error/tests/ui/misuse.rs | 11 +
.../proc-macro-error/tests/ui/misuse.stderr | 13 +
.../tests/ui/multiple_tokens.rs | 6 +
.../tests/ui/multiple_tokens.stderr | 5 +
.../tests/ui/not_proc_macro.rs | 4 +
.../tests/ui/not_proc_macro.stderr | 10 +
.../proc-macro-error/tests/ui/option_ext.rs | 6 +
.../tests/ui/option_ext.stderr | 7 +
.../tests/ui/proc_macro_hack.rs | 10 +
.../tests/ui/proc_macro_hack.stderr | 26 +
.../proc-macro-error/tests/ui/result_ext.rs | 7 +
.../tests/ui/result_ext.stderr | 11 +
.../tests/ui/to_tokens_span.rs | 6 +
.../tests/ui/to_tokens_span.stderr | 11 +
.../tests/ui/unknown_setting.rs | 4 +
.../tests/ui/unknown_setting.stderr | 5 +
.../tests/ui/unrelated_panic.rs | 6 +
.../tests/ui/unrelated_panic.stderr | 7 +
.../vendor/proc-macro2/.cargo-checksum.json | 1 +
.../char/pl011/vendor/proc-macro2/Cargo.toml | 104 +
.../pl011/vendor/proc-macro2/LICENSE-APACHE | 176 +
.../char/pl011/vendor/proc-macro2/LICENSE-MIT | 23 +
.../char/pl011/vendor/proc-macro2/README.md | 94 +
.../hw/char/pl011/vendor/proc-macro2/build.rs | 227 +
.../pl011/vendor/proc-macro2/build/probe.rs | 25 +
.../char/pl011/vendor/proc-macro2/meson.build | 19 +
.../vendor/proc-macro2/rust-toolchain.toml | 2 +
.../pl011/vendor/proc-macro2/src/detection.rs | 75 +
| 151 +
.../pl011/vendor/proc-macro2/src/fallback.rs | 1226 ++++
.../char/pl011/vendor/proc-macro2/src/lib.rs | 1369 +++++
.../pl011/vendor/proc-macro2/src/location.rs | 29 +
.../pl011/vendor/proc-macro2/src/marker.rs | 17 +
.../pl011/vendor/proc-macro2/src/parse.rs | 996 ++++
.../pl011/vendor/proc-macro2/src/rcvec.rs | 145 +
.../pl011/vendor/proc-macro2/src/wrapper.rs | 993 ++++
| 105 +
.../vendor/proc-macro2/tests/features.rs | 8 +
.../pl011/vendor/proc-macro2/tests/marker.rs | 100 +
.../pl011/vendor/proc-macro2/tests/test.rs | 905 +++
.../vendor/proc-macro2/tests/test_fmt.rs | 28 +
.../vendor/proc-macro2/tests/test_size.rs | 73 +
.../pl011/vendor/quote/.cargo-checksum.json | 1 +
rust/hw/char/pl011/vendor/quote/Cargo.toml | 50 +
.../hw/char/pl011/vendor/quote/LICENSE-APACHE | 176 +
rust/hw/char/pl011/vendor/quote/LICENSE-MIT | 23 +
rust/hw/char/pl011/vendor/quote/README.md | 272 +
rust/hw/char/pl011/vendor/quote/meson.build | 17 +
.../pl011/vendor/quote/rust-toolchain.toml | 2 +
rust/hw/char/pl011/vendor/quote/src/ext.rs | 110 +
rust/hw/char/pl011/vendor/quote/src/format.rs | 168 +
.../pl011/vendor/quote/src/ident_fragment.rs | 88 +
rust/hw/char/pl011/vendor/quote/src/lib.rs | 1464 +++++
.../hw/char/pl011/vendor/quote/src/runtime.rs | 530 ++
.../hw/char/pl011/vendor/quote/src/spanned.rs | 50 +
.../char/pl011/vendor/quote/src/to_tokens.rs | 209 +
.../pl011/vendor/quote/tests/compiletest.rs | 7 +
rust/hw/char/pl011/vendor/quote/tests/test.rs | 549 ++
.../ui/does-not-have-iter-interpolated-dup.rs | 9 +
...does-not-have-iter-interpolated-dup.stderr | 11 +
.../ui/does-not-have-iter-interpolated.rs | 9 +
.../ui/does-not-have-iter-interpolated.stderr | 11 +
.../tests/ui/does-not-have-iter-separated.rs | 5 +
.../ui/does-not-have-iter-separated.stderr | 10 +
.../quote/tests/ui/does-not-have-iter.rs | 5 +
.../quote/tests/ui/does-not-have-iter.stderr | 10 +
.../vendor/quote/tests/ui/not-quotable.rs | 7 +
.../vendor/quote/tests/ui/not-quotable.stderr | 20 +
.../vendor/quote/tests/ui/not-repeatable.rs | 8 +
.../quote/tests/ui/not-repeatable.stderr | 34 +
.../vendor/quote/tests/ui/wrong-type-span.rs | 7 +
.../quote/tests/ui/wrong-type-span.stderr | 10 +
.../pl011/vendor/syn/.cargo-checksum.json | 1 +
rust/hw/char/pl011/vendor/syn/Cargo.toml | 260 +
rust/hw/char/pl011/vendor/syn/LICENSE-APACHE | 176 +
rust/hw/char/pl011/vendor/syn/LICENSE-MIT | 23 +
rust/hw/char/pl011/vendor/syn/README.md | 284 +
rust/hw/char/pl011/vendor/syn/benches/file.rs | 57 +
rust/hw/char/pl011/vendor/syn/benches/rust.rs | 182 +
rust/hw/char/pl011/vendor/syn/meson.build | 24 +
rust/hw/char/pl011/vendor/syn/src/attr.rs | 793 +++
rust/hw/char/pl011/vendor/syn/src/bigint.rs | 66 +
rust/hw/char/pl011/vendor/syn/src/buffer.rs | 434 ++
rust/hw/char/pl011/vendor/syn/src/classify.rs | 377 ++
.../pl011/vendor/syn/src/custom_keyword.rs | 260 +
.../vendor/syn/src/custom_punctuation.rs | 304 +
rust/hw/char/pl011/vendor/syn/src/data.rs | 423 ++
rust/hw/char/pl011/vendor/syn/src/derive.rs | 259 +
.../char/pl011/vendor/syn/src/discouraged.rs | 225 +
rust/hw/char/pl011/vendor/syn/src/drops.rs | 58 +
rust/hw/char/pl011/vendor/syn/src/error.rs | 467 ++
rust/hw/char/pl011/vendor/syn/src/export.rs | 73 +
rust/hw/char/pl011/vendor/syn/src/expr.rs | 3960 +++++++++++++
rust/hw/char/pl011/vendor/syn/src/ext.rs | 136 +
rust/hw/char/pl011/vendor/syn/src/file.rs | 130 +
rust/hw/char/pl011/vendor/syn/src/fixup.rs | 218 +
.../hw/char/pl011/vendor/syn/src/gen/clone.rs | 2209 +++++++
.../hw/char/pl011/vendor/syn/src/gen/debug.rs | 3160 ++++++++++
rust/hw/char/pl011/vendor/syn/src/gen/eq.rs | 2242 +++++++
rust/hw/char/pl011/vendor/syn/src/gen/fold.rs | 3779 ++++++++++++
rust/hw/char/pl011/vendor/syn/src/gen/hash.rs | 2807 +++++++++
.../hw/char/pl011/vendor/syn/src/gen/visit.rs | 3858 ++++++++++++
.../pl011/vendor/syn/src/gen/visit_mut.rs | 3855 ++++++++++++
rust/hw/char/pl011/vendor/syn/src/generics.rs | 1286 ++++
rust/hw/char/pl011/vendor/syn/src/group.rs | 291 +
rust/hw/char/pl011/vendor/syn/src/ident.rs | 108 +
rust/hw/char/pl011/vendor/syn/src/item.rs | 3441 +++++++++++
rust/hw/char/pl011/vendor/syn/src/lib.rs | 1019 ++++
rust/hw/char/pl011/vendor/syn/src/lifetime.rs | 156 +
rust/hw/char/pl011/vendor/syn/src/lit.rs | 1830 ++++++
.../hw/char/pl011/vendor/syn/src/lookahead.rs | 169 +
rust/hw/char/pl011/vendor/syn/src/mac.rs | 223 +
rust/hw/char/pl011/vendor/syn/src/macros.rs | 166 +
rust/hw/char/pl011/vendor/syn/src/meta.rs | 427 ++
rust/hw/char/pl011/vendor/syn/src/op.rs | 219 +
rust/hw/char/pl011/vendor/syn/src/parse.rs | 1397 +++++
.../pl011/vendor/syn/src/parse_macro_input.rs | 128 +
.../char/pl011/vendor/syn/src/parse_quote.rs | 210 +
rust/hw/char/pl011/vendor/syn/src/pat.rs | 953 +++
rust/hw/char/pl011/vendor/syn/src/path.rs | 886 +++
.../char/pl011/vendor/syn/src/precedence.rs | 163 +
rust/hw/char/pl011/vendor/syn/src/print.rs | 16 +
.../char/pl011/vendor/syn/src/punctuated.rs | 1132 ++++
.../char/pl011/vendor/syn/src/restriction.rs | 176 +
rust/hw/char/pl011/vendor/syn/src/sealed.rs | 4 +
rust/hw/char/pl011/vendor/syn/src/span.rs | 63 +
rust/hw/char/pl011/vendor/syn/src/spanned.rs | 118 +
rust/hw/char/pl011/vendor/syn/src/stmt.rs | 481 ++
rust/hw/char/pl011/vendor/syn/src/thread.rs | 60 +
rust/hw/char/pl011/vendor/syn/src/token.rs | 1138 ++++
rust/hw/char/pl011/vendor/syn/src/tt.rs | 107 +
rust/hw/char/pl011/vendor/syn/src/ty.rs | 1216 ++++
rust/hw/char/pl011/vendor/syn/src/verbatim.rs | 33 +
.../char/pl011/vendor/syn/src/whitespace.rs | 65 +
.../char/pl011/vendor/syn/tests/common/eq.rs | 900 +++
.../char/pl011/vendor/syn/tests/common/mod.rs | 28 +
.../pl011/vendor/syn/tests/common/parse.rs | 49 +
.../char/pl011/vendor/syn/tests/debug/gen.rs | 5163 +++++++++++++++++
.../char/pl011/vendor/syn/tests/debug/mod.rs | 147 +
.../char/pl011/vendor/syn/tests/macros/mod.rs | 93 +
.../char/pl011/vendor/syn/tests/regression.rs | 5 +
.../vendor/syn/tests/regression/issue1108.rs | 5 +
.../vendor/syn/tests/regression/issue1235.rs | 32 +
.../char/pl011/vendor/syn/tests/repo/mod.rs | 461 ++
.../pl011/vendor/syn/tests/repo/progress.rs | 37 +
.../pl011/vendor/syn/tests/test_asyncness.rs | 43 +
.../pl011/vendor/syn/tests/test_attribute.rs | 225 +
.../vendor/syn/tests/test_derive_input.rs | 781 +++
.../char/pl011/vendor/syn/tests/test_expr.rs | 692 +++
.../pl011/vendor/syn/tests/test_generics.rs | 282 +
.../pl011/vendor/syn/tests/test_grouping.rs | 53 +
.../char/pl011/vendor/syn/tests/test_ident.rs | 87 +
.../char/pl011/vendor/syn/tests/test_item.rs | 332 ++
.../pl011/vendor/syn/tests/test_iterators.rs | 70 +
.../char/pl011/vendor/syn/tests/test_lit.rs | 331 ++
.../char/pl011/vendor/syn/tests/test_meta.rs | 154 +
.../vendor/syn/tests/test_parse_buffer.rs | 103 +
.../vendor/syn/tests/test_parse_quote.rs | 166 +
.../vendor/syn/tests/test_parse_stream.rs | 187 +
.../char/pl011/vendor/syn/tests/test_pat.rs | 152 +
.../char/pl011/vendor/syn/tests/test_path.rs | 130 +
.../pl011/vendor/syn/tests/test_precedence.rs | 537 ++
.../pl011/vendor/syn/tests/test_receiver.rs | 321 +
.../pl011/vendor/syn/tests/test_round_trip.rs | 253 +
.../pl011/vendor/syn/tests/test_shebang.rs | 67 +
.../char/pl011/vendor/syn/tests/test_size.rs | 36 +
.../char/pl011/vendor/syn/tests/test_stmt.rs | 322 +
.../vendor/syn/tests/test_token_trees.rs | 32 +
.../hw/char/pl011/vendor/syn/tests/test_ty.rs | 397 ++
.../pl011/vendor/syn/tests/test_visibility.rs | 185 +
.../char/pl011/vendor/syn/tests/zzz_stable.rs | 33 +
.../vendor/unicode-ident/.cargo-checksum.json | 1 +
.../pl011/vendor/unicode-ident/Cargo.toml | 63 +
.../pl011/vendor/unicode-ident/LICENSE-APACHE | 176 +
.../pl011/vendor/unicode-ident/LICENSE-MIT | 23 +
.../vendor/unicode-ident/LICENSE-UNICODE | 46 +
.../char/pl011/vendor/unicode-ident/README.md | 283 +
.../pl011/vendor/unicode-ident/benches/xid.rs | 124 +
.../pl011/vendor/unicode-ident/meson.build | 14 +
.../pl011/vendor/unicode-ident/src/lib.rs | 269 +
.../pl011/vendor/unicode-ident/src/tables.rs | 651 +++
.../vendor/unicode-ident/tests/compare.rs | 67 +
.../vendor/unicode-ident/tests/fst/mod.rs | 11 +
.../unicode-ident/tests/fst/xid_continue.fst | Bin 0 -> 73249 bytes
.../unicode-ident/tests/fst/xid_start.fst | Bin 0 -> 65487 bytes
.../vendor/unicode-ident/tests/roaring/mod.rs | 21 +
.../vendor/unicode-ident/tests/static_size.rs | 95 +
.../vendor/unicode-ident/tests/tables/mod.rs | 7 +
.../unicode-ident/tests/tables/tables.rs | 347 ++
.../vendor/unicode-ident/tests/trie/mod.rs | 7 +
.../vendor/unicode-ident/tests/trie/trie.rs | 445 ++
.../vendor/version_check/.cargo-checksum.json | 1 +
.../pl011/vendor/version_check/Cargo.toml | 24 +
.../pl011/vendor/version_check/LICENSE-APACHE | 201 +
.../pl011/vendor/version_check/LICENSE-MIT | 19 +
.../char/pl011/vendor/version_check/README.md | 80 +
.../pl011/vendor/version_check/meson.build | 14 +
.../pl011/vendor/version_check/src/channel.rs | 193 +
.../pl011/vendor/version_check/src/date.rs | 203 +
.../pl011/vendor/version_check/src/lib.rs | 493 ++
.../pl011/vendor/version_check/src/version.rs | 316 +
365 files changed, 108770 insertions(+)
create mode 100644 rust/hw/char/pl011/vendor/either/README.rst
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/CHANGELOG.md
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/LICENSE.txt
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/README.md
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/meson.build
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/tests/tests.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/README.md
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/meson.build
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize/split.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal/struct_gen.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/debug_bits.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/default_bits.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/fmt_bits.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/from_bits.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared/discriminant_assigner.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared/fallback.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared/util.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/try_from_bits.rs
create mode 100644 rust/hw/char/pl011/vendor/bilge/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/bilge/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/bilge/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/bilge/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/bilge/README.md
create mode 100644 rust/hw/char/pl011/vendor/bilge/meson.build
create mode 100644 rust/hw/char/pl011/vendor/bilge/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/either/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/either/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/either/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/either/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/either/README-crates.io.md
create mode 100644 rust/hw/char/pl011/vendor/either/meson.build
create mode 100644 rust/hw/char/pl011/vendor/either/src/into_either.rs
create mode 100644 rust/hw/char/pl011/vendor/either/src/iterator.rs
create mode 100644 rust/hw/char/pl011/vendor/either/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/either/src/serde_untagged.rs
create mode 100644 rust/hw/char/pl011/vendor/either/src/serde_untagged_optional.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/itertools/CHANGELOG.md
create mode 100644 rust/hw/char/pl011/vendor/itertools/Cargo.lock
create mode 100644 rust/hw/char/pl011/vendor/itertools/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/itertools/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/itertools/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/itertools/README.md
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/bench1.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/combinations.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/combinations_with_replacement.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/extra/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/extra/zipslices.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/fold_specialization.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/powerset.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/tree_fold1.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/tuple_combinations.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/tuples.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/examples/iris.data
create mode 100644 rust/hw/char/pl011/vendor/itertools/examples/iris.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/meson.build
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/coalesce.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/map.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/multi_product.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/combinations.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/combinations_with_replacement.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/concat_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/cons_tuples_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/diff.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/duplicates_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/either_or_both.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/exactly_one_err.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/extrema_set.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/flatten_ok.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/format.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/free.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/group_map.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/groupbylazy.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/grouping_map.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/impl_macros.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/intersperse.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/k_smallest.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/kmerge_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/lazy_buffer.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/merge_join.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/minmax.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/multipeek_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/pad_tail.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/peek_nth.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/peeking_take_while.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/permutations.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/powerset.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/process_results_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/put_back_n_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/rciter_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/repeatn.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/size_hint.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/sources.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/take_while_inclusive.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/tee.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/tuple_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/unique_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/unziptuple.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/with_position.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/zip_eq_impl.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/zip_longest.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/src/ziptuple.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/adaptors_no_collect.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/flatten_ok.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/macros_hygiene.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/merge_join.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/peeking_take_while.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/quick.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/specializations.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/test_core.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/test_std.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/tuples.rs
create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/zip.rs
create mode 100644 rust/hw/char/pl011/vendor/meson.build
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/build.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/meson.build
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/src/parse.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/src/settings.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/CHANGELOG.md
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/README.md
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/build.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/meson.build
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/diagnostic.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/dummy.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/imp/delegate.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/imp/fallback.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/macros.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/sealed.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/macro-errors.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ok.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/runtime-errors.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.stderr
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/README.md
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/build.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/build/probe.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/meson.build
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/rust-toolchain.toml
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/detection.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/extra.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/fallback.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/location.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/marker.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/parse.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/rcvec.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/wrapper.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/comments.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/features.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/marker.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/test.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/test_fmt.rs
create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/test_size.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/quote/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/quote/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/quote/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/quote/README.md
create mode 100644 rust/hw/char/pl011/vendor/quote/meson.build
create mode 100644 rust/hw/char/pl011/vendor/quote/rust-toolchain.toml
create mode 100644 rust/hw/char/pl011/vendor/quote/src/ext.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/src/format.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/src/ident_fragment.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/src/runtime.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/src/spanned.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/src/to_tokens.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/compiletest.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/test.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.stderr
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.stderr
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.stderr
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.stderr
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.rs
create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.stderr
create mode 100644 rust/hw/char/pl011/vendor/syn/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/syn/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/syn/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/syn/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/syn/README.md
create mode 100644 rust/hw/char/pl011/vendor/syn/benches/file.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/benches/rust.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/meson.build
create mode 100644 rust/hw/char/pl011/vendor/syn/src/attr.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/bigint.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/buffer.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/classify.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/custom_keyword.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/custom_punctuation.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/data.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/derive.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/discouraged.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/drops.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/error.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/export.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/expr.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/ext.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/file.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/fixup.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/clone.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/debug.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/eq.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/fold.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/hash.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/visit.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/visit_mut.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/generics.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/group.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/ident.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/item.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/lifetime.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/lit.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/lookahead.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/mac.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/macros.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/meta.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/op.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/parse.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/parse_macro_input.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/parse_quote.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/pat.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/path.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/precedence.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/print.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/punctuated.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/restriction.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/sealed.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/span.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/spanned.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/stmt.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/thread.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/token.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/tt.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/ty.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/verbatim.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/src/whitespace.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/common/eq.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/common/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/common/parse.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/debug/gen.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/debug/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/macros/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/regression.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/regression/issue1108.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/regression/issue1235.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/repo/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/repo/progress.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_asyncness.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_attribute.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_derive_input.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_expr.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_generics.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_grouping.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_ident.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_item.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_iterators.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_lit.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_meta.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_parse_buffer.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_parse_quote.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_parse_stream.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_pat.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_path.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_precedence.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_receiver.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_round_trip.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_shebang.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_size.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_stmt.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_token_trees.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_ty.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_visibility.rs
create mode 100644 rust/hw/char/pl011/vendor/syn/tests/zzz_stable.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/LICENSE-UNICODE
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/README.md
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/benches/xid.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/meson.build
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/src/tables.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/compare.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/fst/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/fst/xid_continue.fst
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/fst/xid_start.fst
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/roaring/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/static_size.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/tables/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/tables/tables.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/trie/mod.rs
create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/trie/trie.rs
create mode 100644 rust/hw/char/pl011/vendor/version_check/.cargo-checksum.json
create mode 100644 rust/hw/char/pl011/vendor/version_check/Cargo.toml
create mode 100644 rust/hw/char/pl011/vendor/version_check/LICENSE-APACHE
create mode 100644 rust/hw/char/pl011/vendor/version_check/LICENSE-MIT
create mode 100644 rust/hw/char/pl011/vendor/version_check/README.md
create mode 100644 rust/hw/char/pl011/vendor/version_check/meson.build
create mode 100644 rust/hw/char/pl011/vendor/version_check/src/channel.rs
create mode 100644 rust/hw/char/pl011/vendor/version_check/src/date.rs
create mode 100644 rust/hw/char/pl011/vendor/version_check/src/lib.rs
create mode 100644 rust/hw/char/pl011/vendor/version_check/src/version.rs
diff --git a/rust/hw/char/pl011/vendor/either/README.rst b/rust/hw/char/pl011/vendor/either/README.rst
new file mode 100644
index 0000000000..659257fdcd
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/either/README.rst
@@ -0,0 +1,185 @@
+
+Either
+======
+
+The enum ``Either`` with variants ``Left`` and ``Right`` and trait
+implementations including Iterator, Read, Write.
+
+Either has methods that are similar to Option and Result.
+
+Includes convenience macros ``try_left!()`` and ``try_right!()`` to use for
+short-circuiting logic.
+
+Please read the `API documentation here`__
+
+__ https://docs.rs/either/
+
+|build_status|_ |crates|_
+
+.. |build_status| image:: https://github.com/rayon-rs/either/workflows/CI/badge.svg?branch=main
+.. _build_status: https://github.com/rayon-rs/either/actions
+
+.. |crates| image:: https://img.shields.io/crates/v/either.svg
+.. _crates: https://crates.io/crates/either
+
+How to use with cargo::
+
+ [dependencies]
+ either = "1.12"
+
+
+Recent Changes
+--------------
+
+- 1.12.0
+
+ - **MSRV**: ``either`` now requires Rust 1.37 or later.
+
+ - Specialize ``nth_back`` for ``Either`` and ``IterEither``, by @cuviper (#106)
+
+- 1.11.0
+
+ - Add new trait ``IntoEither`` that is useful to convert to ``Either`` in method chains,
+ by @SFM61319 (#101)
+
+- 1.10.0
+
+ - Add new methods ``.factor_iter()``, ``.factor_iter_mut()``, and ``.factor_into_iter()``
+ that return ``Either`` items, plus ``.iter()`` and ``.iter_mut()`` to convert to direct
+ referene iterators; by @aj-bagwell and @cuviper (#91)
+
+- 1.9.0
+
+ - Add new methods ``.map_either()`` and ``.map_either_with()``, by @nasadorian (#82)
+
+- 1.8.1
+
+ - Clarified that the multiple licenses are combined with OR.
+
+- 1.8.0
+
+ - **MSRV**: ``either`` now requires Rust 1.36 or later.
+
+ - Add new methods ``.as_pin_ref()`` and ``.as_pin_mut()`` to project a
+ pinned ``Either`` as inner ``Pin`` variants, by @cuviper (#77)
+
+ - Implement the ``Future`` trait, by @cuviper (#77)
+
+ - Specialize more methods of the ``io`` traits, by @Kixunil and @cuviper (#75)
+
+- 1.7.0
+
+ - **MSRV**: ``either`` now requires Rust 1.31 or later.
+
+ - Export the macro ``for_both!``, by @thomaseizinger (#58)
+
+ - Implement the ``io::Seek`` trait, by @Kerollmops (#60)
+
+ - Add new method ``.either_into()`` for ``Into`` conversion, by @TonalidadeHidrica (#63)
+
+ - Add new methods ``.factor_ok()``, ``.factor_err()``, and ``.factor_none()``,
+ by @zachs18 (#67)
+
+ - Specialize ``source`` in the ``Error`` implementation, by @thomaseizinger (#69)
+
+ - Specialize more iterator methods and implement the ``FusedIterator`` trait,
+ by @Ten0 (#66) and @cuviper (#71)
+
+ - Specialize ``Clone::clone_from``, by @cuviper (#72)
+
+- 1.6.1
+
+ - Add new methods ``.expect_left()``, ``.unwrap_left()``,
+ and equivalents on the right, by @spenserblack (#51)
+
+- 1.6.0
+
+ - Add new modules ``serde_untagged`` and ``serde_untagged_optional`` to customize
+ how ``Either`` fields are serialized in other types, by @MikailBag (#49)
+
+- 1.5.3
+
+ - Add new method ``.map()`` for ``Either<T, T>`` by @nvzqz (#40).
+
+- 1.5.2
+
+ - Add new methods ``.left_or()``, ``.left_or_default()``, ``.left_or_else()``,
+ and equivalents on the right, by @DCjanus (#36)
+
+- 1.5.1
+
+ - Add ``AsRef`` and ``AsMut`` implementations for common unsized types:
+ ``str``, ``[T]``, ``CStr``, ``OsStr``, and ``Path``, by @mexus (#29)
+
+- 1.5.0
+
+ - Add new methods ``.factor_first()``, ``.factor_second()`` and ``.into_inner()``
+ by @mathstuf (#19)
+
+- 1.4.0
+
+ - Add inherent method ``.into_iter()`` by @cuviper (#12)
+
+- 1.3.0
+
+ - Add opt-in serde support by @hcpl
+
+- 1.2.0
+
+ - Add method ``.either_with()`` by @Twey (#13)
+
+- 1.1.0
+
+ - Add methods ``left_and_then``, ``right_and_then`` by @rampantmonkey
+ - Include license files in the repository and released crate
+
+- 1.0.3
+
+ - Add crate categories
+
+- 1.0.2
+
+ - Forward more ``Iterator`` methods
+ - Implement ``Extend`` for ``Either<L, R>`` if ``L, R`` do.
+
+- 1.0.1
+
+ - Fix ``Iterator`` impl for ``Either`` to forward ``.fold()``.
+
+- 1.0.0
+
+ - Add default crate feature ``use_std`` so that you can opt out of linking to
+ std.
+
+- 0.1.7
+
+ - Add methods ``.map_left()``, ``.map_right()`` and ``.either()``.
+ - Add more documentation
+
+- 0.1.3
+
+ - Implement Display, Error
+
+- 0.1.2
+
+ - Add macros ``try_left!`` and ``try_right!``.
+
+- 0.1.1
+
+ - Implement Deref, DerefMut
+
+- 0.1.0
+
+ - Initial release
+ - Support Iterator, Read, Write
+
+License
+-------
+
+Dual-licensed to be compatible with the Rust project.
+
+Licensed under the Apache License, Version 2.0
+https://www.apache.org/licenses/LICENSE-2.0 or the MIT license
+https://opensource.org/licenses/MIT, at your
+option. This file may not be copied, modified, or distributed
+except according to those terms.
diff --git a/rust/hw/char/pl011/vendor/arbitrary-int/.cargo-checksum.json b/rust/hw/char/pl011/vendor/arbitrary-int/.cargo-checksum.json
new file mode 100644
index 0000000000..39c2d4d0e0
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/arbitrary-int/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"d34e39d5bd6b0ba740cae9b7afe9fdf73ae1bedc080de338d238ef577cffe963","Cargo.toml":"0a410a8ab28d72b00c04feeb289be7b725347732443cee6e1a91fb3f193e907b","LICENSE.txt":"6982f0cd109b04512cbb5f0e0f0ef82154f33a57d2127afe058ecc72039ab88c","README.md":"c3ee6e3ec5365bd9f6daddacf2b49204d7d777d09afe896b57451bb0365bea21","src/lib.rs":"9bda88688cfebe72e386d9fbb0bd4570a7631ccc20eef58a0e14b6aadd4724ea","tests/tests.rs":"116002067e9b697d4f22b5f28f23363ade2ed9dd6b59661388272f7c6d4b20f1"},"package":"c84fc003e338a6f69fbd4f7fe9f92b535ff13e9af8997f3b14b6ddff8b1df46d"}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/arbitrary-int/CHANGELOG.md b/rust/hw/char/pl011/vendor/arbitrary-int/CHANGELOG.md
new file mode 100644
index 0000000000..a31fa94c96
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/arbitrary-int/CHANGELOG.md
@@ -0,0 +1,47 @@
+# Changelog
+
+## arbitrary-int 1.2.7
+
+### Added
+
+- Support `Step` so that arbitrary-int can be used in a range expression, e.g. `for n in u3::MIN..=u3::MAX { println!("{n}") }`. Note this trait is currently unstable, and so is only usable in nightly. Enable this feature with `step_trait`.
+- Support formatting via [defmt](https://crates.io/crates/defmt). Enable the option `defmt` feature
+- Support serializing and deserializing via [serde](https://crates.io/crates/serde). Enable the option `serde` feature
+- Support `Mul`, `MulAssign`, `Div`, `DivAssign`
+- The following new methods were implemented to make arbitrary ints feel more like built-in types:
+ * `wrapping_add`, `wrapping_sub`, `wrapping_mul`, `wrapping_div`, `wrapping_shl`, `wrapping_shr`
+ * `saturating_add`, `saturating_sub`, `saturating_mul`, `saturating_div`, `saturating_pow`
+ * `checked_add`, `checked_sub`, `checked_mul`, `checked_div`, `checked_shl`, `checked_shr`
+ * `overflowing_add`, `overflowing_sub`, `overflowing_mul`, `overflowing_div`, `overflowing_shl`, `overflowing_shr`
+
+### Changed
+- In debug builds, `<<` (`Shl`, `ShlAssign`) and `>>` (`Shr`, `ShrAssign`) now bounds-check the shift amount using the same semantics as built-in shifts. For example, shifting a u5 by 5 or more bits will now panic as expected.
+
+## arbitrary-int 1.2.6
+
+### Added
+
+- Support `LowerHex`, `UpperHex`, `Octal`, `Binary` so that arbitrary-int can be printed via e.g. `format!("{:x}", u4::new(12))`
+- Support `Hash` so that arbitrary-int can be used in hash tables
+
+### Changed
+
+- As support for `[const_trait]` has recently been removed from structs like `From<T>` in upstream Rust, opting-in to the `nightly` feature no longer enables this behavior as that would break the build. To continue using this feature with older compiler versions, use `const_convert_and_const_trait_impl` instead.
+
+## arbitrary-int 1.2.5
+
+### Added
+
+- Types that can be expressed as full bytes (e.g. u24, u48) have the following new methods:
+ * `swap_bytes()`
+ * `to_le_bytes()`
+ * `to_be_bytes()`
+ * `to_ne_bytes()`
+ * `to_be()`
+ * `to_le()`
+
+### Changed
+
+- `#[inline]` is specified in more places
+
+### Fixed
diff --git a/rust/hw/char/pl011/vendor/arbitrary-int/Cargo.toml b/rust/hw/char/pl011/vendor/arbitrary-int/Cargo.toml
new file mode 100644
index 0000000000..810071d602
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/arbitrary-int/Cargo.toml
@@ -0,0 +1,54 @@
+# 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"
+name = "arbitrary-int"
+version = "1.2.7"
+authors = ["Daniel Lehmann <danlehmannmuc@gmail.com>"]
+description = "Modern and lightweight implementation of u2, u3, u4, ..., u127."
+readme = "README.md"
+keywords = [
+ "integer",
+ "unaligned",
+ "misaligned",
+]
+categories = [
+ "embedded",
+ "no-std",
+ "data-structures",
+]
+license = "MIT"
+repository = "https://github.com/danlehmann/arbitrary-int"
+
+[dependencies.defmt]
+version = "0.3.5"
+optional = true
+
+[dependencies.num-traits]
+version = "0.2.17"
+optional = true
+default-features = false
+
+[dependencies.serde]
+version = "1.0"
+optional = true
+default-features = false
+
+[dev-dependencies.serde_test]
+version = "1.0"
+
+[features]
+const_convert_and_const_trait_impl = []
+defmt = ["dep:defmt"]
+serde = ["dep:serde"]
+std = []
+step_trait = []
diff --git a/rust/hw/char/pl011/vendor/arbitrary-int/LICENSE.txt b/rust/hw/char/pl011/vendor/arbitrary-int/LICENSE.txt
new file mode 100644
index 0000000000..eb8c29c461
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/arbitrary-int/LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Daniel Lehmann
+
+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.
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/arbitrary-int/README.md b/rust/hw/char/pl011/vendor/arbitrary-int/README.md
new file mode 100644
index 0000000000..d34676fd93
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/arbitrary-int/README.md
@@ -0,0 +1,72 @@
+# arbitrary-int
+
+This crate implements arbitrary numbers for Rust. Once included, you can use types like `u5` or `u120`.
+
+## Why yet another arbitrary integer crate?
+
+There are quite a few similar crates to this one (the most famous being https://crates.io/crates/ux). After trying out a
+few of them I just realized that they are all very heavy: They create a ton of classes and take seconds to compile.
+
+This crate is designed to be very short, using const generics. Instead of introducing ~123 new structs, this crates only
+introduces 5 (one for `u8`, `u16`, `u32`, `u64`, `u128`) and uses const generics for the specific bit depth.
+It does introduce 123 new type aliases (`u1`, `u2`, etc.), but these don't stress the compiler nearly as much.
+
+Additionally, most of its functions are const, so that they can be used in const contexts.
+
+## How to use
+
+Unlike primitive data types like `u32`, there is no intrinsic syntax (Rust does not allow that). An instance is created as
+follows:
+
+```rust
+let value9 = u9::new(30);
+```
+
+This will create a value with 9 bits. If the value passed into `new()` doesn't fit, a panic! will be raised. This means
+that a function that accepts a `u9` as an argument can be certain that its contents are never larger than an `u9`.
+
+Standard operators are all overloaded, so it is possible to perform calculations using this type. Note that addition
+and subtraction (at least in debug mode) performs bounds check. If this is undesired, see chapter num-traits below.
+
+Internally, `u9` will hold its data in an `u16`. It is possible to get this value:
+
+```rust
+let value9 = u9::new(30).value();
+```
+
+## Underlying data type
+
+This crate defines types `u1`, `u2`, .., `u126`, `u127` (skipping the normal `u8`, `u16`, `u32`, `u64`, `u128`). Each of those types holds
+its actual data in the next larger data type (e.g. a `u14` internally has an `u16`, a `u120` internally has an `u128`). However,
+`uXX` are just type aliases; it is also possible to use the actual underlying generic struct:
+
+```rust
+let a = UInt::<u8, 5>::new(0b10101));
+let b = UInt::<u32, 5>::new(0b10101));
+```
+
+In this example, `a` will have 5 bits and be represented by a `u8`. This is identical to `u5`. `b` however is represented by a
+`u32`, so it is a different type from `u5`.
+
+## Extract
+
+A common source for arbitrary integers is by extracting them from bitfields. For example, if data contained 32 bits and
+we want to extract bits `4..=9`, we could perform the following:
+
+```rust
+let a = u6::new(((data >> 4) & 0b111111) as u8);
+```
+
+This is a pretty common operation, but it's easy to get it wrong: The number of 1s and `u6` have to match. Also, `new()`
+will internally perform a bounds-check, which can panic. Thirdly, a type-cast is often needed.
+To make this easier, various extract methods exist that handle shifting and masking, for example:
+
+```rust
+let a = u6::extract_u32(data, 4);
+let b = u12::extract_u128(data2, 63);
+```
+
+## num-traits
+
+By default, arbitrary-int doesn't require any other traits. It has optional support for num-traits however. It
+implements `WrappingAdd`, `WrappingSub`, which (unlike the regular addition and subtraction) don't perform bounds checks.
diff --git a/rust/hw/char/pl011/vendor/arbitrary-int/meson.build b/rust/hw/char/pl011/vendor/arbitrary-int/meson.build
new file mode 100644
index 0000000000..e02139a5bc
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/arbitrary-int/meson.build
@@ -0,0 +1,14 @@
+_arbitrary_int_rs = static_library(
+ 'arbitrary_int',
+ files('src/lib.rs'),
+ gnu_symbol_visibility: 'hidden',
+ rust_abi: 'rust',
+ rust_args: rust_args + [
+ '--edition', '2021',
+ ],
+ dependencies: [],
+)
+
+dep_arbitrary_int = declare_dependency(
+ link_with: _arbitrary_int_rs,
+)
diff --git a/rust/hw/char/pl011/vendor/arbitrary-int/src/lib.rs b/rust/hw/char/pl011/vendor/arbitrary-int/src/lib.rs
new file mode 100644
index 0000000000..4c2b9c3997
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/arbitrary-int/src/lib.rs
@@ -0,0 +1,1489 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![cfg_attr(
+ feature = "const_convert_and_const_trait_impl",
+ feature(const_convert, const_trait_impl)
+)]
+#![cfg_attr(feature = "step_trait", feature(step_trait))]
+
+use core::fmt::{Binary, Debug, Display, Formatter, LowerHex, Octal, UpperHex};
+use core::hash::{Hash, Hasher};
+#[cfg(feature = "step_trait")]
+use core::iter::Step;
+#[cfg(feature = "num-traits")]
+use core::num::Wrapping;
+use core::ops::{
+ Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
+ Mul, MulAssign, Not, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
+};
+#[cfg(feature = "serde")]
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
+
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub struct TryNewError;
+
+impl Display for TryNewError {
+ fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
+ write!(f, "Value too large to fit within this integer type")
+ }
+}
+
+#[cfg_attr(feature = "const_convert_and_const_trait_impl", const_trait)]
+pub trait Number: Sized {
+ type UnderlyingType: Debug
+ + From<u8>
+ + TryFrom<u16>
+ + TryFrom<u32>
+ + TryFrom<u64>
+ + TryFrom<u128>;
+
+ /// Number of bits that can fit in this type
+ const BITS: usize;
+
+ /// Minimum value that can be represented by this type
+ const MIN: Self;
+
+ /// Maximum value that can be represented by this type
+ const MAX: Self;
+
+ fn new(value: Self::UnderlyingType) -> Self;
+
+ fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError>;
+
+ fn value(self) -> Self::UnderlyingType;
+}
+
+#[cfg(feature = "const_convert_and_const_trait_impl")]
+macro_rules! impl_number_native {
+ ($( $type:ty ),+) => {
+ $(
+ impl const Number for $type {
+ type UnderlyingType = $type;
+ const BITS: usize = Self::BITS as usize;
+ const MIN: Self = Self::MIN;
+ const MAX: Self = Self::MAX;
+
+ #[inline]
+ fn new(value: Self::UnderlyingType) -> Self { value }
+
+ #[inline]
+ fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError> { Ok(value) }
+
+ #[inline]
+ fn value(self) -> Self::UnderlyingType { self }
+ }
+ )+
+ };
+}
+
+#[cfg(not(feature = "const_convert_and_const_trait_impl"))]
+macro_rules! impl_number_native {
+ ($( $type:ty ),+) => {
+ $(
+ impl Number for $type {
+ type UnderlyingType = $type;
+ const BITS: usize = Self::BITS as usize;
+ const MIN: Self = Self::MIN;
+ const MAX: Self = Self::MAX;
+
+ #[inline]
+ fn new(value: Self::UnderlyingType) -> Self { value }
+
+ #[inline]
+ fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError> { Ok(value) }
+
+ #[inline]
+ fn value(self) -> Self::UnderlyingType { self }
+ }
+ )+
+ };
+}
+
+impl_number_native!(u8, u16, u32, u64, u128);
+
+struct CompileTimeAssert<const A: usize, const B: usize> {}
+
+impl<const A: usize, const B: usize> CompileTimeAssert<A, B> {
+ pub const SMALLER_OR_EQUAL: () = {
+ assert!(A <= B);
+ };
+}
+
+#[derive(Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd)]
+pub struct UInt<T, const BITS: usize> {
+ value: T,
+}
+
+impl<T: Copy, const BITS: usize> UInt<T, BITS> {
+ pub const BITS: usize = BITS;
+
+ /// Returns the type as a fundamental data type
+ #[inline]
+ pub const fn value(self) -> T {
+ self.value
+ }
+
+ /// Initializes a new value without checking the bounds
+ ///
+ /// # Safety
+ /// Must only be called with a value less than or equal to [Self::MAX](Self::MAX) value.
+ #[inline]
+ pub const unsafe fn new_unchecked(value: T) -> Self {
+ Self { value }
+ }
+}
+
+impl<T, const BITS: usize> UInt<T, BITS>
+where
+ Self: Number,
+ T: Copy,
+{
+ pub const MASK: T = Self::MAX.value;
+}
+
+// Next are specific implementations for u8, u16, u32, u64 and u128. A couple notes:
+// - The existence of MAX also serves as a neat bounds-check for BITS: If BITS is too large,
+// the subtraction overflows which will fail to compile. This simplifies things a lot.
+// However, that only works if every constructor also uses MAX somehow (doing let _ = MAX is enough)
+
+#[cfg(feature = "const_convert_and_const_trait_impl")]
+macro_rules! uint_impl_num {
+ ($($type:ident),+) => {
+ $(
+ impl<const BITS: usize> const Number for UInt<$type, BITS> {
+ type UnderlyingType = $type;
+
+ const BITS: usize = BITS;
+
+ const MIN: Self = Self { value: 0 };
+
+ // The existence of MAX also serves as a bounds check: If NUM_BITS is > available bits,
+ // we will get a compiler error right here
+ const MAX: Self = Self { value: (<$type as Number>::MAX >> (<$type as Number>::BITS - Self::BITS)) };
+
+ #[inline]
+ fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError> {
+ if value <= Self::MAX.value {
+ Ok(Self { value })
+ } else {
+ Err(TryNewError{})
+ }
+ }
+
+ #[inline]
+ fn new(value: $type) -> Self {
+ assert!(value <= Self::MAX.value);
+
+ Self { value }
+ }
+
+ #[inline]
+ fn value(self) -> $type {
+ self.value
+ }
+ }
+ )+
+ };
+}
+
+#[cfg(not(feature = "const_convert_and_const_trait_impl"))]
+macro_rules! uint_impl_num {
+ ($($type:ident),+) => {
+ $(
+ impl<const BITS: usize> Number for UInt<$type, BITS> {
+ type UnderlyingType = $type;
+
+ const BITS: usize = BITS;
+
+ const MIN: Self = Self { value: 0 };
+
+ // The existence of MAX also serves as a bounds check: If NUM_BITS is > available bits,
+ // we will get a compiler error right here
+ const MAX: Self = Self { value: (<$type as Number>::MAX >> (<$type as Number>::BITS - Self::BITS)) };
+
+ #[inline]
+ fn try_new(value: Self::UnderlyingType) -> Result<Self, TryNewError> {
+ if value <= Self::MAX.value {
+ Ok(Self { value })
+ } else {
+ Err(TryNewError{})
+ }
+ }
+
+ #[inline]
+ fn new(value: $type) -> Self {
+ assert!(value <= Self::MAX.value);
+
+ Self { value }
+ }
+
+ #[inline]
+ fn value(self) -> $type {
+ self.value
+ }
+ }
+ )+
+ };
+}
+
+uint_impl_num!(u8, u16, u32, u64, u128);
+
+macro_rules! uint_impl {
+ ($($type:ident),+) => {
+ $(
+ impl<const BITS: usize> UInt<$type, BITS> {
+ /// Creates an instance. Panics if the given value is outside of the valid range
+ #[inline]
+ pub const fn new(value: $type) -> Self {
+ assert!(value <= Self::MAX.value);
+
+ Self { value }
+ }
+
+ /// Creates an instance or an error if the given value is outside of the valid range
+ #[inline]
+ pub const fn try_new(value: $type) -> Result<Self, TryNewError> {
+ if value <= Self::MAX.value {
+ Ok(Self { value })
+ } else {
+ Err(TryNewError {})
+ }
+ }
+
+ #[deprecated(note = "Use one of the specific functions like extract_u32")]
+ pub const fn extract(value: $type, start_bit: usize) -> Self {
+ assert!(start_bit + BITS <= $type::BITS as usize);
+ // Query MAX to ensure that we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
+ let _ = Self::MAX;
+
+ Self {
+ value: (value >> start_bit) & Self::MAX.value,
+ }
+ }
+
+ /// Extracts bits from a given value. The extract is equivalent to: `new((value >> start_bit) & MASK)`
+ /// Unlike new, extract doesn't perform range-checking so it is slightly more efficient.
+ /// panics if start_bit+<number of bits> doesn't fit within an u8, e.g. u5::extract_u8(8, 4);
+ #[inline]
+ pub const fn extract_u8(value: u8, start_bit: usize) -> Self {
+ assert!(start_bit + BITS <= 8);
+ // Query MAX to ensure that we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
+ let _ = Self::MAX;
+
+ Self {
+ value: ((value >> start_bit) as $type) & Self::MAX.value,
+ }
+ }
+
+ /// Extracts bits from a given value. The extract is equivalent to: `new((value >> start_bit) & MASK)`
+ /// Unlike new, extract doesn't perform range-checking so it is slightly more efficient
+ /// panics if start_bit+<number of bits> doesn't fit within a u16, e.g. u15::extract_u16(8, 2);
+ #[inline]
+ pub const fn extract_u16(value: u16, start_bit: usize) -> Self {
+ assert!(start_bit + BITS <= 16);
+ // Query MAX to ensure that we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
+ let _ = Self::MAX;
+
+ Self {
+ value: ((value >> start_bit) as $type) & Self::MAX.value,
+ }
+ }
+
+ /// Extracts bits from a given value. The extract is equivalent to: `new((value >> start_bit) & MASK)`
+ /// Unlike new, extract doesn't perform range-checking so it is slightly more efficient
+ /// panics if start_bit+<number of bits> doesn't fit within a u32, e.g. u30::extract_u32(8, 4);
+ #[inline]
+ pub const fn extract_u32(value: u32, start_bit: usize) -> Self {
+ assert!(start_bit + BITS <= 32);
+ // Query MAX to ensure that we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
+ let _ = Self::MAX;
+
+ Self {
+ value: ((value >> start_bit) as $type) & Self::MAX.value,
+ }
+ }
+
+ /// Extracts bits from a given value. The extract is equivalent to: `new((value >> start_bit) & MASK)`
+ /// Unlike new, extract doesn't perform range-checking so it is slightly more efficient
+ /// panics if start_bit+<number of bits> doesn't fit within a u64, e.g. u60::extract_u64(8, 5);
+ #[inline]
+ pub const fn extract_u64(value: u64, start_bit: usize) -> Self {
+ assert!(start_bit + BITS <= 64);
+ // Query MAX to ensure that we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
+ let _ = Self::MAX;
+
+ Self {
+ value: ((value >> start_bit) as $type) & Self::MAX.value,
+ }
+ }
+
+ /// Extracts bits from a given value. The extract is equivalent to: `new((value >> start_bit) & MASK)`
+ /// Unlike new, extract doesn't perform range-checking so it is slightly more efficient
+ /// panics if start_bit+<number of bits> doesn't fit within a u128, e.g. u120::extract_u64(8, 9);
+ #[inline]
+ pub const fn extract_u128(value: u128, start_bit: usize) -> Self {
+ assert!(start_bit + BITS <= 128);
+ // Query MAX to ensure that we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
+ let _ = Self::MAX;
+
+ Self {
+ value: ((value >> start_bit) as $type) & Self::MAX.value,
+ }
+ }
+
+ /// Returns a UInt with a wider bit depth but with the same base data type
+ pub const fn widen<const BITS_RESULT: usize>(
+ self,
+ ) -> UInt<$type, BITS_RESULT> {
+ let _ = CompileTimeAssert::<BITS, BITS_RESULT>::SMALLER_OR_EQUAL;
+ // Query MAX of the result to ensure we get a compiler error if the current definition is bogus (e.g. <u8, 9>)
+ let _ = UInt::<$type, BITS_RESULT>::MAX;
+ UInt::<$type, BITS_RESULT> { value: self.value }
+ }
+
+ pub const fn wrapping_add(self, rhs: Self) -> Self {
+ let sum = self.value.wrapping_add(rhs.value);
+ Self {
+ value: sum & Self::MASK,
+ }
+ }
+
+ pub const fn wrapping_sub(self, rhs: Self) -> Self {
+ let sum = self.value.wrapping_sub(rhs.value);
+ Self {
+ value: sum & Self::MASK,
+ }
+ }
+
+ pub const fn wrapping_mul(self, rhs: Self) -> Self {
+ let sum = self.value.wrapping_mul(rhs.value);
+ Self {
+ value: sum & Self::MASK,
+ }
+ }
+
+ pub const fn wrapping_div(self, rhs: Self) -> Self {
+ let sum = self.value.wrapping_div(rhs.value);
+ Self {
+ // No need to mask here - divisions always produce a result that is <= self
+ value: sum,
+ }
+ }
+
+ pub const fn wrapping_shl(self, rhs: u32) -> Self {
+ // modulo is expensive on some platforms, so only do it when necessary
+ let shift_amount = if rhs >= (BITS as u32) {
+ rhs % (BITS as u32)
+ } else {
+ rhs
+ };
+
+ Self {
+ // We could use wrapping_shl here to make Debug builds slightly smaller;
+ // the downside would be that on weird CPUs that don't do wrapping_shl by
+ // default release builds would get slightly worse. Using << should give
+ // good release performance everywere
+ value: (self.value << shift_amount) & Self::MASK,
+ }
+ }
+
+ pub const fn wrapping_shr(self, rhs: u32) -> Self {
+ // modulo is expensive on some platforms, so only do it when necessary
+ let shift_amount = if rhs >= (BITS as u32) {
+ rhs % (BITS as u32)
+ } else {
+ rhs
+ };
+
+ Self {
+ value: (self.value >> shift_amount),
+ }
+ }
+
+ pub const fn saturating_add(self, rhs: Self) -> Self {
+ let saturated = if core::mem::size_of::<$type>() << 3 == BITS {
+ // We are something like a UInt::<u8; 8>. We can fallback to the base implementation
+ self.value.saturating_add(rhs.value)
+ } else {
+ // We're dealing with fewer bits than the underlying type (e.g. u7).
+ // That means the addition can never overflow the underlying type
+ let sum = self.value.wrapping_add(rhs.value);
+ let max = Self::MAX.value();
+ if sum > max { max } else { sum }
+ };
+ Self {
+ value: saturated,
+ }
+ }
+
+ pub const fn saturating_sub(self, rhs: Self) -> Self {
+ // For unsigned numbers, the only difference is when we reach 0 - which is the same
+ // no matter the data size
+ Self {
+ value: self.value.saturating_sub(rhs.value),
+ }
+ }
+
+ pub const fn saturating_mul(self, rhs: Self) -> Self {
+ let product = if BITS << 1 <= (core::mem::size_of::<$type>() << 3) {
+ // We have half the bits (e.g. u4 * u4) of the base type, so we can't overflow the base type
+ // wrapping_mul likely provides the best performance on all cpus
+ self.value.wrapping_mul(rhs.value)
+ } else {
+ // We have more than half the bits (e.g. u6 * u6)
+ self.value.saturating_mul(rhs.value)
+ };
+
+ let max = Self::MAX.value();
+ let saturated = if product > max { max } else { product };
+ Self {
+ value: saturated,
+ }
+ }
+
+ pub const fn saturating_div(self, rhs: Self) -> Self {
+ // When dividing unsigned numbers, we never need to saturate.
+ // Divison by zero in saturating_div throws an exception (in debug and release mode),
+ // so no need to do anything special there either
+ Self {
+ value: self.value.saturating_div(rhs.value),
+ }
+ }
+
+ pub const fn saturating_pow(self, exp: u32) -> Self {
+ // It might be possible to handwrite this to be slightly faster as both
+ // saturating_pow has to do a bounds-check and then we do second one
+ let powed = self.value.saturating_pow(exp);
+ let max = Self::MAX.value();
+ let saturated = if powed > max { max } else { powed };
+ Self {
+ value: saturated,
+ }
+ }
+
+ pub const fn checked_add(self, rhs: Self) -> Option<Self> {
+ if core::mem::size_of::<$type>() << 3 == BITS {
+ // We are something like a UInt::<u8; 8>. We can fallback to the base implementation
+ match self.value.checked_add(rhs.value) {
+ Some(value) => Some(Self { value }),
+ None => None
+ }
+ } else {
+ // We're dealing with fewer bits than the underlying type (e.g. u7).
+ // That means the addition can never overflow the underlying type
+ let sum = self.value.wrapping_add(rhs.value);
+ if sum > Self::MAX.value() { None } else { Some(Self { value: sum })}
+ }
+ }
+
+ pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
+ match self.value.checked_sub(rhs.value) {
+ Some(value) => Some(Self { value }),
+ None => None
+ }
+ }
+
+ pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
+ let product = if BITS << 1 <= (core::mem::size_of::<$type>() << 3) {
+ // We have half the bits (e.g. u4 * u4) of the base type, so we can't overflow the base type
+ // wrapping_mul likely provides the best performance on all cpus
+ Some(self.value.wrapping_mul(rhs.value))
+ } else {
+ // We have more than half the bits (e.g. u6 * u6)
+ self.value.checked_mul(rhs.value)
+ };
+
+ match product {
+ Some(value) => {
+ if value > Self::MAX.value() {
+ None
+ } else {
+ Some(Self {value})
+ }
+ }
+ None => None
+ }
+ }
+
+ pub const fn checked_div(self, rhs: Self) -> Option<Self> {
+ match self.value.checked_div(rhs.value) {
+ Some(value) => Some(Self { value }),
+ None => None
+ }
+ }
+
+ pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
+ if rhs >= (BITS as u32) {
+ None
+ } else {
+ Some(Self {
+ value: (self.value << rhs) & Self::MASK,
+ })
+ }
+ }
+
+ pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
+ if rhs >= (BITS as u32) {
+ None
+ } else {
+ Some(Self {
+ value: (self.value >> rhs),
+ })
+ }
+ }
+
+ pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
+ let (value, overflow) = if core::mem::size_of::<$type>() << 3 == BITS {
+ // We are something like a UInt::<u8; 8>. We can fallback to the base implementation
+ self.value.overflowing_add(rhs.value)
+ } else {
+ // We're dealing with fewer bits than the underlying type (e.g. u7).
+ // That means the addition can never overflow the underlying type
+ let sum = self.value.wrapping_add(rhs.value);
+ let masked = sum & Self::MASK;
+ (masked, masked != sum)
+ };
+ (Self { value }, overflow)
+ }
+
+ pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
+ // For unsigned numbers, the only difference is when we reach 0 - which is the same
+ // no matter the data size. In the case of overflow we do have the mask the result though
+ let (value, overflow) = self.value.overflowing_sub(rhs.value);
+ (Self { value: value & Self::MASK }, overflow)
+ }
+
+ pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
+ let (wrapping_product, overflow) = if BITS << 1 <= (core::mem::size_of::<$type>() << 3) {
+ // We have half the bits (e.g. u4 * u4) of the base type, so we can't overflow the base type
+ // wrapping_mul likely provides the best performance on all cpus
+ self.value.overflowing_mul(rhs.value)
+ } else {
+ // We have more than half the bits (e.g. u6 * u6)
+ self.value.overflowing_mul(rhs.value)
+ };
+
+ let masked = wrapping_product & Self::MASK;
+ let overflow2 = masked != wrapping_product;
+ (Self { value: masked }, overflow || overflow2 )
+ }
+
+ pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
+ let value = self.value.wrapping_div(rhs.value);
+ (Self { value }, false )
+ }
+
+ pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
+ if rhs >= (BITS as u32) {
+ (Self { value: self.value << (rhs % (BITS as u32)) }, true)
+ } else {
+ (Self { value: self.value << rhs }, false)
+ }
+ }
+
+ pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
+ if rhs >= (BITS as u32) {
+ (Self { value: self.value >> (rhs % (BITS as u32)) }, true)
+ } else {
+ (Self { value: self.value >> rhs }, false)
+ }
+ }
+
+ /// Reverses the order of bits in the integer. The least significant bit becomes the most significant bit, second least-significant bit becomes second most-significant bit, etc.
+ pub const fn reverse_bits(self) -> Self {
+ let shift_right = (core::mem::size_of::<$type>() << 3) - BITS;
+ Self { value: self.value.reverse_bits() >> shift_right }
+ }
+
+ /// Returns the number of ones in the binary representation of self.
+ pub const fn count_ones(self) -> u32 {
+ // The upper bits are zero, so we can ignore them
+ self.value.count_ones()
+ }
+
+ /// Returns the number of zeros in the binary representation of self.
+ pub const fn count_zeros(self) -> u32 {
+ // The upper bits are zero, so we can have to subtract them from the result
+ let filler_bits = ((core::mem::size_of::<$type>() << 3) - BITS) as u32;
+ self.value.count_zeros() - filler_bits
+ }
+
+ /// Returns the number of leading ones in the binary representation of self.
+ pub const fn leading_ones(self) -> u32 {
+ let shift = ((core::mem::size_of::<$type>() << 3) - BITS) as u32;
+ (self.value << shift).leading_ones()
+ }
+
+ /// Returns the number of leading zeros in the binary representation of self.
+ pub const fn leading_zeros(self) -> u32 {
+ let shift = ((core::mem::size_of::<$type>() << 3) - BITS) as u32;
+ (self.value << shift).leading_zeros()
+ }
+
+ /// Returns the number of leading ones in the binary representation of self.
+ pub const fn trailing_ones(self) -> u32 {
+ self.value.trailing_ones()
+ }
+
+ /// Returns the number of leading zeros in the binary representation of self.
+ pub const fn trailing_zeros(self) -> u32 {
+ self.value.trailing_zeros()
+ }
+
+ /// Shifts the bits to the left by a specified amount, n, wrapping the truncated bits to the end of the resulting integer.
+ /// Please note this isn't the same operation as the << shifting operator!
+ pub const fn rotate_left(self, n: u32) -> Self {
+ let b = BITS as u32;
+ let n = if n >= b { n % b } else { n };
+
+ let moved_bits = (self.value << n) & Self::MASK;
+ let truncated_bits = self.value >> (b - n);
+ Self { value: moved_bits | truncated_bits }
+ }
+
+ /// Shifts the bits to the right by a specified amount, n, wrapping the truncated bits to the beginning of the resulting integer.
+ /// Please note this isn't the same operation as the >> shifting operator!
+ pub const fn rotate_right(self, n: u32) -> Self {
+ let b = BITS as u32;
+ let n = if n >= b { n % b } else { n };
+
+ let moved_bits = self.value >> n;
+ let truncated_bits = (self.value << (b - n)) & Self::MASK;
+ Self { value: moved_bits | truncated_bits }
+ }
+ }
+ )+
+ };
+}
+
+uint_impl!(u8, u16, u32, u64, u128);
+
+// Arithmetic implementations
+impl<T, const BITS: usize> Add for UInt<T, BITS>
+where
+ Self: Number,
+ T: PartialEq
+ + Copy
+ + BitAnd<T, Output = T>
+ + Not<Output = T>
+ + Add<T, Output = T>
+ + Sub<T, Output = T>
+ + From<u8>,
+{
+ type Output = UInt<T, BITS>;
+
+ fn add(self, rhs: Self) -> Self::Output {
+ let sum = self.value + rhs.value;
+ #[cfg(debug_assertions)]
+ if (sum & !Self::MASK) != T::from(0) {
+ panic!("attempt to add with overflow");
+ }
+ Self {
+ value: sum & Self::MASK,
+ }
+ }
+}
+
+impl<T, const BITS: usize> AddAssign for UInt<T, BITS>
+where
+ Self: Number,
+ T: PartialEq
+ + Eq
+ + Not<Output = T>
+ + Copy
+ + AddAssign<T>
+ + BitAnd<T, Output = T>
+ + BitAndAssign<T>
+ + From<u8>,
+{
+ fn add_assign(&mut self, rhs: Self) {
+ self.value += rhs.value;
+ #[cfg(debug_assertions)]
+ if (self.value & !Self::MASK) != T::from(0) {
+ panic!("attempt to add with overflow");
+ }
+ self.value &= Self::MASK;
+ }
+}
+
+impl<T, const BITS: usize> Sub for UInt<T, BITS>
+where
+ Self: Number,
+ T: Copy + BitAnd<T, Output = T> + Sub<T, Output = T>,
+{
+ type Output = UInt<T, BITS>;
+
+ fn sub(self, rhs: Self) -> Self::Output {
+ // No need for extra overflow checking as the regular minus operator already handles it for us
+ Self {
+ value: (self.value - rhs.value) & Self::MASK,
+ }
+ }
+}
+
+impl<T, const BITS: usize> SubAssign for UInt<T, BITS>
+where
+ Self: Number,
+ T: Copy + SubAssign<T> + BitAnd<T, Output = T> + BitAndAssign<T> + Sub<T, Output = T>,
+{
+ fn sub_assign(&mut self, rhs: Self) {
+ // No need for extra overflow checking as the regular minus operator already handles it for us
+ self.value -= rhs.value;
+ self.value &= Self::MASK;
+ }
+}
+
+impl<T, const BITS: usize> Mul for UInt<T, BITS>
+where
+ Self: Number,
+ T: PartialEq + Copy + BitAnd<T, Output = T> + Not<Output = T> + Mul<T, Output = T> + From<u8>,
+{
+ type Output = UInt<T, BITS>;
+
+ fn mul(self, rhs: Self) -> Self::Output {
+ // In debug builds, this will perform two bounds checks: Initial multiplication, followed by
+ // our bounds check. As wrapping_mul isn't available as a trait bound (in regular Rust), this
+ // is unavoidable
+ let product = self.value * rhs.value;
+ #[cfg(debug_assertions)]
+ if (product & !Self::MASK) != T::from(0) {
+ panic!("attempt to multiply with overflow");
+ }
+ Self {
+ value: product & Self::MASK,
+ }
+ }
+}
+
+impl<T, const BITS: usize> MulAssign for UInt<T, BITS>
+where
+ Self: Number,
+ T: PartialEq
+ + Eq
+ + Not<Output = T>
+ + Copy
+ + MulAssign<T>
+ + BitAnd<T, Output = T>
+ + BitAndAssign<T>
+ + From<u8>,
+{
+ fn mul_assign(&mut self, rhs: Self) {
+ self.value *= rhs.value;
+ #[cfg(debug_assertions)]
+ if (self.value & !Self::MASK) != T::from(0) {
+ panic!("attempt to multiply with overflow");
+ }
+ self.value &= Self::MASK;
+ }
+}
+
+impl<T, const BITS: usize> Div for UInt<T, BITS>
+where
+ Self: Number,
+ T: PartialEq + Div<T, Output = T>,
+{
+ type Output = UInt<T, BITS>;
+
+ fn div(self, rhs: Self) -> Self::Output {
+ // Integer division can only make the value smaller. And as the result is same type as
+ // Self, there's no need to range-check or mask
+ Self {
+ value: self.value / rhs.value,
+ }
+ }
+}
+
+impl<T, const BITS: usize> DivAssign for UInt<T, BITS>
+where
+ Self: Number,
+ T: PartialEq + DivAssign<T>,
+{
+ fn div_assign(&mut self, rhs: Self) {
+ self.value /= rhs.value;
+ }
+}
+
+impl<T, const BITS: usize> BitAnd for UInt<T, BITS>
+where
+ Self: Number,
+ T: Copy
+ + BitAnd<T, Output = T>
+ + Sub<T, Output = T>
+ + Shl<usize, Output = T>
+ + Shr<usize, Output = T>
+ + From<u8>,
+{
+ type Output = UInt<T, BITS>;
+
+ fn bitand(self, rhs: Self) -> Self::Output {
+ Self {
+ value: self.value & rhs.value,
+ }
+ }
+}
+
+impl<T, const BITS: usize> BitAndAssign for UInt<T, BITS>
+where
+ T: Copy + BitAndAssign<T> + Sub<T, Output = T> + Shl<usize, Output = T> + From<u8>,
+{
+ fn bitand_assign(&mut self, rhs: Self) {
+ self.value &= rhs.value;
+ }
+}
+
+impl<T, const BITS: usize> BitOr for UInt<T, BITS>
+where
+ T: Copy + BitOr<T, Output = T> + Sub<T, Output = T> + Shl<usize, Output = T> + From<u8>,
+{
+ type Output = UInt<T, BITS>;
+
+ fn bitor(self, rhs: Self) -> Self::Output {
+ Self {
+ value: self.value | rhs.value,
+ }
+ }
+}
+
+impl<T, const BITS: usize> BitOrAssign for UInt<T, BITS>
+where
+ T: Copy + BitOrAssign<T> + Sub<T, Output = T> + Shl<usize, Output = T> + From<u8>,
+{
+ fn bitor_assign(&mut self, rhs: Self) {
+ self.value |= rhs.value;
+ }
+}
+
+impl<T, const BITS: usize> BitXor for UInt<T, BITS>
+where
+ T: Copy + BitXor<T, Output = T> + Sub<T, Output = T> + Shl<usize, Output = T> + From<u8>,
+{
+ type Output = UInt<T, BITS>;
+
+ fn bitxor(self, rhs: Self) -> Self::Output {
+ Self {
+ value: self.value ^ rhs.value,
+ }
+ }
+}
+
+impl<T, const BITS: usize> BitXorAssign for UInt<T, BITS>
+where
+ T: Copy + BitXorAssign<T> + Sub<T, Output = T> + Shl<usize, Output = T> + From<u8>,
+{
+ fn bitxor_assign(&mut self, rhs: Self) {
+ self.value ^= rhs.value;
+ }
+}
+
+impl<T, const BITS: usize> Not for UInt<T, BITS>
+where
+ Self: Number,
+ T: Copy
+ + BitAnd<T, Output = T>
+ + BitXor<T, Output = T>
+ + Sub<T, Output = T>
+ + Shl<usize, Output = T>
+ + Shr<usize, Output = T>
+ + From<u8>,
+{
+ type Output = UInt<T, BITS>;
+
+ fn not(self) -> Self::Output {
+ Self {
+ value: self.value ^ Self::MASK,
+ }
+ }
+}
+
+impl<T, TSHIFTBITS, const BITS: usize> Shl<TSHIFTBITS> for UInt<T, BITS>
+where
+ Self: Number,
+ T: Copy
+ + BitAnd<T, Output = T>
+ + Shl<TSHIFTBITS, Output = T>
+ + Sub<T, Output = T>
+ + Shl<usize, Output = T>
+ + Shr<usize, Output = T>
+ + From<u8>,
+ TSHIFTBITS: TryInto<usize> + Copy,
+{
+ type Output = UInt<T, BITS>;
+
+ fn shl(self, rhs: TSHIFTBITS) -> Self::Output {
+ // With debug assertions, the << and >> operators throw an exception if the shift amount
+ // is larger than the number of bits (in which case the result would always be 0)
+ #[cfg(debug_assertions)]
+ if rhs.try_into().unwrap_or(usize::MAX) >= BITS {
+ panic!("attempt to shift left with overflow")
+ }
+
+ Self {
+ value: (self.value << rhs) & Self::MASK,
+ }
+ }
+}
+
+impl<T, TSHIFTBITS, const BITS: usize> ShlAssign<TSHIFTBITS> for UInt<T, BITS>
+where
+ Self: Number,
+ T: Copy
+ + BitAnd<T, Output = T>
+ + BitAndAssign<T>
+ + ShlAssign<TSHIFTBITS>
+ + Sub<T, Output = T>
+ + Shr<usize, Output = T>
+ + Shl<usize, Output = T>
+ + From<u8>,
+ TSHIFTBITS: TryInto<usize> + Copy,
+{
+ fn shl_assign(&mut self, rhs: TSHIFTBITS) {
+ // With debug assertions, the << and >> operators throw an exception if the shift amount
+ // is larger than the number of bits (in which case the result would always be 0)
+ #[cfg(debug_assertions)]
+ if rhs.try_into().unwrap_or(usize::MAX) >= BITS {
+ panic!("attempt to shift left with overflow")
+ }
+ self.value <<= rhs;
+ self.value &= Self::MASK;
+ }
+}
+
+impl<T, TSHIFTBITS, const BITS: usize> Shr<TSHIFTBITS> for UInt<T, BITS>
+where
+ T: Copy + Shr<TSHIFTBITS, Output = T> + Sub<T, Output = T> + Shl<usize, Output = T> + From<u8>,
+ TSHIFTBITS: TryInto<usize> + Copy,
+{
+ type Output = UInt<T, BITS>;
+
+ fn shr(self, rhs: TSHIFTBITS) -> Self::Output {
+ // With debug assertions, the << and >> operators throw an exception if the shift amount
+ // is larger than the number of bits (in which case the result would always be 0)
+ #[cfg(debug_assertions)]
+ if rhs.try_into().unwrap_or(usize::MAX) >= BITS {
+ panic!("attempt to shift left with overflow")
+ }
+ Self {
+ value: self.value >> rhs,
+ }
+ }
+}
+
+impl<T, TSHIFTBITS, const BITS: usize> ShrAssign<TSHIFTBITS> for UInt<T, BITS>
+where
+ T: Copy + ShrAssign<TSHIFTBITS> + Sub<T, Output = T> + Shl<usize, Output = T> + From<u8>,
+ TSHIFTBITS: TryInto<usize> + Copy,
+{
+ fn shr_assign(&mut self, rhs: TSHIFTBITS) {
+ // With debug assertions, the << and >> operators throw an exception if the shift amount
+ // is larger than the number of bits (in which case the result would always be 0)
+ #[cfg(debug_assertions)]
+ if rhs.try_into().unwrap_or(usize::MAX) >= BITS {
+ panic!("attempt to shift left with overflow")
+ }
+ self.value >>= rhs;
+ }
+}
+
+impl<T, const BITS: usize> Display for UInt<T, BITS>
+where
+ T: Display,
+{
+ #[inline]
+ fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+ self.value.fmt(f)
+ }
+}
+
+impl<T, const BITS: usize> Debug for UInt<T, BITS>
+where
+ T: Debug,
+{
+ #[inline]
+ fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+ self.value.fmt(f)
+ }
+}
+
+impl<T, const BITS: usize> LowerHex for UInt<T, BITS>
+where
+ T: LowerHex,
+{
+ #[inline]
+ fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+ self.value.fmt(f)
+ }
+}
+
+impl<T, const BITS: usize> UpperHex for UInt<T, BITS>
+where
+ T: UpperHex,
+{
+ #[inline]
+ fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+ self.value.fmt(f)
+ }
+}
+
+impl<T, const BITS: usize> Octal for UInt<T, BITS>
+where
+ T: Octal,
+{
+ #[inline]
+ fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+ self.value.fmt(f)
+ }
+}
+
+impl<T, const BITS: usize> Binary for UInt<T, BITS>
+where
+ T: Binary,
+{
+ #[inline]
+ fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+ self.value.fmt(f)
+ }
+}
+
+#[cfg(feature = "defmt")]
+impl<T, const BITS: usize> defmt::Format for UInt<T, BITS>
+where
+ T: defmt::Format,
+{
+ #[inline]
+ fn format(&self, f: defmt::Formatter) {
+ self.value.format(f)
+ }
+}
+
+#[cfg(feature = "serde")]
+impl<T, const BITS: usize> Serialize for UInt<T, BITS>
+where
+ T: Serialize,
+{
+ fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
+ self.value.serialize(serializer)
+ }
+}
+
+// Serde's invalid_value error (https://rust-lang.github.io/hashbrown/serde/de/trait.Error.html#method.invalid_value)
+// takes an Unexpected (https://rust-lang.github.io/hashbrown/serde/de/enum.Unexpected.html) which only accepts a 64 bit
+// unsigned integer. This is a problem for us because we want to support 128 bit unsigned integers. To work around this
+// we define our own error type using the UInt's underlying type which implements Display and then use
+// serde::de::Error::custom to create an error with our custom type.
+#[cfg(feature = "serde")]
+struct InvalidUIntValueError<T: Display> {
+ value: T,
+ max: T,
+}
+
+#[cfg(feature = "serde")]
+impl<T: Display> Display for InvalidUIntValueError<T> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+ write!(
+ f,
+ "invalid value: integer `{}`, expected a value between `0` and `{}`",
+ self.value, self.max
+ )
+ }
+}
+
+#[cfg(feature = "serde")]
+impl<'de, T: Display, const BITS: usize> Deserialize<'de> for UInt<T, BITS>
+where
+ Self: Number,
+ T: Deserialize<'de> + PartialOrd,
+{
+ fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+ let value = T::deserialize(deserializer)?;
+
+ if value <= Self::MAX.value {
+ Ok(Self { value })
+ } else {
+ Err(serde::de::Error::custom(InvalidUIntValueError {
+ value,
+ max: Self::MAX.value,
+ }))
+ }
+ }
+}
+
+impl<T, const BITS: usize> Hash for UInt<T, BITS>
+where
+ T: Hash,
+{
+ #[inline]
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.value.hash(state)
+ }
+}
+
+#[cfg(feature = "step_trait")]
+impl<T, const BITS: usize> Step for UInt<T, BITS>
+where
+ Self: Number<UnderlyingType = T>,
+ T: Copy + Step,
+{
+ #[inline]
+ fn steps_between(start: &Self, end: &Self) -> Option<usize> {
+ Step::steps_between(&start.value(), &end.value())
+ }
+
+ #[inline]
+ fn forward_checked(start: Self, count: usize) -> Option<Self> {
+ if let Some(res) = Step::forward_checked(start.value(), count) {
+ Self::try_new(res).ok()
+ } else {
+ None
+ }
+ }
+
+ #[inline]
+ fn backward_checked(start: Self, count: usize) -> Option<Self> {
+ if let Some(res) = Step::backward_checked(start.value(), count) {
+ Self::try_new(res).ok()
+ } else {
+ None
+ }
+ }
+}
+
+#[cfg(feature = "num-traits")]
+impl<T, const NUM_BITS: usize> num_traits::WrappingAdd for UInt<T, NUM_BITS>
+where
+ Self: Number,
+ T: PartialEq
+ + Eq
+ + Copy
+ + Add<T, Output = T>
+ + Sub<T, Output = T>
+ + BitAnd<T, Output = T>
+ + Not<Output = T>
+ + Shr<usize, Output = T>
+ + Shl<usize, Output = T>
+ + From<u8>,
+ Wrapping<T>: Add<Wrapping<T>, Output = Wrapping<T>>,
+{
+ #[inline]
+ fn wrapping_add(&self, rhs: &Self) -> Self {
+ let sum = (Wrapping(self.value) + Wrapping(rhs.value)).0;
+ Self {
+ value: sum & Self::MASK,
+ }
+ }
+}
+
+#[cfg(feature = "num-traits")]
+impl<T, const NUM_BITS: usize> num_traits::WrappingSub for UInt<T, NUM_BITS>
+where
+ Self: Number,
+ T: PartialEq
+ + Eq
+ + Copy
+ + Add<T, Output = T>
+ + Sub<T, Output = T>
+ + BitAnd<T, Output = T>
+ + Not<Output = T>
+ + Shr<usize, Output = T>
+ + Shl<usize, Output = T>
+ + From<u8>,
+ Wrapping<T>: Sub<Wrapping<T>, Output = Wrapping<T>>,
+{
+ #[inline]
+ fn wrapping_sub(&self, rhs: &Self) -> Self {
+ let sum = (Wrapping(self.value) - Wrapping(rhs.value)).0;
+ Self {
+ value: sum & Self::MASK,
+ }
+ }
+}
+
+#[cfg(feature = "num-traits")]
+impl<T, const NUM_BITS: usize> num_traits::bounds::Bounded for UInt<T, NUM_BITS>
+where
+ Self: Number,
+{
+ fn min_value() -> Self {
+ Self::MIN
+ }
+
+ fn max_value() -> Self {
+ Self::MAX
+ }
+}
+
+macro_rules! bytes_operation_impl {
+ ($base_data_type:ty, $bits:expr, [$($indices:expr),+]) => {
+ impl UInt<$base_data_type, $bits>
+ {
+ /// Reverses the byte order of the integer.
+ #[inline]
+ pub const fn swap_bytes(&self) -> Self {
+ // swap_bytes() of the underlying type does most of the work. Then, we just need to shift
+ const SHIFT_RIGHT: usize = (core::mem::size_of::<$base_data_type>() << 3) - $bits;
+ Self { value: self.value.swap_bytes() >> SHIFT_RIGHT }
+ }
+
+ pub const fn to_le_bytes(&self) -> [u8; $bits >> 3] {
+ let v = self.value();
+
+ [ $( (v >> ($indices << 3)) as u8, )+ ]
+ }
+
+ pub const fn from_le_bytes(from: [u8; $bits >> 3]) -> Self {
+ let value = { 0 $( | (from[$indices] as $base_data_type) << ($indices << 3))+ };
+ Self { value }
+ }
+
+ pub const fn to_be_bytes(&self) -> [u8; $bits >> 3] {
+ let v = self.value();
+
+ [ $( (v >> ($bits - 8 - ($indices << 3))) as u8, )+ ]
+ }
+
+ pub const fn from_be_bytes(from: [u8; $bits >> 3]) -> Self {
+ let value = { 0 $( | (from[$indices] as $base_data_type) << ($bits - 8 - ($indices << 3)))+ };
+ Self { value }
+ }
+
+ #[inline]
+ pub const fn to_ne_bytes(&self) -> [u8; $bits >> 3] {
+ #[cfg(target_endian = "little")]
+ {
+ self.to_le_bytes()
+ }
+ #[cfg(target_endian = "big")]
+ {
+ self.to_be_bytes()
+ }
+ }
+
+ #[inline]
+ pub const fn from_ne_bytes(bytes: [u8; $bits >> 3]) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ Self::from_le_bytes(bytes)
+ }
+ #[cfg(target_endian = "big")]
+ {
+ Self::from_be_bytes(bytes)
+ }
+ }
+
+ #[inline]
+ pub const fn to_le(self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ self
+ }
+ #[cfg(target_endian = "big")]
+ {
+ self.swap_bytes()
+ }
+ }
+
+ #[inline]
+ pub const fn to_be(self) -> Self {
+ #[cfg(target_endian = "little")]
+ {
+ self.swap_bytes()
+ }
+ #[cfg(target_endian = "big")]
+ {
+ self
+ }
+ }
+
+ #[inline]
+ pub const fn from_le(value: Self) -> Self {
+ value.to_le()
+ }
+
+ #[inline]
+ pub const fn from_be(value: Self) -> Self {
+ value.to_be()
+ }
+ }
+ };
+}
+
+bytes_operation_impl!(u32, 24, [0, 1, 2]);
+bytes_operation_impl!(u64, 24, [0, 1, 2]);
+bytes_operation_impl!(u128, 24, [0, 1, 2]);
+bytes_operation_impl!(u64, 40, [0, 1, 2, 3, 4]);
+bytes_operation_impl!(u128, 40, [0, 1, 2, 3, 4]);
+bytes_operation_impl!(u64, 48, [0, 1, 2, 3, 4, 5]);
+bytes_operation_impl!(u128, 48, [0, 1, 2, 3, 4, 5]);
+bytes_operation_impl!(u64, 56, [0, 1, 2, 3, 4, 5, 6]);
+bytes_operation_impl!(u128, 56, [0, 1, 2, 3, 4, 5, 6]);
+bytes_operation_impl!(u128, 72, [0, 1, 2, 3, 4, 5, 6, 7, 8]);
+bytes_operation_impl!(u128, 80, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+bytes_operation_impl!(u128, 88, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+bytes_operation_impl!(u128, 96, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
+bytes_operation_impl!(u128, 104, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
+bytes_operation_impl!(u128, 112, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
+bytes_operation_impl!(
+ u128,
+ 120,
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
+);
+
+// Conversions
+
+#[cfg(feature = "const_convert_and_const_trait_impl")]
+macro_rules! from_arbitrary_int_impl {
+ ($from:ty, [$($into:ty),+]) => {
+ $(
+ impl<const BITS: usize, const BITS_FROM: usize> const From<UInt<$from, BITS_FROM>>
+ for UInt<$into, BITS>
+ {
+ #[inline]
+ fn from(item: UInt<$from, BITS_FROM>) -> Self {
+ let _ = CompileTimeAssert::<BITS_FROM, BITS>::SMALLER_OR_EQUAL;
+ Self { value: item.value as $into }
+ }
+ }
+ )+
+ };
+}
+
+#[cfg(not(feature = "const_convert_and_const_trait_impl"))]
+macro_rules! from_arbitrary_int_impl {
+ ($from:ty, [$($into:ty),+]) => {
+ $(
+ impl<const BITS: usize, const BITS_FROM: usize> From<UInt<$from, BITS_FROM>>
+ for UInt<$into, BITS>
+ {
+ #[inline]
+ fn from(item: UInt<$from, BITS_FROM>) -> Self {
+ let _ = CompileTimeAssert::<BITS_FROM, BITS>::SMALLER_OR_EQUAL;
+ Self { value: item.value as $into }
+ }
+ }
+ )+
+ };
+}
+
+#[cfg(feature = "const_convert_and_const_trait_impl")]
+macro_rules! from_native_impl {
+ ($from:ty, [$($into:ty),+]) => {
+ $(
+ impl<const BITS: usize> const From<$from> for UInt<$into, BITS> {
+ #[inline]
+ fn from(from: $from) -> Self {
+ let _ = CompileTimeAssert::<{ <$from>::BITS as usize }, BITS>::SMALLER_OR_EQUAL;
+ Self { value: from as $into }
+ }
+ }
+
+ impl<const BITS: usize> const From<UInt<$from, BITS>> for $into {
+ #[inline]
+ fn from(from: UInt<$from, BITS>) -> Self {
+ let _ = CompileTimeAssert::<BITS, { <$into>::BITS as usize }>::SMALLER_OR_EQUAL;
+ from.value as $into
+ }
+ }
+ )+
+ };
+}
+
+#[cfg(not(feature = "const_convert_and_const_trait_impl"))]
+macro_rules! from_native_impl {
+ ($from:ty, [$($into:ty),+]) => {
+ $(
+ impl<const BITS: usize> From<$from> for UInt<$into, BITS> {
+ #[inline]
+ fn from(from: $from) -> Self {
+ let _ = CompileTimeAssert::<{ <$from>::BITS as usize }, BITS>::SMALLER_OR_EQUAL;
+ Self { value: from as $into }
+ }
+ }
+
+ impl<const BITS: usize> From<UInt<$from, BITS>> for $into {
+ #[inline]
+ fn from(from: UInt<$from, BITS>) -> Self {
+ let _ = CompileTimeAssert::<BITS, { <$into>::BITS as usize }>::SMALLER_OR_EQUAL;
+ from.value as $into
+ }
+ }
+ )+
+ };
+}
+
+from_arbitrary_int_impl!(u8, [u16, u32, u64, u128]);
+from_arbitrary_int_impl!(u16, [u8, u32, u64, u128]);
+from_arbitrary_int_impl!(u32, [u8, u16, u64, u128]);
+from_arbitrary_int_impl!(u64, [u8, u16, u32, u128]);
+from_arbitrary_int_impl!(u128, [u8, u32, u64, u16]);
+
+from_native_impl!(u8, [u8, u16, u32, u64, u128]);
+from_native_impl!(u16, [u8, u16, u32, u64, u128]);
+from_native_impl!(u32, [u8, u16, u32, u64, u128]);
+from_native_impl!(u64, [u8, u16, u32, u64, u128]);
+from_native_impl!(u128, [u8, u16, u32, u64, u128]);
+
+// Define type aliases like u1, u63 and u80 using the smallest possible underlying data type.
+// These are for convenience only - UInt<u32, 15> is still legal
+macro_rules! type_alias {
+ ($storage:ty, $(($name:ident, $bits:expr)),+) => {
+ $( pub type $name = crate::UInt<$storage, $bits>; )+
+ }
+}
+
+pub use aliases::*;
+
+#[allow(non_camel_case_types)]
+#[rustfmt::skip]
+mod aliases {
+ type_alias!(u8, (u1, 1), (u2, 2), (u3, 3), (u4, 4), (u5, 5), (u6, 6), (u7, 7));
+ type_alias!(u16, (u9, 9), (u10, 10), (u11, 11), (u12, 12), (u13, 13), (u14, 14), (u15, 15));
+ type_alias!(u32, (u17, 17), (u18, 18), (u19, 19), (u20, 20), (u21, 21), (u22, 22), (u23, 23), (u24, 24), (u25, 25), (u26, 26), (u27, 27), (u28, 28), (u29, 29), (u30, 30), (u31, 31));
+ type_alias!(u64, (u33, 33), (u34, 34), (u35, 35), (u36, 36), (u37, 37), (u38, 38), (u39, 39), (u40, 40), (u41, 41), (u42, 42), (u43, 43), (u44, 44), (u45, 45), (u46, 46), (u47, 47), (u48, 48), (u49, 49), (u50, 50), (u51, 51), (u52, 52), (u53, 53), (u54, 54), (u55, 55), (u56, 56), (u57, 57), (u58, 58), (u59, 59), (u60, 60), (u61, 61), (u62, 62), (u63, 63));
+ type_alias!(u128, (u65, 65), (u66, 66), (u67, 67), (u68, 68), (u69, 69), (u70, 70), (u71, 71), (u72, 72), (u73, 73), (u74, 74), (u75, 75), (u76, 76), (u77, 77), (u78, 78), (u79, 79), (u80, 80), (u81, 81), (u82, 82), (u83, 83), (u84, 84), (u85, 85), (u86, 86), (u87, 87), (u88, 88), (u89, 89), (u90, 90), (u91, 91), (u92, 92), (u93, 93), (u94, 94), (u95, 95), (u96, 96), (u97, 97), (u98, 98), (u99, 99), (u100, 100), (u101, 101), (u102, 102), (u103, 103), (u104, 104), (u105, 105), (u106, 106), (u107, 107), (u108, 108), (u109, 109), (u110, 110), (u111, 111), (u112, 112), (u113, 113), (u114, 114), (u115, 115), (u116, 116), (u117, 117), (u118, 118), (u119, 119), (u120, 120), (u121, 121), (u122, 122), (u123, 123), (u124, 124), (u125, 125), (u126, 126), (u127, 127));
+}
+
+// We need to wrap this in a macro, currently: https://github.com/rust-lang/rust/issues/67792#issuecomment-1130369066
+
+#[cfg(feature = "const_convert_and_const_trait_impl")]
+macro_rules! boolu1 {
+ () => {
+ impl const From<bool> for u1 {
+ #[inline]
+ fn from(value: bool) -> Self {
+ u1::new(value as u8)
+ }
+ }
+ impl const From<u1> for bool {
+ #[inline]
+ fn from(value: u1) -> Self {
+ match value.value() {
+ 0 => false,
+ 1 => true,
+ _ => panic!("arbitrary_int_type already validates that this is unreachable"), //TODO: unreachable!() is not const yet
+ }
+ }
+ }
+ };
+}
+
+#[cfg(not(feature = "const_convert_and_const_trait_impl"))]
+macro_rules! boolu1 {
+ () => {
+ impl From<bool> for u1 {
+ #[inline]
+ fn from(value: bool) -> Self {
+ u1::new(value as u8)
+ }
+ }
+ impl From<u1> for bool {
+ #[inline]
+ fn from(value: u1) -> Self {
+ match value.value() {
+ 0 => false,
+ 1 => true,
+ _ => panic!("arbitrary_int_type already validates that this is unreachable"), //TODO: unreachable!() is not const yet
+ }
+ }
+ }
+ };
+}
+
+boolu1!();
diff --git a/rust/hw/char/pl011/vendor/arbitrary-int/tests/tests.rs b/rust/hw/char/pl011/vendor/arbitrary-int/tests/tests.rs
new file mode 100644
index 0000000000..e050f00c99
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/arbitrary-int/tests/tests.rs
@@ -0,0 +1,1913 @@
+#![cfg_attr(feature = "step_trait", feature(step_trait))]
+
+extern crate core;
+
+use arbitrary_int::*;
+use std::collections::HashMap;
+#[cfg(feature = "step_trait")]
+use std::iter::Step;
+
+#[test]
+fn constants() {
+ // Make a constant to ensure new().value() works in a const-context
+ const TEST_CONSTANT: u8 = u7::new(127).value();
+ assert_eq!(TEST_CONSTANT, 127u8);
+
+ // Same with widen()
+ const TEST_CONSTANT2: u7 = u6::new(63).widen();
+ assert_eq!(TEST_CONSTANT2, u7::new(63));
+
+ // Same with widen()
+ const TEST_CONSTANT3A: Result<u6, TryNewError> = u6::try_new(62);
+ assert_eq!(TEST_CONSTANT3A, Ok(u6::new(62)));
+ const TEST_CONSTANT3B: Result<u6, TryNewError> = u6::try_new(64);
+ assert!(TEST_CONSTANT3B.is_err());
+}
+
+#[test]
+fn create_simple() {
+ let value7 = u7::new(123);
+ let value8 = UInt::<u8, 8>::new(189);
+
+ let value13 = u13::new(123);
+ let value16 = UInt::<u16, 16>::new(60000);
+
+ let value23 = u23::new(123);
+ let value67 = u67::new(123);
+
+ assert_eq!(value7.value(), 123);
+ assert_eq!(value8.value(), 189);
+
+ assert_eq!(value13.value(), 123);
+ assert_eq!(value16.value(), 60000);
+
+ assert_eq!(value23.value(), 123);
+ assert_eq!(value67.value(), 123);
+}
+
+#[test]
+fn create_try_new() {
+ assert_eq!(u7::new(123).value(), 123);
+ assert_eq!(u7::try_new(190).expect_err("No error seen"), TryNewError {});
+}
+
+#[test]
+#[should_panic]
+fn create_panic_u7() {
+ u7::new(128);
+}
+
+#[test]
+#[should_panic]
+fn create_panic_u15() {
+ u15::new(32768);
+}
+
+#[test]
+#[should_panic]
+fn create_panic_u31() {
+ u31::new(2147483648);
+}
+
+#[test]
+#[should_panic]
+fn create_panic_u63() {
+ u63::new(0x8000_0000_0000_0000);
+}
+
+#[test]
+#[should_panic]
+fn create_panic_u127() {
+ u127::new(0x8000_0000_0000_0000_0000_0000_0000_0000);
+}
+
+#[test]
+fn add() {
+ assert_eq!(u7::new(10) + u7::new(20), u7::new(30));
+ assert_eq!(u7::new(100) + u7::new(27), u7::new(127));
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn add_overflow() {
+ let _ = u7::new(127) + u7::new(3);
+}
+
+#[cfg(not(debug_assertions))]
+#[test]
+fn add_no_overflow() {
+ let _ = u7::new(127) + u7::new(3);
+}
+
+#[cfg(feature = "num-traits")]
+#[test]
+fn num_traits_add_wrapping() {
+ let v1 = u7::new(120);
+ let v2 = u7::new(10);
+ let v3 = num_traits::WrappingAdd::wrapping_add(&v1, &v2);
+ assert_eq!(v3, u7::new(2));
+}
+
+#[cfg(feature = "num-traits")]
+#[test]
+fn num_traits_sub_wrapping() {
+ let v1 = u7::new(15);
+ let v2 = u7::new(20);
+ let v3 = num_traits::WrappingSub::wrapping_sub(&v1, &v2);
+ assert_eq!(v3, u7::new(123));
+}
+
+#[cfg(feature = "num-traits")]
+#[test]
+fn num_traits_bounded() {
+ use num_traits::bounds::Bounded;
+ assert_eq!(u7::MAX, u7::max_value());
+ assert_eq!(u119::MAX, u119::max_value());
+ assert_eq!(u7::new(0), u7::min_value());
+ assert_eq!(u119::new(0), u119::min_value());
+}
+
+#[test]
+fn addassign() {
+ let mut value = u9::new(500);
+ value += u9::new(11);
+ assert_eq!(value, u9::new(511));
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn addassign_overflow() {
+ let mut value = u9::new(500);
+ value += u9::new(40);
+}
+
+#[cfg(not(debug_assertions))]
+#[test]
+fn addassign_no_overflow() {
+ let mut value = u9::new(500);
+ value += u9::new(28);
+ assert_eq!(value, u9::new(16));
+}
+
+#[test]
+fn sub() {
+ assert_eq!(u7::new(22) - u7::new(10), u7::new(12));
+ assert_eq!(u7::new(127) - u7::new(127), u7::new(0));
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn sub_overflow() {
+ let _ = u7::new(100) - u7::new(127);
+}
+
+#[cfg(not(debug_assertions))]
+#[test]
+fn sub_no_overflow() {
+ let value = u7::new(100) - u7::new(127);
+ assert_eq!(value, u7::new(101));
+}
+
+#[test]
+fn subassign() {
+ let mut value = u9::new(500);
+ value -= u9::new(11);
+ assert_eq!(value, u9::new(489));
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn subassign_overflow() {
+ let mut value = u9::new(30);
+ value -= u9::new(40);
+}
+
+#[cfg(not(debug_assertions))]
+#[test]
+fn subassign_no_overflow() {
+ let mut value = u9::new(30);
+ value -= u9::new(40);
+ assert_eq!(value, u9::new(502));
+}
+
+#[test]
+fn mul() {
+ assert_eq!(u7::new(22) * u7::new(4), u7::new(88));
+ assert_eq!(u7::new(127) * u7::new(0), u7::new(0));
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn mul_overflow() {
+ let _ = u7::new(100) * u7::new(2);
+}
+
+#[cfg(not(debug_assertions))]
+#[test]
+fn mul_no_overflow() {
+ let result = u7::new(100) * u7::new(2);
+ assert_eq!(result, u7::new(72));
+}
+
+#[test]
+fn mulassign() {
+ let mut value = u9::new(240);
+ value *= u9::new(2);
+ assert_eq!(value, u9::new(480));
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn mulassign_overflow() {
+ let mut value = u9::new(500);
+ value *= u9::new(2);
+}
+
+#[cfg(not(debug_assertions))]
+#[test]
+fn mulassign_no_overflow() {
+ let mut value = u9::new(500);
+ value *= u9::new(40);
+ assert_eq!(value, u9::new(32));
+}
+
+#[test]
+fn div() {
+ // div just forwards to the underlying type, so there isn't much to do
+ assert_eq!(u7::new(22) / u7::new(4), u7::new(5));
+ assert_eq!(u7::new(127) / u7::new(1), u7::new(127));
+ assert_eq!(u7::new(127) / u7::new(127), u7::new(1));
+}
+
+#[should_panic]
+#[test]
+fn div_by_zero() {
+ let _ = u7::new(22) / u7::new(0);
+}
+
+#[test]
+fn divassign() {
+ let mut value = u9::new(240);
+ value /= u9::new(2);
+ assert_eq!(value, u9::new(120));
+}
+
+#[should_panic]
+#[test]
+fn divassign_by_zero() {
+ let mut value = u9::new(240);
+ value /= u9::new(0);
+}
+
+#[test]
+fn bitand() {
+ assert_eq!(
+ u17::new(0b11001100) & u17::new(0b01101001),
+ u17::new(0b01001000)
+ );
+ assert_eq!(u17::new(0b11001100) & u17::new(0), u17::new(0));
+ assert_eq!(
+ u17::new(0b11001100) & u17::new(0x1_FFFF),
+ u17::new(0b11001100)
+ );
+}
+
+#[test]
+fn bitandassign() {
+ let mut value = u4::new(0b0101);
+ value &= u4::new(0b0110);
+ assert_eq!(value, u4::new(0b0100));
+}
+
+#[test]
+fn bitor() {
+ assert_eq!(
+ u17::new(0b11001100) | u17::new(0b01101001),
+ u17::new(0b11101101)
+ );
+ assert_eq!(u17::new(0b11001100) | u17::new(0), u17::new(0b11001100));
+ assert_eq!(
+ u17::new(0b11001100) | u17::new(0x1_FFFF),
+ u17::new(0x1_FFFF)
+ );
+}
+
+#[test]
+fn bitorassign() {
+ let mut value = u4::new(0b0101);
+ value |= u4::new(0b0110);
+ assert_eq!(value, u4::new(0b0111));
+}
+
+#[test]
+fn bitxor() {
+ assert_eq!(
+ u17::new(0b11001100) ^ u17::new(0b01101001),
+ u17::new(0b10100101)
+ );
+ assert_eq!(u17::new(0b11001100) ^ u17::new(0), u17::new(0b11001100));
+ assert_eq!(
+ u17::new(0b11001100) ^ u17::new(0x1_FFFF),
+ u17::new(0b1_11111111_00110011)
+ );
+}
+
+#[test]
+fn bitxorassign() {
+ let mut value = u4::new(0b0101);
+ value ^= u4::new(0b0110);
+ assert_eq!(value, u4::new(0b0011));
+}
+
+#[test]
+fn not() {
+ assert_eq!(!u17::new(0), u17::new(0b1_11111111_11111111));
+ assert_eq!(!u5::new(0b10101), u5::new(0b01010));
+}
+
+#[test]
+fn shl() {
+ assert_eq!(u17::new(0b1) << 5u8, u17::new(0b100000));
+ // Ensure bits on the left are shifted out
+ assert_eq!(u9::new(0b11110000) << 3u64, u9::new(0b1_10000000));
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn shl_too_much8() {
+ let _ = u53::new(123) << 53u8;
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn shl_too_much16() {
+ let _ = u53::new(123) << 53u16;
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn shl_too_much32() {
+ let _ = u53::new(123) << 53u32;
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn shl_too_much64() {
+ let _ = u53::new(123) << 53u64;
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn shl_too_much128() {
+ let _ = u53::new(123) << 53u128;
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn shl_too_much_usize() {
+ let _ = u53::new(123) << 53usize;
+}
+
+#[test]
+fn shlassign() {
+ let mut value = u9::new(0b11110000);
+ value <<= 3;
+ assert_eq!(value, u9::new(0b1_10000000));
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn shlassign_too_much() {
+ let mut value = u9::new(0b11110000);
+ value <<= 9;
+}
+
+#[cfg(debug_assertions)]
+#[test]
+#[should_panic]
+fn shlassign_too_much2() {
+ let mut value = u9::new(0b11110000);
+ value <<= 10;
+}
+
+#[test]
+fn shr() {
+ assert_eq!(u17::new(0b100110) >> 5usize, u17::new(1));
+
+ // Ensure there's no sign extension
+ assert_eq!(u17::new(0b1_11111111_11111111) >> 8, u17::new(0b1_11111111));
+}
+
+#[test]
+fn shrassign() {
+ let mut value = u9::new(0b1_11110000);
+ value >>= 6;
+ assert_eq!(value, u9::new(0b0_00000111));
+}
+
+#[test]
+fn compare() {
+ assert_eq!(true, u4::new(0b1100) > u4::new(0b0011));
+ assert_eq!(true, u4::new(0b1100) >= u4::new(0b0011));
+ assert_eq!(false, u4::new(0b1100) < u4::new(0b0011));
+ assert_eq!(false, u4::new(0b1100) <= u4::new(0b0011));
+ assert_eq!(true, u4::new(0b1100) != u4::new(0b0011));
+ assert_eq!(false, u4::new(0b1100) == u4::new(0b0011));
+
+ assert_eq!(false, u4::new(0b1100) > u4::new(0b1100));
+ assert_eq!(true, u4::new(0b1100) >= u4::new(0b1100));
+ assert_eq!(false, u4::new(0b1100) < u4::new(0b1100));
+ assert_eq!(true, u4::new(0b1100) <= u4::new(0b1100));
+ assert_eq!(false, u4::new(0b1100) != u4::new(0b1100));
+ assert_eq!(true, u4::new(0b1100) == u4::new(0b1100));
+
+ assert_eq!(false, u4::new(0b0011) > u4::new(0b1100));
+ assert_eq!(false, u4::new(0b0011) >= u4::new(0b1100));
+ assert_eq!(true, u4::new(0b0011) < u4::new(0b1100));
+ assert_eq!(true, u4::new(0b0011) <= u4::new(0b1100));
+ assert_eq!(true, u4::new(0b0011) != u4::new(0b1100));
+ assert_eq!(false, u4::new(0b0011) == u4::new(0b1100));
+}
+
+#[test]
+fn min_max() {
+ assert_eq!(0, u4::MIN.value());
+ assert_eq!(0b1111, u4::MAX.value());
+ assert_eq!(u4::new(0b1111), u4::MAX);
+
+ assert_eq!(0, u15::MIN.value());
+ assert_eq!(32767, u15::MAX.value());
+ assert_eq!(u15::new(32767), u15::MAX);
+
+ assert_eq!(0, u31::MIN.value());
+ assert_eq!(2147483647, u31::MAX.value());
+
+ assert_eq!(0, u63::MIN.value());
+ assert_eq!(0x7FFF_FFFF_FFFF_FFFF, u63::MAX.value());
+
+ assert_eq!(0, u127::MIN.value());
+ assert_eq!(0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, u127::MAX.value());
+}
+
+#[test]
+fn bits() {
+ assert_eq!(4, u4::BITS);
+ assert_eq!(12, u12::BITS);
+ assert_eq!(120, u120::BITS);
+ assert_eq!(13, UInt::<u128, 13usize>::BITS);
+
+ assert_eq!(8, u8::BITS);
+ assert_eq!(16, u16::BITS);
+}
+
+#[test]
+fn mask() {
+ assert_eq!(0x1u8, u1::MASK);
+ assert_eq!(0xFu8, u4::MASK);
+ assert_eq!(0x3FFFFu32, u18::MASK);
+ assert_eq!(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFFu128, u127::MASK);
+ assert_eq!(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFFu128, u127::MASK);
+ assert_eq!(0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFFu128, u128::MAX);
+}
+
+#[test]
+fn min_max_fullwidth() {
+ assert_eq!(u8::MIN, UInt::<u8, 8>::MIN.value());
+ assert_eq!(u8::MAX, UInt::<u8, 8>::MAX.value());
+
+ assert_eq!(u16::MIN, UInt::<u16, 16>::MIN.value());
+ assert_eq!(u16::MAX, UInt::<u16, 16>::MAX.value());
+
+ assert_eq!(u32::MIN, UInt::<u32, 32>::MIN.value());
+ assert_eq!(u32::MAX, UInt::<u32, 32>::MAX.value());
+
+ assert_eq!(u64::MIN, UInt::<u64, 64>::MIN.value());
+ assert_eq!(u64::MAX, UInt::<u64, 64>::MAX.value());
+
+ assert_eq!(u128::MIN, UInt::<u128, 128>::MIN.value());
+ assert_eq!(u128::MAX, UInt::<u128, 128>::MAX.value());
+}
+
+#[allow(deprecated)]
+#[test]
+fn extract() {
+ assert_eq!(u5::new(0b10000), u5::extract(0b11110000, 0));
+ assert_eq!(u5::new(0b11100), u5::extract(0b11110000, 2));
+ assert_eq!(u5::new(0b11110), u5::extract(0b11110000, 3));
+
+ // Use extract with a custom type (5 bits of u32)
+ assert_eq!(
+ UInt::<u32, 5>::new(0b11110),
+ UInt::<u32, 5>::extract(0b11110000, 3)
+ );
+ assert_eq!(
+ u5::new(0b11110),
+ UInt::<u32, 5>::extract(0b11110000, 3).into()
+ );
+}
+
+#[test]
+fn extract_typed() {
+ assert_eq!(u5::new(0b10000), u5::extract_u8(0b11110000, 0));
+ assert_eq!(u5::new(0b00011), u5::extract_u16(0b11110000_11110110, 6));
+ assert_eq!(
+ u5::new(0b01011),
+ u5::extract_u32(0b11110010_11110110_00000000_00000000, 22)
+ );
+ assert_eq!(
+ u5::new(0b01011),
+ u5::extract_u64(
+ 0b11110010_11110110_00000000_00000000_00000000_00000000_00000000_00000000,
+ 54
+ )
+ );
+ assert_eq!(u5::new(0b01011), u5::extract_u128(0b11110010_11110110_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000, 118));
+}
+
+#[test]
+fn extract_full_width_typed() {
+ assert_eq!(
+ 0b1010_0011,
+ UInt::<u8, 8>::extract_u8(0b1010_0011, 0).value()
+ );
+ assert_eq!(
+ 0b1010_0011,
+ UInt::<u8, 8>::extract_u16(0b1111_1111_1010_0011, 0).value()
+ );
+}
+
+#[test]
+#[should_panic]
+fn extract_not_enough_bits_8() {
+ let _ = u5::extract_u8(0b11110000, 4);
+}
+
+#[test]
+#[should_panic]
+fn extract_not_enough_bits_8_full_width() {
+ let _ = UInt::<u8, 8>::extract_u8(0b11110000, 1);
+}
+
+#[test]
+#[should_panic]
+fn extract_not_enough_bits_16() {
+ let _ = u5::extract_u16(0b11110000, 12);
+}
+
+#[test]
+#[should_panic]
+fn extract_not_enough_bits_32() {
+ let _ = u5::extract_u32(0b11110000, 28);
+}
+
+#[test]
+#[should_panic]
+fn extract_not_enough_bits_64() {
+ let _ = u5::extract_u64(0b11110000, 60);
+}
+
+#[test]
+#[should_panic]
+fn extract_not_enough_bits_128() {
+ let _ = u5::extract_u128(0b11110000, 124);
+}
+
+#[test]
+fn from_same_bit_widths() {
+ assert_eq!(u5::from(UInt::<u8, 5>::new(0b10101)), u5::new(0b10101));
+ assert_eq!(u5::from(UInt::<u16, 5>::new(0b10101)), u5::new(0b10101));
+ assert_eq!(u5::from(UInt::<u32, 5>::new(0b10101)), u5::new(0b10101));
+ assert_eq!(u5::from(UInt::<u64, 5>::new(0b10101)), u5::new(0b10101));
+ assert_eq!(u5::from(UInt::<u128, 5>::new(0b10101)), u5::new(0b10101));
+
+ assert_eq!(
+ UInt::<u8, 8>::from(UInt::<u128, 8>::new(0b1110_0101)),
+ UInt::<u8, 8>::new(0b1110_0101)
+ );
+
+ assert_eq!(
+ UInt::<u16, 6>::from(UInt::<u8, 5>::new(0b10101)),
+ UInt::<u16, 6>::new(0b10101)
+ );
+ assert_eq!(u15::from(UInt::<u16, 15>::new(0b10101)), u15::new(0b10101));
+ assert_eq!(u15::from(UInt::<u32, 15>::new(0b10101)), u15::new(0b10101));
+ assert_eq!(u15::from(UInt::<u64, 15>::new(0b10101)), u15::new(0b10101));
+ assert_eq!(u15::from(UInt::<u128, 15>::new(0b10101)), u15::new(0b10101));
+
+ assert_eq!(
+ UInt::<u32, 6>::from(u6::new(0b10101)),
+ UInt::<u32, 6>::new(0b10101)
+ );
+ assert_eq!(
+ UInt::<u32, 14>::from(u14::new(0b10101)),
+ UInt::<u32, 14>::new(0b10101)
+ );
+ assert_eq!(u30::from(UInt::<u32, 30>::new(0b10101)), u30::new(0b10101));
+ assert_eq!(u30::from(UInt::<u64, 30>::new(0b10101)), u30::new(0b10101));
+ assert_eq!(u30::from(UInt::<u128, 30>::new(0b10101)), u30::new(0b10101));
+
+ assert_eq!(
+ UInt::<u64, 7>::from(UInt::<u8, 7>::new(0b10101)),
+ UInt::<u64, 7>::new(0b10101)
+ );
+ assert_eq!(
+ UInt::<u64, 12>::from(UInt::<u16, 12>::new(0b10101)),
+ UInt::<u64, 12>::new(0b10101)
+ );
+ assert_eq!(
+ UInt::<u64, 28>::from(UInt::<u32, 28>::new(0b10101)),
+ UInt::<u64, 28>::new(0b10101)
+ );
+ assert_eq!(u60::from(u60::new(0b10101)), u60::new(0b10101));
+ assert_eq!(u60::from(UInt::<u128, 60>::new(0b10101)), u60::new(0b10101));
+
+ assert_eq!(
+ UInt::<u128, 5>::from(UInt::<u8, 5>::new(0b10101)),
+ UInt::<u128, 5>::new(0b10101)
+ );
+ assert_eq!(
+ UInt::<u128, 12>::from(UInt::<u16, 12>::new(0b10101)),
+ UInt::<u128, 12>::new(0b10101)
+ );
+ assert_eq!(
+ UInt::<u128, 26>::from(UInt::<u32, 26>::new(0b10101)),
+ UInt::<u128, 26>::new(0b10101)
+ );
+ assert_eq!(
+ UInt::<u128, 60>::from(UInt::<u64, 60>::new(0b10101)),
+ UInt::<u128, 60>::new(0b10101)
+ );
+ assert_eq!(
+ u120::from(UInt::<u128, 120>::new(0b10101)),
+ u120::new(0b10101)
+ );
+}
+
+#[cfg(feature = "num-traits")]
+#[test]
+fn calculation_with_number_trait() {
+ fn increment_by_1<T: num_traits::WrappingAdd + Number>(foo: T) -> T {
+ foo.wrapping_add(&T::new(1.into()))
+ }
+
+ fn increment_by_512<T: num_traits::WrappingAdd + Number>(
+ foo: T,
+ ) -> Result<T, <<T as Number>::UnderlyingType as TryFrom<u32>>::Error>
+ where
+ <<T as Number>::UnderlyingType as TryFrom<u32>>::Error: core::fmt::Debug,
+ {
+ Ok(foo.wrapping_add(&T::new(512u32.try_into()?)))
+ }
+
+ assert_eq!(increment_by_1(0u16), 1u16);
+ assert_eq!(increment_by_1(u7::new(3)), u7::new(4));
+ assert_eq!(increment_by_1(u15::new(3)), u15::new(4));
+
+ assert_eq!(increment_by_512(0u16), Ok(512u16));
+ assert!(increment_by_512(u7::new(3)).is_err());
+ assert_eq!(increment_by_512(u15::new(3)), Ok(u15::new(515)));
+}
+
+#[test]
+fn from_smaller_bit_widths() {
+ // The code to get more bits from fewer bits (through From) is the same as the code above
+ // for identical bitwidths. Therefore just do a few point checks to ensure things compile
+
+ // There are compile-breakers for the opposite direction (e.g. tryint to do u5 = From(u17),
+ // but we can't test compile failures here
+
+ // from is not yet supported if the bitcounts are different but the base data types are the same (need
+ // fancier Rust features to support that)
+ assert_eq!(u6::from(UInt::<u16, 5>::new(0b10101)), u6::new(0b10101));
+ assert_eq!(u6::from(UInt::<u32, 5>::new(0b10101)), u6::new(0b10101));
+ assert_eq!(u6::from(UInt::<u64, 5>::new(0b10101)), u6::new(0b10101));
+ assert_eq!(u6::from(UInt::<u128, 5>::new(0b10101)), u6::new(0b10101));
+
+ assert_eq!(u15::from(UInt::<u8, 7>::new(0b10101)), u15::new(0b10101));
+ //assert_eq!(u15::from(UInt::<u16, 15>::new(0b10101)), u15::new(0b10101));
+ assert_eq!(u15::from(UInt::<u32, 14>::new(0b10101)), u15::new(0b10101));
+ assert_eq!(u15::from(UInt::<u64, 14>::new(0b10101)), u15::new(0b10101));
+ assert_eq!(u15::from(UInt::<u128, 14>::new(0b10101)), u15::new(0b10101));
+}
+
+#[allow(non_camel_case_types)]
+#[test]
+fn from_native_ints_same_bits() {
+ use std::primitive;
+
+ type u8 = UInt<primitive::u8, 8>;
+ type u16 = UInt<primitive::u16, 16>;
+ type u32 = UInt<primitive::u32, 32>;
+ type u64 = UInt<primitive::u64, 64>;
+ type u128 = UInt<primitive::u128, 128>;
+
+ assert_eq!(u8::from(0x80_u8), u8::new(0x80));
+ assert_eq!(u16::from(0x8000_u16), u16::new(0x8000));
+ assert_eq!(u32::from(0x8000_0000_u32), u32::new(0x8000_0000));
+ assert_eq!(
+ u64::from(0x8000_0000_0000_0000_u64),
+ u64::new(0x8000_0000_0000_0000)
+ );
+ assert_eq!(
+ u128::from(0x8000_0000_0000_0000_0000_0000_0000_0000_u128),
+ u128::new(0x8000_0000_0000_0000_0000_0000_0000_0000)
+ );
+}
+
+#[test]
+fn from_native_ints_fewer_bits() {
+ assert_eq!(u9::from(0x80_u8), u9::new(0x80));
+
+ assert_eq!(u17::from(0x80_u8), u17::new(0x80));
+ assert_eq!(u17::from(0x8000_u16), u17::new(0x8000));
+
+ assert_eq!(u33::from(0x80_u8), u33::new(0x80));
+ assert_eq!(u33::from(0x8000_u16), u33::new(0x8000));
+ assert_eq!(u33::from(0x8000_0000_u32), u33::new(0x8000_0000));
+
+ assert_eq!(u65::from(0x80_u8), u65::new(0x80));
+ assert_eq!(u65::from(0x8000_u16), u65::new(0x8000));
+ assert_eq!(u65::from(0x8000_0000_u32), u65::new(0x8000_0000));
+ assert_eq!(
+ u65::from(0x8000_0000_0000_0000_u64),
+ u65::new(0x8000_0000_0000_0000)
+ );
+}
+
+#[allow(non_camel_case_types)]
+#[test]
+fn into_native_ints_same_bits() {
+ assert_eq!(u8::from(UInt::<u8, 8>::new(0x80)), 0x80);
+ assert_eq!(u16::from(UInt::<u16, 16>::new(0x8000)), 0x8000);
+ assert_eq!(u32::from(UInt::<u32, 32>::new(0x8000_0000)), 0x8000_0000);
+ assert_eq!(
+ u64::from(UInt::<u64, 64>::new(0x8000_0000_0000_0000)),
+ 0x8000_0000_0000_0000
+ );
+ assert_eq!(
+ u128::from(UInt::<u128, 128>::new(
+ 0x8000_0000_0000_0000_0000_0000_0000_0000
+ )),
+ 0x8000_0000_0000_0000_0000_0000_0000_0000
+ );
+}
+
+#[test]
+fn into_native_ints_fewer_bits() {
+ assert_eq!(u8::from(u7::new(0x40)), 0x40);
+ assert_eq!(u16::from(u15::new(0x4000)), 0x4000);
+ assert_eq!(u32::from(u31::new(0x4000_0000)), 0x4000_0000);
+ assert_eq!(
+ u64::from(u63::new(0x4000_0000_0000_0000)),
+ 0x4000_0000_0000_0000
+ );
+ assert_eq!(
+ u128::from(u127::new(0x4000_0000_0000_0000_0000_0000_0000_0000)),
+ 0x4000_0000_0000_0000_0000_0000_0000_0000
+ );
+}
+
+#[test]
+fn from_into_bool() {
+ assert_eq!(u1::from(true), u1::new(1));
+ assert_eq!(u1::from(false), u1::new(0));
+ assert_eq!(bool::from(u1::new(1)), true);
+ assert_eq!(bool::from(u1::new(0)), false);
+}
+
+#[test]
+fn widen() {
+ // As From() can't be used while keeping the base-data-type, there's widen
+
+ assert_eq!(u5::new(0b11011).widen::<6>(), u6::new(0b11011));
+ assert_eq!(u5::new(0b11011).widen::<8>(), UInt::<u8, 8>::new(0b11011));
+ assert_eq!(u10::new(0b11011).widen::<11>(), u11::new(0b11011));
+ assert_eq!(u20::new(0b11011).widen::<24>(), u24::new(0b11011));
+ assert_eq!(u60::new(0b11011).widen::<61>(), u61::new(0b11011));
+ assert_eq!(u80::new(0b11011).widen::<127>().value(), 0b11011);
+}
+
+#[test]
+fn to_string() {
+ assert_eq!("Value: 5", format!("Value: {}", 5u32.to_string()));
+ assert_eq!("Value: 5", format!("Value: {}", u5::new(5).to_string()));
+ assert_eq!("Value: 5", format!("Value: {}", u11::new(5).to_string()));
+ assert_eq!("Value: 5", format!("Value: {}", u17::new(5).to_string()));
+ assert_eq!("Value: 5", format!("Value: {}", u38::new(5).to_string()));
+ assert_eq!("Value: 60", format!("Value: {}", u65::new(60).to_string()));
+}
+
+#[test]
+fn display() {
+ assert_eq!("Value: 5", format!("Value: {}", 5u32));
+ assert_eq!("Value: 5", format!("Value: {}", u5::new(5)));
+ assert_eq!("Value: 5", format!("Value: {}", u11::new(5)));
+ assert_eq!("Value: 5", format!("Value: {}", u17::new(5)));
+ assert_eq!("Value: 5", format!("Value: {}", u38::new(5)));
+ assert_eq!("Value: 60", format!("Value: {}", u65::new(60)));
+}
+
+#[test]
+fn debug() {
+ assert_eq!("Value: 5", format!("Value: {:?}", 5u32));
+ assert_eq!("Value: 5", format!("Value: {:?}", u5::new(5)));
+ assert_eq!("Value: 5", format!("Value: {:?}", u11::new(5)));
+ assert_eq!("Value: 5", format!("Value: {:?}", u17::new(5)));
+ assert_eq!("Value: 5", format!("Value: {:?}", u38::new(5)));
+ assert_eq!("Value: 60", format!("Value: {:?}", u65::new(60)));
+}
+
+#[test]
+fn lower_hex() {
+ assert_eq!("Value: a", format!("Value: {:x}", 10u32));
+ assert_eq!("Value: a", format!("Value: {:x}", u5::new(10)));
+ assert_eq!("Value: a", format!("Value: {:x}", u11::new(10)));
+ assert_eq!("Value: a", format!("Value: {:x}", u17::new(10)));
+ assert_eq!("Value: a", format!("Value: {:x}", u38::new(10)));
+ assert_eq!("Value: 3c", format!("Value: {:x}", 60));
+ assert_eq!("Value: 3c", format!("Value: {:x}", u65::new(60)));
+}
+
+#[test]
+fn upper_hex() {
+ assert_eq!("Value: A", format!("Value: {:X}", 10u32));
+ assert_eq!("Value: A", format!("Value: {:X}", u5::new(10)));
+ assert_eq!("Value: A", format!("Value: {:X}", u11::new(10)));
+ assert_eq!("Value: A", format!("Value: {:X}", u17::new(10)));
+ assert_eq!("Value: A", format!("Value: {:X}", u38::new(10)));
+ assert_eq!("Value: 3C", format!("Value: {:X}", 60));
+ assert_eq!("Value: 3C", format!("Value: {:X}", u65::new(60)));
+}
+
+#[test]
+fn lower_hex_fancy() {
+ assert_eq!("Value: 0xa", format!("Value: {:#x}", 10u32));
+ assert_eq!("Value: 0xa", format!("Value: {:#x}", u5::new(10)));
+ assert_eq!("Value: 0xa", format!("Value: {:#x}", u11::new(10)));
+ assert_eq!("Value: 0xa", format!("Value: {:#x}", u17::new(10)));
+ assert_eq!("Value: 0xa", format!("Value: {:#x}", u38::new(10)));
+ assert_eq!("Value: 0x3c", format!("Value: {:#x}", 60));
+ assert_eq!("Value: 0x3c", format!("Value: {:#x}", u65::new(60)));
+}
+
+#[test]
+fn upper_hex_fancy() {
+ assert_eq!("Value: 0xA", format!("Value: {:#X}", 10u32));
+ assert_eq!("Value: 0xA", format!("Value: {:#X}", u5::new(10)));
+ assert_eq!("Value: 0xA", format!("Value: {:#X}", u11::new(10)));
+ assert_eq!("Value: 0xA", format!("Value: {:#X}", u17::new(10)));
+ assert_eq!("Value: 0xA", format!("Value: {:#X}", u38::new(10)));
+ assert_eq!("Value: 0x3C", format!("Value: {:#X}", 60));
+ assert_eq!("Value: 0x3C", format!("Value: {:#X}", u65::new(60)));
+}
+
+#[test]
+fn debug_lower_hex_fancy() {
+ assert_eq!("Value: 0xa", format!("Value: {:#x?}", 10u32));
+ assert_eq!("Value: 0xa", format!("Value: {:#x?}", u5::new(10)));
+ assert_eq!("Value: 0xa", format!("Value: {:#x?}", u11::new(10)));
+ assert_eq!("Value: 0xa", format!("Value: {:#x?}", u17::new(10)));
+ assert_eq!("Value: 0xa", format!("Value: {:#x?}", u38::new(10)));
+ assert_eq!("Value: 0x3c", format!("Value: {:#x?}", 60));
+ assert_eq!("Value: 0x3c", format!("Value: {:#x?}", u65::new(60)));
+}
+
+#[test]
+fn debug_upper_hex_fancy() {
+ assert_eq!("Value: 0xA", format!("Value: {:#X?}", 10u32));
+ assert_eq!("Value: 0xA", format!("Value: {:#X?}", u5::new(10)));
+ assert_eq!("Value: 0xA", format!("Value: {:#X?}", u11::new(10)));
+ assert_eq!("Value: 0xA", format!("Value: {:#X?}", u17::new(10)));
+ assert_eq!("Value: 0xA", format!("Value: {:#X?}", u38::new(10)));
+ assert_eq!("Value: 0x3C", format!("Value: {:#X?}", 60));
+ assert_eq!("Value: 0x3C", format!("Value: {:#X?}", u65::new(60)));
+}
+
+#[test]
+fn octal() {
+ assert_eq!("Value: 12", format!("Value: {:o}", 10u32));
+ assert_eq!("Value: 12", format!("Value: {:o}", u5::new(10)));
+ assert_eq!("Value: 12", format!("Value: {:o}", u11::new(10)));
+ assert_eq!("Value: 12", format!("Value: {:o}", u17::new(10)));
+ assert_eq!("Value: 12", format!("Value: {:o}", u38::new(10)));
+ assert_eq!("Value: 74", format!("Value: {:o}", 0o74));
+ assert_eq!("Value: 74", format!("Value: {:o}", u65::new(0o74)));
+}
+
+#[test]
+fn binary() {
+ assert_eq!("Value: 1010", format!("Value: {:b}", 10u32));
+ assert_eq!("Value: 1010", format!("Value: {:b}", u5::new(10)));
+ assert_eq!("Value: 1010", format!("Value: {:b}", u11::new(10)));
+ assert_eq!("Value: 1010", format!("Value: {:b}", u17::new(10)));
+ assert_eq!("Value: 1010", format!("Value: {:b}", u38::new(10)));
+ assert_eq!("Value: 111100", format!("Value: {:b}", 0b111100));
+ assert_eq!("Value: 111100", format!("Value: {:b}", u65::new(0b111100)));
+}
+
+#[test]
+fn hash() {
+ let mut hashmap = HashMap::<u5, u7>::new();
+
+ hashmap.insert(u5::new(11), u7::new(9));
+
+ assert_eq!(Some(&u7::new(9)), hashmap.get(&u5::new(11)));
+ assert_eq!(None, hashmap.get(&u5::new(12)));
+}
+
+#[test]
+fn swap_bytes() {
+ assert_eq!(u24::new(0x12_34_56).swap_bytes(), u24::new(0x56_34_12));
+ assert_eq!(
+ UInt::<u64, 24>::new(0x12_34_56).swap_bytes(),
+ UInt::<u64, 24>::new(0x56_34_12)
+ );
+ assert_eq!(
+ UInt::<u128, 24>::new(0x12_34_56).swap_bytes(),
+ UInt::<u128, 24>::new(0x56_34_12)
+ );
+
+ assert_eq!(
+ u40::new(0x12_34_56_78_9A).swap_bytes(),
+ u40::new(0x9A_78_56_34_12)
+ );
+ assert_eq!(
+ UInt::<u128, 40>::new(0x12_34_56_78_9A).swap_bytes(),
+ UInt::<u128, 40>::new(0x9A_78_56_34_12)
+ );
+
+ assert_eq!(
+ u48::new(0x12_34_56_78_9A_BC).swap_bytes(),
+ u48::new(0xBC_9A_78_56_34_12)
+ );
+ assert_eq!(
+ UInt::<u128, 48>::new(0x12_34_56_78_9A_BC).swap_bytes(),
+ UInt::<u128, 48>::new(0xBC_9A_78_56_34_12)
+ );
+
+ assert_eq!(
+ u56::new(0x12_34_56_78_9A_BC_DE).swap_bytes(),
+ u56::new(0xDE_BC_9A_78_56_34_12)
+ );
+ assert_eq!(
+ UInt::<u128, 56>::new(0x12_34_56_78_9A_BC_DE).swap_bytes(),
+ UInt::<u128, 56>::new(0xDE_BC_9A_78_56_34_12)
+ );
+
+ assert_eq!(
+ u72::new(0x12_34_56_78_9A_BC_DE_FE_DC).swap_bytes(),
+ u72::new(0xDC_FE_DE_BC_9A_78_56_34_12)
+ );
+
+ assert_eq!(
+ u80::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA).swap_bytes(),
+ u80::new(0xBA_DC_FE_DE_BC_9A_78_56_34_12)
+ );
+
+ assert_eq!(
+ u88::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98).swap_bytes(),
+ u88::new(0x98_BA_DC_FE_DE_BC_9A_78_56_34_12)
+ );
+
+ assert_eq!(
+ u96::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76).swap_bytes(),
+ u96::new(0x76_98_BA_DC_FE_DE_BC_9A_78_56_34_12)
+ );
+
+ assert_eq!(
+ u104::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54).swap_bytes(),
+ u104::new(0x54_76_98_BA_DC_FE_DE_BC_9A_78_56_34_12)
+ );
+
+ assert_eq!(
+ u112::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54_32).swap_bytes(),
+ u112::new(0x32_54_76_98_BA_DC_FE_DE_BC_9A_78_56_34_12)
+ );
+
+ assert_eq!(
+ u120::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54_32_10).swap_bytes(),
+ u120::new(0x10_32_54_76_98_BA_DC_FE_DE_BC_9A_78_56_34_12)
+ );
+}
+
+#[test]
+fn to_le_and_be_bytes() {
+ assert_eq!(u24::new(0x12_34_56).to_le_bytes(), [0x56, 0x34, 0x12]);
+ assert_eq!(
+ UInt::<u64, 24>::new(0x12_34_56).to_le_bytes(),
+ [0x56, 0x34, 0x12]
+ );
+ assert_eq!(
+ UInt::<u128, 24>::new(0x12_34_56).to_le_bytes(),
+ [0x56, 0x34, 0x12]
+ );
+
+ assert_eq!(u24::new(0x12_34_56).to_be_bytes(), [0x12, 0x34, 0x56]);
+ assert_eq!(
+ UInt::<u64, 24>::new(0x12_34_56).to_be_bytes(),
+ [0x12, 0x34, 0x56]
+ );
+ assert_eq!(
+ UInt::<u128, 24>::new(0x12_34_56).to_be_bytes(),
+ [0x12, 0x34, 0x56]
+ );
+
+ assert_eq!(
+ u40::new(0x12_34_56_78_9A).to_le_bytes(),
+ [0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+ assert_eq!(
+ UInt::<u128, 40>::new(0x12_34_56_78_9A).to_le_bytes(),
+ [0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+
+ assert_eq!(
+ u40::new(0x12_34_56_78_9A).to_be_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A]
+ );
+ assert_eq!(
+ UInt::<u128, 40>::new(0x12_34_56_78_9A).to_be_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A]
+ );
+
+ assert_eq!(
+ u48::new(0x12_34_56_78_9A_BC).to_le_bytes(),
+ [0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+ assert_eq!(
+ UInt::<u128, 48>::new(0x12_34_56_78_9A_BC).to_le_bytes(),
+ [0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+
+ assert_eq!(
+ u48::new(0x12_34_56_78_9A_BC).to_be_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC]
+ );
+ assert_eq!(
+ UInt::<u128, 48>::new(0x12_34_56_78_9A_BC).to_be_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC]
+ );
+
+ assert_eq!(
+ u56::new(0x12_34_56_78_9A_BC_DE).to_le_bytes(),
+ [0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+ assert_eq!(
+ UInt::<u128, 56>::new(0x12_34_56_78_9A_BC_DE).to_le_bytes(),
+ [0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+
+ assert_eq!(
+ u56::new(0x12_34_56_78_9A_BC_DE).to_be_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE]
+ );
+ assert_eq!(
+ UInt::<u128, 56>::new(0x12_34_56_78_9A_BC_DE).to_be_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE]
+ );
+
+ assert_eq!(
+ u72::new(0x12_34_56_78_9A_BC_DE_FE_DC).to_le_bytes(),
+ [0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+
+ assert_eq!(
+ u72::new(0x12_34_56_78_9A_BC_DE_FE_DC).to_be_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC]
+ );
+
+ assert_eq!(
+ u80::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA).to_le_bytes(),
+ [0xBA, 0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+
+ assert_eq!(
+ u80::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA).to_be_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC, 0xBA]
+ );
+
+ assert_eq!(
+ u88::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98).to_le_bytes(),
+ [0x98, 0xBA, 0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+
+ assert_eq!(
+ u88::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98).to_be_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC, 0xBA, 0x98]
+ );
+
+ assert_eq!(
+ u96::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76).to_le_bytes(),
+ [0x76, 0x98, 0xBA, 0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+
+ assert_eq!(
+ u96::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76).to_be_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC, 0xBA, 0x98, 0x76]
+ );
+
+ assert_eq!(
+ u104::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54).to_le_bytes(),
+ [0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+
+ assert_eq!(
+ u104::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54).to_be_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54]
+ );
+
+ assert_eq!(
+ u112::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54_32).to_le_bytes(),
+ [0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+
+ assert_eq!(
+ u112::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54_32).to_be_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32]
+ );
+
+ assert_eq!(
+ u120::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54_32_10).to_le_bytes(),
+ [
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34,
+ 0x12
+ ]
+ );
+
+ assert_eq!(
+ u120::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54_32_10).to_be_bytes(),
+ [
+ 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32,
+ 0x10
+ ]
+ );
+}
+
+#[test]
+fn from_le_and_be_bytes() {
+ assert_eq!(u24::from_le_bytes([0x56, 0x34, 0x12]), u24::new(0x12_34_56));
+ assert_eq!(
+ UInt::<u64, 24>::from_le_bytes([0x56, 0x34, 0x12]),
+ UInt::<u64, 24>::new(0x12_34_56)
+ );
+ assert_eq!(
+ UInt::<u128, 24>::from_le_bytes([0x56, 0x34, 0x12]),
+ UInt::<u128, 24>::new(0x12_34_56)
+ );
+
+ assert_eq!(u24::from_be_bytes([0x12, 0x34, 0x56]), u24::new(0x12_34_56));
+ assert_eq!(
+ UInt::<u64, 24>::from_be_bytes([0x12, 0x34, 0x56]),
+ UInt::<u64, 24>::new(0x12_34_56)
+ );
+ assert_eq!(
+ UInt::<u128, 24>::from_be_bytes([0x12, 0x34, 0x56]),
+ UInt::<u128, 24>::new(0x12_34_56)
+ );
+
+ assert_eq!(
+ u40::from_le_bytes([0x9A, 0x78, 0x56, 0x34, 0x12]),
+ u40::new(0x12_34_56_78_9A)
+ );
+ assert_eq!(
+ UInt::<u128, 40>::from_le_bytes([0x9A, 0x78, 0x56, 0x34, 0x12]),
+ UInt::<u128, 40>::new(0x12_34_56_78_9A)
+ );
+
+ assert_eq!(
+ u40::from_be_bytes([0x12, 0x34, 0x56, 0x78, 0x9A]),
+ u40::new(0x12_34_56_78_9A)
+ );
+ assert_eq!(
+ UInt::<u128, 40>::from_be_bytes([0x12, 0x34, 0x56, 0x78, 0x9A]),
+ UInt::<u128, 40>::new(0x12_34_56_78_9A)
+ );
+
+ assert_eq!(
+ u48::from_le_bytes([0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]),
+ u48::new(0x12_34_56_78_9A_BC)
+ );
+ assert_eq!(
+ UInt::<u128, 48>::from_le_bytes([0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]),
+ UInt::<u128, 48>::new(0x12_34_56_78_9A_BC)
+ );
+
+ assert_eq!(
+ u48::from_be_bytes([0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC]),
+ u48::new(0x12_34_56_78_9A_BC)
+ );
+ assert_eq!(
+ UInt::<u128, 48>::from_be_bytes([0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC]),
+ UInt::<u128, 48>::new(0x12_34_56_78_9A_BC)
+ );
+
+ assert_eq!(
+ u56::from_le_bytes([0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]),
+ u56::new(0x12_34_56_78_9A_BC_DE)
+ );
+ assert_eq!(
+ UInt::<u128, 56>::from_le_bytes([0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]),
+ UInt::<u128, 56>::new(0x12_34_56_78_9A_BC_DE)
+ );
+
+ assert_eq!(
+ u56::from_be_bytes([0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE]),
+ u56::new(0x12_34_56_78_9A_BC_DE)
+ );
+ assert_eq!(
+ UInt::<u128, 56>::from_be_bytes([0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE]),
+ UInt::<u128, 56>::new(0x12_34_56_78_9A_BC_DE)
+ );
+
+ assert_eq!(
+ u72::from_le_bytes([0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]),
+ u72::new(0x12_34_56_78_9A_BC_DE_FE_DC)
+ );
+
+ assert_eq!(
+ u72::from_be_bytes([0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC]),
+ u72::new(0x12_34_56_78_9A_BC_DE_FE_DC)
+ );
+
+ assert_eq!(
+ u80::from_le_bytes([0xBA, 0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]),
+ u80::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA)
+ );
+
+ assert_eq!(
+ u80::from_be_bytes([0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC, 0xBA]),
+ u80::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA)
+ );
+
+ assert_eq!(
+ u88::from_le_bytes([0x98, 0xBA, 0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]),
+ u88::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98)
+ );
+
+ assert_eq!(
+ u88::from_be_bytes([0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC, 0xBA, 0x98]),
+ u88::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98)
+ );
+
+ assert_eq!(
+ u96::from_le_bytes([
+ 0x76, 0x98, 0xBA, 0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12
+ ]),
+ u96::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76)
+ );
+
+ assert_eq!(
+ u96::from_be_bytes([
+ 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC, 0xBA, 0x98, 0x76
+ ]),
+ u96::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76)
+ );
+
+ assert_eq!(
+ u104::from_le_bytes([
+ 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12
+ ]),
+ u104::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54)
+ );
+
+ assert_eq!(
+ u104::from_be_bytes([
+ 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54
+ ]),
+ u104::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54)
+ );
+
+ assert_eq!(
+ u112::from_le_bytes([
+ 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12
+ ]),
+ u112::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54_32)
+ );
+
+ assert_eq!(
+ u112::from_be_bytes([
+ 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32
+ ]),
+ u112::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54_32)
+ );
+
+ assert_eq!(
+ u120::from_le_bytes([
+ 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34,
+ 0x12
+ ]),
+ u120::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54_32_10)
+ );
+
+ assert_eq!(
+ u120::from_be_bytes([
+ 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32,
+ 0x10
+ ]),
+ u120::new(0x12_34_56_78_9A_BC_DE_FE_DC_BA_98_76_54_32_10)
+ );
+}
+
+#[test]
+fn to_ne_bytes() {
+ if cfg!(target_endian = "little") {
+ assert_eq!(
+ u40::new(0x12_34_56_78_9A).to_ne_bytes(),
+ [0x9A, 0x78, 0x56, 0x34, 0x12]
+ );
+ } else {
+ assert_eq!(
+ u40::new(0x12_34_56_78_9A).to_ne_bytes(),
+ [0x12, 0x34, 0x56, 0x78, 0x9A]
+ );
+ }
+}
+
+#[test]
+fn from_ne_bytes() {
+ if cfg!(target_endian = "little") {
+ assert_eq!(
+ u40::from_ne_bytes([0x9A, 0x78, 0x56, 0x34, 0x12]),
+ u40::new(0x12_34_56_78_9A)
+ );
+ } else {
+ assert_eq!(
+ u40::from_ne_bytes([0x12, 0x34, 0x56, 0x78, 0x9A]),
+ u40::new(0x12_34_56_78_9A)
+ );
+ }
+}
+
+#[test]
+fn simple_le_be() {
+ const REGULAR: u40 = u40::new(0x12_34_56_78_9A);
+ const SWAPPED: u40 = u40::new(0x9A_78_56_34_12);
+ if cfg!(target_endian = "little") {
+ assert_eq!(REGULAR.to_le(), REGULAR);
+ assert_eq!(REGULAR.to_be(), SWAPPED);
+ assert_eq!(u40::from_le(REGULAR), REGULAR);
+ assert_eq!(u40::from_be(REGULAR), SWAPPED);
+ } else {
+ assert_eq!(REGULAR.to_le(), SWAPPED);
+ assert_eq!(REGULAR.to_be(), REGULAR);
+ assert_eq!(u40::from_le(REGULAR), SWAPPED);
+ assert_eq!(u40::from_be(REGULAR), REGULAR);
+ }
+}
+
+#[test]
+fn wrapping_add() {
+ assert_eq!(u7::new(120).wrapping_add(u7::new(1)), u7::new(121));
+ assert_eq!(u7::new(120).wrapping_add(u7::new(10)), u7::new(2));
+ assert_eq!(u7::new(127).wrapping_add(u7::new(127)), u7::new(126));
+}
+
+#[test]
+fn wrapping_sub() {
+ assert_eq!(u7::new(120).wrapping_sub(u7::new(1)), u7::new(119));
+ assert_eq!(u7::new(10).wrapping_sub(u7::new(20)), u7::new(118));
+ assert_eq!(u7::new(0).wrapping_sub(u7::new(1)), u7::new(127));
+}
+
+#[test]
+fn wrapping_mul() {
+ assert_eq!(u7::new(120).wrapping_mul(u7::new(0)), u7::new(0));
+ assert_eq!(u7::new(120).wrapping_mul(u7::new(1)), u7::new(120));
+
+ // Overflow u7
+ assert_eq!(u7::new(120).wrapping_mul(u7::new(2)), u7::new(112));
+
+ // Overflow the underlying type
+ assert_eq!(u7::new(120).wrapping_mul(u7::new(3)), u7::new(104));
+}
+
+#[test]
+fn wrapping_div() {
+ assert_eq!(u7::new(120).wrapping_div(u7::new(1)), u7::new(120));
+ assert_eq!(u7::new(120).wrapping_div(u7::new(2)), u7::new(60));
+ assert_eq!(u7::new(120).wrapping_div(u7::new(120)), u7::new(1));
+ assert_eq!(u7::new(120).wrapping_div(u7::new(121)), u7::new(0));
+}
+
+#[should_panic]
+#[test]
+fn wrapping_div_by_zero() {
+ let _ = u7::new(120).wrapping_div(u7::new(0));
+}
+
+#[test]
+fn wrapping_shl() {
+ assert_eq!(u7::new(0b010_1101).wrapping_shl(0), u7::new(0b010_1101));
+ assert_eq!(u7::new(0b010_1101).wrapping_shl(1), u7::new(0b101_1010));
+ assert_eq!(u7::new(0b010_1101).wrapping_shl(6), u7::new(0b100_0000));
+ assert_eq!(u7::new(0b010_1101).wrapping_shl(7), u7::new(0b010_1101));
+ assert_eq!(u7::new(0b010_1101).wrapping_shl(8), u7::new(0b101_1010));
+ assert_eq!(u7::new(0b010_1101).wrapping_shl(14), u7::new(0b010_1101));
+ assert_eq!(u7::new(0b010_1101).wrapping_shl(15), u7::new(0b101_1010));
+}
+
+#[test]
+fn wrapping_shr() {
+ assert_eq!(u7::new(0b010_1101).wrapping_shr(0), u7::new(0b010_1101));
+ assert_eq!(u7::new(0b010_1101).wrapping_shr(1), u7::new(0b001_0110));
+ assert_eq!(u7::new(0b010_1101).wrapping_shr(5), u7::new(0b000_0001));
+ assert_eq!(u7::new(0b010_1101).wrapping_shr(7), u7::new(0b010_1101));
+ assert_eq!(u7::new(0b010_1101).wrapping_shr(8), u7::new(0b001_0110));
+ assert_eq!(u7::new(0b010_1101).wrapping_shr(14), u7::new(0b010_1101));
+ assert_eq!(u7::new(0b010_1101).wrapping_shr(15), u7::new(0b001_0110));
+}
+
+#[test]
+fn saturating_add() {
+ assert_eq!(u7::new(120).saturating_add(u7::new(1)), u7::new(121));
+ assert_eq!(u7::new(120).saturating_add(u7::new(10)), u7::new(127));
+ assert_eq!(u7::new(127).saturating_add(u7::new(127)), u7::new(127));
+ assert_eq!(
+ UInt::<u8, 8>::new(250).saturating_add(UInt::<u8, 8>::new(10)),
+ UInt::<u8, 8>::new(255)
+ );
+}
+
+#[test]
+fn saturating_sub() {
+ assert_eq!(u7::new(120).saturating_sub(u7::new(30)), u7::new(90));
+ assert_eq!(u7::new(120).saturating_sub(u7::new(119)), u7::new(1));
+ assert_eq!(u7::new(120).saturating_sub(u7::new(120)), u7::new(0));
+ assert_eq!(u7::new(120).saturating_sub(u7::new(121)), u7::new(0));
+ assert_eq!(u7::new(0).saturating_sub(u7::new(127)), u7::new(0));
+}
+
+#[test]
+fn saturating_mul() {
+ // Fast-path: Only the arbitrary int is bounds checked
+ assert_eq!(u4::new(5).saturating_mul(u4::new(2)), u4::new(10));
+ assert_eq!(u4::new(5).saturating_mul(u4::new(3)), u4::new(15));
+ assert_eq!(u4::new(5).saturating_mul(u4::new(4)), u4::new(15));
+ assert_eq!(u4::new(5).saturating_mul(u4::new(5)), u4::new(15));
+ assert_eq!(u4::new(5).saturating_mul(u4::new(6)), u4::new(15));
+ assert_eq!(u4::new(5).saturating_mul(u4::new(7)), u4::new(15));
+
+ // Slow-path (well, one more comparison)
+ assert_eq!(u5::new(5).saturating_mul(u5::new(2)), u5::new(10));
+ assert_eq!(u5::new(5).saturating_mul(u5::new(3)), u5::new(15));
+ assert_eq!(u5::new(5).saturating_mul(u5::new(4)), u5::new(20));
+ assert_eq!(u5::new(5).saturating_mul(u5::new(5)), u5::new(25));
+ assert_eq!(u5::new(5).saturating_mul(u5::new(6)), u5::new(30));
+ assert_eq!(u5::new(5).saturating_mul(u5::new(7)), u5::new(31));
+ assert_eq!(u5::new(30).saturating_mul(u5::new(1)), u5::new(30));
+ assert_eq!(u5::new(30).saturating_mul(u5::new(2)), u5::new(31));
+ assert_eq!(u5::new(30).saturating_mul(u5::new(10)), u5::new(31));
+}
+
+#[test]
+fn saturating_div() {
+ assert_eq!(u4::new(5).saturating_div(u4::new(1)), u4::new(5));
+ assert_eq!(u4::new(5).saturating_div(u4::new(2)), u4::new(2));
+ assert_eq!(u4::new(5).saturating_div(u4::new(3)), u4::new(1));
+ assert_eq!(u4::new(5).saturating_div(u4::new(4)), u4::new(1));
+ assert_eq!(u4::new(5).saturating_div(u4::new(5)), u4::new(1));
+}
+
+#[test]
+#[should_panic]
+fn saturating_divby0() {
+ // saturating_div throws an exception on zero
+ let _ = u4::new(5).saturating_div(u4::new(0));
+}
+
+#[test]
+fn saturating_pow() {
+ assert_eq!(u7::new(5).saturating_pow(0), u7::new(1));
+ assert_eq!(u7::new(5).saturating_pow(1), u7::new(5));
+ assert_eq!(u7::new(5).saturating_pow(2), u7::new(25));
+ assert_eq!(u7::new(5).saturating_pow(3), u7::new(125));
+ assert_eq!(u7::new(5).saturating_pow(4), u7::new(127));
+ assert_eq!(u7::new(5).saturating_pow(255), u7::new(127));
+}
+
+#[test]
+fn checked_add() {
+ assert_eq!(u7::new(120).checked_add(u7::new(1)), Some(u7::new(121)));
+ assert_eq!(u7::new(120).checked_add(u7::new(7)), Some(u7::new(127)));
+ assert_eq!(u7::new(120).checked_add(u7::new(10)), None);
+ assert_eq!(u7::new(127).checked_add(u7::new(127)), None);
+ assert_eq!(
+ UInt::<u8, 8>::new(250).checked_add(UInt::<u8, 8>::new(10)),
+ None
+ );
+}
+
+#[test]
+fn checked_sub() {
+ assert_eq!(u7::new(120).checked_sub(u7::new(30)), Some(u7::new(90)));
+ assert_eq!(u7::new(120).checked_sub(u7::new(119)), Some(u7::new(1)));
+ assert_eq!(u7::new(120).checked_sub(u7::new(120)), Some(u7::new(0)));
+ assert_eq!(u7::new(120).checked_sub(u7::new(121)), None);
+ assert_eq!(u7::new(0).checked_sub(u7::new(127)), None);
+}
+
+#[test]
+fn checked_mul() {
+ // Fast-path: Only the arbitrary int is bounds checked
+ assert_eq!(u4::new(5).checked_mul(u4::new(2)), Some(u4::new(10)));
+ assert_eq!(u4::new(5).checked_mul(u4::new(3)), Some(u4::new(15)));
+ assert_eq!(u4::new(5).checked_mul(u4::new(4)), None);
+ assert_eq!(u4::new(5).checked_mul(u4::new(5)), None);
+ assert_eq!(u4::new(5).checked_mul(u4::new(6)), None);
+ assert_eq!(u4::new(5).checked_mul(u4::new(7)), None);
+
+ // Slow-path (well, one more comparison)
+ assert_eq!(u5::new(5).checked_mul(u5::new(2)), Some(u5::new(10)));
+ assert_eq!(u5::new(5).checked_mul(u5::new(3)), Some(u5::new(15)));
+ assert_eq!(u5::new(5).checked_mul(u5::new(4)), Some(u5::new(20)));
+ assert_eq!(u5::new(5).checked_mul(u5::new(5)), Some(u5::new(25)));
+ assert_eq!(u5::new(5).checked_mul(u5::new(6)), Some(u5::new(30)));
+ assert_eq!(u5::new(5).checked_mul(u5::new(7)), None);
+ assert_eq!(u5::new(30).checked_mul(u5::new(1)), Some(u5::new(30)));
+ assert_eq!(u5::new(30).checked_mul(u5::new(2)), None);
+ assert_eq!(u5::new(30).checked_mul(u5::new(10)), None);
+}
+
+#[test]
+fn checked_div() {
+ // checked_div handles division by zero without exception, unlike saturating_div
+ assert_eq!(u4::new(5).checked_div(u4::new(0)), None);
+ assert_eq!(u4::new(5).checked_div(u4::new(1)), Some(u4::new(5)));
+ assert_eq!(u4::new(5).checked_div(u4::new(2)), Some(u4::new(2)));
+ assert_eq!(u4::new(5).checked_div(u4::new(3)), Some(u4::new(1)));
+ assert_eq!(u4::new(5).checked_div(u4::new(4)), Some(u4::new(1)));
+ assert_eq!(u4::new(5).checked_div(u4::new(5)), Some(u4::new(1)));
+}
+
+#[test]
+fn checked_shl() {
+ assert_eq!(
+ u7::new(0b010_1101).checked_shl(0),
+ Some(u7::new(0b010_1101))
+ );
+ assert_eq!(
+ u7::new(0b010_1101).checked_shl(1),
+ Some(u7::new(0b101_1010))
+ );
+ assert_eq!(
+ u7::new(0b010_1101).checked_shl(6),
+ Some(u7::new(0b100_0000))
+ );
+ assert_eq!(u7::new(0b010_1101).checked_shl(7), None);
+ assert_eq!(u7::new(0b010_1101).checked_shl(8), None);
+ assert_eq!(u7::new(0b010_1101).checked_shl(14), None);
+ assert_eq!(u7::new(0b010_1101).checked_shl(15), None);
+}
+
+#[test]
+fn checked_shr() {
+ assert_eq!(
+ u7::new(0b010_1101).checked_shr(0),
+ Some(u7::new(0b010_1101))
+ );
+ assert_eq!(
+ u7::new(0b010_1101).checked_shr(1),
+ Some(u7::new(0b001_0110))
+ );
+ assert_eq!(
+ u7::new(0b010_1101).checked_shr(5),
+ Some(u7::new(0b000_0001))
+ );
+ assert_eq!(u7::new(0b010_1101).checked_shr(7), None);
+ assert_eq!(u7::new(0b010_1101).checked_shr(8), None);
+ assert_eq!(u7::new(0b010_1101).checked_shr(14), None);
+ assert_eq!(u7::new(0b010_1101).checked_shr(15), None);
+}
+
+#[test]
+fn overflowing_add() {
+ assert_eq!(
+ u7::new(120).overflowing_add(u7::new(1)),
+ (u7::new(121), false)
+ );
+ assert_eq!(
+ u7::new(120).overflowing_add(u7::new(7)),
+ (u7::new(127), false)
+ );
+ assert_eq!(
+ u7::new(120).overflowing_add(u7::new(10)),
+ (u7::new(2), true)
+ );
+ assert_eq!(
+ u7::new(127).overflowing_add(u7::new(127)),
+ (u7::new(126), true)
+ );
+ assert_eq!(
+ UInt::<u8, 8>::new(250).overflowing_add(UInt::<u8, 8>::new(5)),
+ (UInt::<u8, 8>::new(255), false)
+ );
+ assert_eq!(
+ UInt::<u8, 8>::new(250).overflowing_add(UInt::<u8, 8>::new(10)),
+ (UInt::<u8, 8>::new(4), true)
+ );
+}
+
+#[test]
+fn overflowing_sub() {
+ assert_eq!(
+ u7::new(120).overflowing_sub(u7::new(30)),
+ (u7::new(90), false)
+ );
+ assert_eq!(
+ u7::new(120).overflowing_sub(u7::new(119)),
+ (u7::new(1), false)
+ );
+ assert_eq!(
+ u7::new(120).overflowing_sub(u7::new(120)),
+ (u7::new(0), false)
+ );
+ assert_eq!(
+ u7::new(120).overflowing_sub(u7::new(121)),
+ (u7::new(127), true)
+ );
+ assert_eq!(u7::new(0).overflowing_sub(u7::new(127)), (u7::new(1), true));
+}
+
+#[test]
+fn overflowing_mul() {
+ // Fast-path: Only the arbitrary int is bounds checked
+ assert_eq!(u4::new(5).overflowing_mul(u4::new(2)), (u4::new(10), false));
+ assert_eq!(u4::new(5).overflowing_mul(u4::new(3)), (u4::new(15), false));
+ assert_eq!(u4::new(5).overflowing_mul(u4::new(4)), (u4::new(4), true));
+ assert_eq!(u4::new(5).overflowing_mul(u4::new(5)), (u4::new(9), true));
+ assert_eq!(u4::new(5).overflowing_mul(u4::new(6)), (u4::new(14), true));
+ assert_eq!(u4::new(5).overflowing_mul(u4::new(7)), (u4::new(3), true));
+
+ // Slow-path (well, one more comparison)
+ assert_eq!(u5::new(5).overflowing_mul(u5::new(2)), (u5::new(10), false));
+ assert_eq!(u5::new(5).overflowing_mul(u5::new(3)), (u5::new(15), false));
+ assert_eq!(u5::new(5).overflowing_mul(u5::new(4)), (u5::new(20), false));
+ assert_eq!(u5::new(5).overflowing_mul(u5::new(5)), (u5::new(25), false));
+ assert_eq!(u5::new(5).overflowing_mul(u5::new(6)), (u5::new(30), false));
+ assert_eq!(u5::new(5).overflowing_mul(u5::new(7)), (u5::new(3), true));
+ assert_eq!(
+ u5::new(30).overflowing_mul(u5::new(1)),
+ (u5::new(30), false)
+ );
+ assert_eq!(u5::new(30).overflowing_mul(u5::new(2)), (u5::new(28), true));
+ assert_eq!(
+ u5::new(30).overflowing_mul(u5::new(10)),
+ (u5::new(12), true)
+ );
+}
+
+#[test]
+fn overflowing_div() {
+ assert_eq!(u4::new(5).overflowing_div(u4::new(1)), (u4::new(5), false));
+ assert_eq!(u4::new(5).overflowing_div(u4::new(2)), (u4::new(2), false));
+ assert_eq!(u4::new(5).overflowing_div(u4::new(3)), (u4::new(1), false));
+ assert_eq!(u4::new(5).overflowing_div(u4::new(4)), (u4::new(1), false));
+ assert_eq!(u4::new(5).overflowing_div(u4::new(5)), (u4::new(1), false));
+}
+
+#[should_panic]
+#[test]
+fn overflowing_div_by_zero() {
+ let _ = u4::new(5).overflowing_div(u4::new(0));
+}
+
+#[test]
+fn overflowing_shl() {
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shl(0),
+ (u7::new(0b010_1101), false)
+ );
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shl(1),
+ (u7::new(0b101_1010), false)
+ );
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shl(6),
+ (u7::new(0b100_0000), false)
+ );
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shl(7),
+ (u7::new(0b010_1101), true)
+ );
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shl(8),
+ (u7::new(0b101_1010), true)
+ );
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shl(14),
+ (u7::new(0b010_1101), true)
+ );
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shl(15),
+ (u7::new(0b101_1010), true)
+ );
+}
+
+#[test]
+fn overflowing_shr() {
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shr(0),
+ (u7::new(0b010_1101), false)
+ );
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shr(1),
+ (u7::new(0b001_0110), false)
+ );
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shr(5),
+ (u7::new(0b000_0001), false)
+ );
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shr(7),
+ (u7::new(0b010_1101), true)
+ );
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shr(8),
+ (u7::new(0b001_0110), true)
+ );
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shr(14),
+ (u7::new(0b010_1101), true)
+ );
+ assert_eq!(
+ u7::new(0b010_1101).overflowing_shr(15),
+ (u7::new(0b001_0110), true)
+ );
+}
+
+#[test]
+fn reverse_bits() {
+ const A: u5 = u5::new(0b11101);
+ const B: u5 = A.reverse_bits();
+ assert_eq!(B, u5::new(0b10111));
+
+ assert_eq!(
+ UInt::<u128, 6>::new(0b101011),
+ UInt::<u128, 6>::new(0b110101).reverse_bits()
+ );
+
+ assert_eq!(u1::new(1).reverse_bits().value(), 1);
+ assert_eq!(u1::new(0).reverse_bits().value(), 0);
+}
+
+#[test]
+fn count_ones_and_zeros() {
+ assert_eq!(4, u5::new(0b10111).count_ones());
+ assert_eq!(1, u5::new(0b10111).count_zeros());
+ assert_eq!(1, u5::new(0b10111).leading_ones());
+ assert_eq!(0, u5::new(0b10111).leading_zeros());
+ assert_eq!(3, u5::new(0b10111).trailing_ones());
+ assert_eq!(0, u5::new(0b10111).trailing_zeros());
+
+ assert_eq!(2, u5::new(0b10100).trailing_zeros());
+ assert_eq!(3, u5::new(0b00011).leading_zeros());
+
+ assert_eq!(0, u5::new(0b00000).count_ones());
+ assert_eq!(5, u5::new(0b00000).count_zeros());
+
+ assert_eq!(5, u5::new(0b11111).count_ones());
+ assert_eq!(0, u5::new(0b11111).count_zeros());
+
+ assert_eq!(3, u127::new(0b111).count_ones());
+ assert_eq!(124, u127::new(0b111).count_zeros());
+}
+
+#[test]
+fn rotate_left() {
+ assert_eq!(u1::new(0b1), u1::new(0b1).rotate_left(1));
+ assert_eq!(u2::new(0b01), u2::new(0b10).rotate_left(1));
+
+ assert_eq!(u5::new(0b10111), u5::new(0b10111).rotate_left(0));
+ assert_eq!(u5::new(0b01111), u5::new(0b10111).rotate_left(1));
+ assert_eq!(u5::new(0b11110), u5::new(0b10111).rotate_left(2));
+ assert_eq!(u5::new(0b11101), u5::new(0b10111).rotate_left(3));
+ assert_eq!(u5::new(0b11011), u5::new(0b10111).rotate_left(4));
+ assert_eq!(u5::new(0b10111), u5::new(0b10111).rotate_left(5));
+ assert_eq!(u5::new(0b01111), u5::new(0b10111).rotate_left(6));
+ assert_eq!(u5::new(0b01111), u5::new(0b10111).rotate_left(556));
+
+ assert_eq!(u24::new(0x0FFEEC), u24::new(0xC0FFEE).rotate_left(4));
+}
+
+#[test]
+fn rotate_right() {
+ assert_eq!(u1::new(0b1), u1::new(0b1).rotate_right(1));
+ assert_eq!(u2::new(0b01), u2::new(0b10).rotate_right(1));
+
+ assert_eq!(u5::new(0b10011), u5::new(0b10011).rotate_right(0));
+ assert_eq!(u5::new(0b11001), u5::new(0b10011).rotate_right(1));
+ assert_eq!(u5::new(0b11100), u5::new(0b10011).rotate_right(2));
+ assert_eq!(u5::new(0b01110), u5::new(0b10011).rotate_right(3));
+ assert_eq!(u5::new(0b00111), u5::new(0b10011).rotate_right(4));
+ assert_eq!(u5::new(0b10011), u5::new(0b10011).rotate_right(5));
+ assert_eq!(u5::new(0b11001), u5::new(0b10011).rotate_right(6));
+
+ assert_eq!(u24::new(0xEC0FFE), u24::new(0xC0FFEE).rotate_right(4));
+}
+
+#[cfg(feature = "step_trait")]
+#[test]
+fn range_agrees_with_underlying() {
+ compare_range(u19::MIN, u19::MAX);
+ compare_range(u37::new(95_993), u37::new(1_994_910));
+ compare_range(u68::new(58_858_348), u68::new(58_860_000));
+ compare_range(u122::new(111_222_333_444), u122::new(111_222_444_555));
+ compare_range(u5::MIN, u5::MAX);
+ compare_range(u23::MIN, u23::MAX);
+ compare_range(u48::new(999_444), u48::new(1_005_000));
+ compare_range(u99::new(12345), u99::new(54321));
+
+ fn compare_range<T, const BITS: usize>(arb_start: UInt<T, BITS>, arb_end: UInt<T, BITS>)
+ where
+ T: Copy + Step,
+ UInt<T, BITS>: Step,
+ {
+ let arbint_range = (arb_start..=arb_end).map(UInt::value);
+ let underlying_range = arb_start.value()..=arb_end.value();
+
+ assert!(arbint_range.eq(underlying_range));
+ }
+}
+
+#[cfg(feature = "step_trait")]
+#[test]
+fn forward_checked() {
+ // In range
+ assert_eq!(Some(u7::new(121)), Step::forward_checked(u7::new(120), 1));
+ assert_eq!(Some(u7::new(127)), Step::forward_checked(u7::new(120), 7));
+
+ // Out of range
+ assert_eq!(None, Step::forward_checked(u7::new(120), 8));
+
+ // Out of range for the underlying type
+ assert_eq!(None, Step::forward_checked(u7::new(120), 140));
+}
+
+#[cfg(feature = "step_trait")]
+#[test]
+fn backward_checked() {
+ // In range
+ assert_eq!(Some(u7::new(1)), Step::backward_checked(u7::new(10), 9));
+ assert_eq!(Some(u7::new(0)), Step::backward_checked(u7::new(10), 10));
+
+ // Out of range (for both the arbitrary int and and the underlying type)
+ assert_eq!(None, Step::backward_checked(u7::new(10), 11));
+}
+
+#[cfg(feature = "step_trait")]
+#[test]
+fn steps_between() {
+ assert_eq!(Some(0), Step::steps_between(&u50::new(50), &u50::new(50)));
+
+ assert_eq!(Some(4), Step::steps_between(&u24::new(5), &u24::new(9)));
+ assert_eq!(None, Step::steps_between(&u24::new(9), &u24::new(5)));
+
+ // this assumes usize is <= 64 bits. a test like this one exists in `core::iter::step`.
+ assert_eq!(
+ Some(usize::MAX),
+ Step::steps_between(&u125::new(0x7), &u125::new(0x1_0000_0000_0000_0006))
+ );
+ assert_eq!(
+ None,
+ Step::steps_between(&u125::new(0x7), &u125::new(0x1_0000_0000_0000_0007))
+ );
+}
+
+#[cfg(feature = "serde")]
+#[test]
+fn serde() {
+ use serde_test::{assert_de_tokens_error, assert_tokens, Token};
+
+ let a = u7::new(0b0101_0101);
+ assert_tokens(&a, &[Token::U8(0b0101_0101)]);
+
+ let b = u63::new(0x1234_5678_9ABC_DEFE);
+ assert_tokens(&b, &[Token::U64(0x1234_5678_9ABC_DEFE)]);
+
+ // This requires https://github.com/serde-rs/test/issues/18 (Add Token::I128 and Token::U128 to serde_test)
+ // let c = u127::new(0x1234_5678_9ABC_DEFE_DCBA_9876_5432_1010);
+ // assert_tokens(&c, &[Token::U128(0x1234_5678_9ABC_DEFE_DCBA_9876_5432_1010)]);
+
+ assert_de_tokens_error::<u2>(
+ &[Token::U8(0b0101_0101)],
+ "invalid value: integer `85`, expected a value between `0` and `3`",
+ );
+
+ assert_de_tokens_error::<u100>(
+ &[Token::I64(-1)],
+ "invalid value: integer `-1`, expected u128",
+ );
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/.cargo-checksum.json b/rust/hw/char/pl011/vendor/bilge-impl/.cargo-checksum.json
new file mode 100644
index 0000000000..304736708c
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"b1ebf0b5d89b3e8387d70b589b2557196f0dc902364900889acabed886b3ce1f","README.md":"6d4fcc631ed47bbe8e654649185ce987e9630192ea25c84edd264674e30efa4d","src/bitsize.rs":"8a0878699f18889c987954e1ab918d37c434a387a5dec0f1da8864596fcb14b4","src/bitsize/split.rs":"a59469023f48c5675159b6b46c3655033b4d9adefaba3575301fb485b4868e3d","src/bitsize_internal.rs":"30e67efe8e7baff1514b1a63f1a470701dfcfbf9933cc28aaccef663069a37b0","src/bitsize_internal/struct_gen.rs":"e04bd0346cd393467b3821e977c5deddfde11603ccfa9b63b5e1e60d726d51bb","src/debug_bits.rs":"e28a9e9101c2b365d21c2f6777a389d72dde03f2fcf5fc5add2c7aed278fc1a1","src/default_bits.rs":"bd1943f685f590cdb740b0071de302725dd9c8696d5ca83c7ce9e1dea967d573","src/fmt_bits.rs":"e656c5c019081a6322a678b4bc8c259493081b5888be3a982a12b896ce63deb7","src/from_bits.rs":"fa0acec12ccf1692f47f1b44d6b8ecce0f7da5bfdb465a85546304ede15efd4f","src/lib.rs":"e402a6aabc5b3715a1be94e022f27bf8a3760248ac62d3de7b4c0112cf53b7a2","src/shared.rs":"ac0fb16da63e96d7916f3d8e43e65895c0f0bf14f1afdb2196ec0a7ae5aa2aa2","src/shared/discriminant_assigner.rs":"1d719c4c1d8e1111888d32e930dbaf83a532b4df2b774faa8a0f8cdc6050682a","src/shared/fallback.rs":"8e8af0f66991fd93891d0d9eb1379ed7ead68725100568211677529c9007162c","src/shared/util.rs":"3c191d8585837b2ef391c05df1c201c4beedef0161f0bf37e19b292feef7ef5f","src/try_from_bits.rs":"bda602a90dd6df33e308f8ba9433032cd409213649ab5a0d0297199f4d93b2dd"},"package":"feb11e002038ad243af39c2068c8a72bcf147acf05025dcdb916fcc000adb2d8"}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/Cargo.toml b/rust/hw/char/pl011/vendor/bilge-impl/Cargo.toml
new file mode 100644
index 0000000000..4cf7c59505
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/Cargo.toml
@@ -0,0 +1,54 @@
+# 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"
+name = "bilge-impl"
+version = "0.2.0"
+authors = ["Hecatia Elegua"]
+description = "Use bitsized types as if they were a feature of rust."
+documentation = "https://docs.rs/bilge"
+readme = "README.md"
+keywords = [
+ "bilge",
+ "bitfield",
+ "bits",
+ "register",
+]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/hecatia-elegua/bilge"
+
+[lib]
+proc-macro = true
+
+[dependencies.itertools]
+version = "0.11.0"
+
+[dependencies.proc-macro-error]
+version = "1.0"
+default-features = false
+
+[dependencies.proc-macro2]
+version = "1.0"
+
+[dependencies.quote]
+version = "1.0"
+
+[dependencies.syn]
+version = "2.0"
+features = ["full"]
+
+[dev-dependencies.syn-path]
+version = "2.0"
+
+[features]
+default = []
+nightly = []
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/README.md b/rust/hw/char/pl011/vendor/bilge-impl/README.md
new file mode 100644
index 0000000000..48daad0fcb
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/README.md
@@ -0,0 +1,327 @@
+# bilge: the most readable bitfields
+
+[](https://crates.io/crates/bilge)
+[](https://docs.rs/bilge)
+[](https://github.com/Aaronepower/tokei#badges)
+
+_Y e s_, this is yet another bitfield crate, but hear me out:
+
+This is a _**bit**_ better than what we had before.
+
+I wanted a design fitting rust:
+
+- **safe**
+ - types model as much of the functionality as possible and don't allow false usage
+- **fast**
+ - like handwritten bit fiddling code
+- **simple to complex**
+ - obvious and readable basic frontend, like normal structs
+ - only minimally and gradually introduce advanced concepts
+ - provide extension mechanisms
+
+The lib is **no-std** (and fully `const` behind a `"nightly"` feature gate).
+
+For some more explanations on the "why" and "how": [blog post](https://hecatia-elegua.github.io/blog/no-more-bit-fiddling/) and [reddit comments](https://www.reddit.com/r/rust/comments/13ic0mf/no_more_bit_fiddling_and_introducing_bilge/).
+
+## WARNING
+
+Our current version is still pre 1.0, which means nothing is completely stable.
+
+However, constructors, getters, setters and From/TryFrom should stay the same, since their semantics are very clear.
+
+[//]: # (keep this fixed to the version in .github/workflows/ci.yml, rust-toolchain.toml)
+
+The nightly feature is tested on `nightly-2022-11-03` and [will not work on the newest nightly until const_convert comes back](https://github.com/rust-lang/rust/issues/110395#issuecomment-1524775763).
+
+## Usage
+
+To make your life easier:
+
+```rust
+use bilge::prelude::*;
+```
+
+### Infallible (From)
+
+You can just specify bitsized fields like normal fields:
+
+```rust
+#[bitsize(14)]
+struct Register {
+ header: u4,
+ body: u7,
+ footer: Footer,
+}
+```
+
+The attribute `bitsize` generates the bitfield, while `14` works as a failsafe, emitting a compile error if your struct definition doesn't declare 14 bits.
+Let's define the nested struct `Footer` as well:
+
+```rust
+#[bitsize(3)]
+#[derive(FromBits)]
+struct Footer {
+ is_last: bool,
+ code: Code,
+}
+```
+
+As you can see, we added `#[derive(FromBits)]`, which is needed for `Register`'s getters and setters.
+Due to how rust macros work (outside-in), it needs to be below `#[bitsize]`.
+Also, `bool` can be used as one bit.
+
+`Code` is another nesting, this time an enum:
+
+```rust
+#[bitsize(2)]
+#[derive(FromBits)]
+enum Code { Success, Error, IoError, GoodExample }
+```
+
+Now we can construct `Register`:
+
+```rust
+let reg1 = Register::new(
+ u4::new(0b1010),
+ u7::new(0b010_1010),
+ Footer::new(true, Code::GoodExample)
+);
+```
+
+Or, if we add `#[derive(FromBits)]` to `Register` and want to parse a raw register value:
+
+```rust
+let mut reg2 = Register::from(u14::new(0b11_1_0101010_1010));
+```
+
+And getting and setting fields is done like this:
+
+```rust
+let header = reg2.header();
+reg2.set_footer(Footer::new(false, Code::Success));
+```
+
+Any kinds of tuple and array are also supported:
+
+```rust
+#[bitsize(32)]
+#[derive(FromBits)]
+struct InterruptSetEnables([bool; 32]);
+```
+
+Which produces the usual getter and setter, but also element accessors:
+
+```rust
+let mut ise = InterruptSetEnables::from(0b0000_0000_0000_0000_0000_0000_0001_0000);
+let ise5 = ise.val_0_at(4);
+ise.set_val_0_at(2, ise5);
+assert_eq!(0b0000_0000_0000_0000_0000_0000_0001_0100, ise.value);
+```
+
+Depending on what you're working with, only a subset of enum values might be clear, or some values might be reserved.
+In that case, you can use a fallback variant, defined like this:
+
+```rust
+#[bitsize(32)]
+#[derive(FromBits, Debug, PartialEq)]
+enum Subclass {
+ Mouse,
+ Keyboard,
+ Speakers,
+ #[fallback]
+ Reserved,
+}
+```
+
+which will convert any undeclared bits to `Reserved`:
+
+```rust
+assert_eq!(Subclass::Reserved, Subclass::from(3));
+assert_eq!(Subclass::Reserved, Subclass::from(42));
+let num = u32::from(Subclass::from(42));
+assert_eq!(3, num);
+assert_ne!(42, num);
+```
+
+or, if you need to keep the exact number saved, use:
+
+```rust
+#[fallback]
+Reserved(u32),
+```
+
+```rust
+assert_eq!(Subclass2::Reserved(3), Subclass2::from(3));
+assert_eq!(Subclass2::Reserved(42), Subclass2::from(42));
+let num = u32::from(Subclass2::from(42));
+assert_eq!(42, num);
+assert_ne!(3, num);
+```
+
+### Fallible (TryFrom)
+
+In contrast to structs, enums don't have to declare all of their bits:
+
+```rust
+#[bitsize(2)]
+#[derive(TryFromBits)]
+enum Class {
+ Mobile, Semimobile, /* 0x2 undefined */ Stationary = 0x3
+}
+```
+
+meaning this will work:
+
+```rust
+let class = Class::try_from(u2::new(2));
+assert!(class.is_err());
+```
+
+except we first need to `#[derive(Debug, PartialEq)]` on `Class`, since `assert_eq!` needs those.
+
+Let's do that, and use `Class` as a field:
+
+```rust
+#[bitsize(8)]
+#[derive(TryFromBits)]
+struct Device {
+ reserved: u2,
+ class: Class,
+ reserved: u4,
+}
+```
+
+This shows `TryFrom` being propagated upward. There's also another small help: `reserved` fields (which are often used in registers) can all have the same name.
+
+Again, let's try to print this:
+
+```rust
+println!("{:?}", Device::try_from(0b0000_11_00));
+println!("{:?}", Device::new(Class::Mobile));
+```
+
+And again, `Device` doesn't implement `Debug`:
+
+### DebugBits
+
+For structs, you need to add `#[derive(DebugBits)]` to get an output like this:
+
+```rust
+Ok(Device { reserved_i: 0, class: Stationary, reserved_ii: 0 })
+Device { reserved_i: 0, class: Mobile, reserved_ii: 0 }
+```
+
+For testing + overview, the full readme example code is in `/examples/readme.rs`.
+
+### Custom -Bits derives
+
+One of the main advantages of our approach is that we can keep `#[bitsize]` pretty slim, offloading all the other features to derive macros.
+Besides the derive macros shown above, you can extend `bilge` with your own derive crates working on bitfields.
+An example of this is given in [`/tests/custom_derive.rs`](https://github.com/hecatia-elegua/bilge/blob/main/tests/custom_derive.rs), with its implementation in [`tests/custom_bits`](https://github.com/hecatia-elegua/bilge/blob/1dfb6cf7d278d102d3f96ac31a9374e2b27fafc7/tests/custom_bits/custom_bits_derive/src/lib.rs).
+
+## Back- and Forwards Compatibility
+
+The syntax is kept very similar to usual rust structs for a simple reason:
+
+The endgoal of this library is to support the adoption of LLVM's arbitrary bitwidth integers into rust,
+thereby allowing rust-native bitfields.
+Until then, bilge is using the wonderful [`arbitrary-int` crate by danlehmann](https://github.com/danlehmann/arbitrary-int).
+
+After all attribute expansions, our generated bitfield contains a single field, somewhat like:
+
+```rust
+struct Register { value: u14 }
+```
+
+This means you _could_ modify the inner value directly, but it breaks type safety guarantees (e.g. unfilled or read-only fields).
+So if you need to modify the whole field, instead use the type-safe conversions `u14::from(register)` and `Register::from(u14)`.
+It is possible that this inner type will be made private.
+
+For some more examples and an overview of functionality, take a look at `/examples` and `/tests`.
+
+## Alternatives
+
+### benchmarks, performance, asm line count
+
+First of all, [basic benchmarking](https://github.com/hecatia-elegua/bilge/blob/main/benches/compared/main.rs) reveals that all alternatives mentioned here (besides deku) have about the same performance and line count. This includes a handwritten version.
+
+### build-time
+
+Measuring build time of the crate inself (both with its dependencies and without), yields these numbers on my machine:
+| | debug | debug single crate | release | release single crate |
+|-----------------------|-------|--------------------|-----------|----------------------|
+| bilge 1.67-nightly | 8 | 1.8 | 6 | 0.8 |
+| bitbybit 1.69 | 4.5 | 1.3 | 13.5 [^*] | 9.5 [^*] |
+| modular-bitfield 1.69 | 8 | 2.2 | 7.2 | 1.6 |
+
+[^*]: This is just a weird rustc regression or my setup or sth, not representative.
+
+This was measured with `cargo clean && cargo build [--release] --quiet --timings`.
+Of course, the actual codegen time on an example project needs to be measured, too.
+
+
+### handwritten implementation
+
+The common handwritten implementation pattern for bitfields in rust looks [somewhat like benches/compared/handmade.rs](https://github.com/hecatia-elegua/bilge/blob/main/benches/compared/handmade.rs), sometimes also throwing around a lot of consts for field offsets. The problems with this approach are:
+- readability suffers
+- offset, cast or masking errors could go unnoticed
+- bit fiddling, shifting and masking is done all over the place, in contrast to bitfields
+- beginners suffer, although I would argue even seniors, since it's more like: "Why do we need to learn and debug bit fiddling if we can get most of it done by using structs?"
+- reimplementing different kinds of _fallible nested-struct enum-tuple array field access_ might not be so fun
+
+### modular-bitfield
+
+The often used and very inspiring [`modular-bitfield`](https://github.com/robbepop/modular-bitfield) has a few
+problems:
+- it is unmaintained and has a quirky structure
+- constructors use the builder pattern
+ - makes user code unreadable if you have many fields
+ - can accidentally leave things uninitialized
+- `from_bytes` can easily take invalid arguments, which turns verification inside-out:
+ - modular-bitfield flow: `u16` -> `PackedData::from_bytes([u16])` -> `PackedData::status_or_err()?`
+ - needs to check for `Err` on every single access
+ - adds duplicate getters and setters with postfix `_or_err`
+ - reinvents `From<u16>`/`TryFrom<u16>` as a kind of hybrid
+ - bilge: usual type-system centric flow: `u16` -> `PackedData::try_from(u16)?` -> `PackedData::status()`
+ - just works, needs to check nothing on access
+ - some more general info on this: [Parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/)
+- big god-macro
+ - powerful, but less readable to the devs of modular-bitfield
+ - needs to cover many derives in itself, like `impl Debug` (other bitfield crates do this as well)
+ - bilge: solves this by providing a kind of scope for `-Bits`-derives
+
+and implementation differences:
+- underlying type is a byte array
+ - can be useful for bitfields larger than u128
+ - bilge: if your bitfields get larger than u128, you can most often split them into multiple bitfields of a primitive size (like u64) and put those in a parent struct which is not a bitfield
+
+Still, modular-bitfield is pretty good and I had set out to build something equal or hopefully better than it.
+Tell me where I can do better, I will try.
+
+### bitbybit
+
+One of the libs inspired by the same crate is [`bitbybit`](https://github.com/danlehmann/bitfield), which is much more readable and up-to-date. Actually, I even helped and am still helping on that one as well. After experimenting and hacking around in their code though, I realized it would need to be severely changed for the features and structure I had in mind.
+
+implementation differences (as of 26.04.23):
+- it can do read/write-only, array strides and repeat the same bits for multiple fields
+ - bilge: these will be added the moment someone needs it
+- redundant bit-offset specification, which can help or annoy, the same way bilge's `reserved` fields can help or annoy
+
+### deku
+
+After looking at a ton of bitfield libs on crates.io, I _didn't_ find [`deku`](https://github.com/sharksforarms/deku).
+I will still mention it here because it uses a very interesting crate underneath (bitvec).
+Currently (as of 26.04.23), it generates far more assembly and takes longer to run, since parts of the API are not `const`.
+I've opened an issue on their repo about that.
+
+### most others
+
+Besides that, many bitfield libs try to imitate or look like C bitfields, even though these are hated by many.
+I argue most beginners would have the idea to specify bits with basic primitives like u1, u2, ...
+This also opens up some possibilities for calculation and conversion on those primitives.
+
+Something similar can be said about `bitflags`, which, under this model, can be turned into simple structs with bools and enums.
+
+Basically, `bilge` tries to convert bit fiddling, shifting and masking into more widely known concepts like struct access.
+
+About the name: a bilge is one of the "lowest" parts of a ship, nothing else to it :)
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/meson.build b/rust/hw/char/pl011/vendor/bilge-impl/meson.build
new file mode 100644
index 0000000000..11f3dd186f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/meson.build
@@ -0,0 +1,24 @@
+rust = import('rust')
+
+_bilge_impl_rs = rust.proc_macro(
+ 'bilge_impl',
+ files('src/lib.rs'),
+ rust_args: rust_args + [
+ '--edition', '2021',
+ '--cfg', 'use_fallback',
+ '--cfg', 'feature="syn-error"',
+ '--cfg', 'feature="proc-macro"',
+ ],
+ dependencies: [
+ dep_itertools,
+ dep_proc_macro_error_attr,
+ dep_proc_macro_error,
+ dep_quote,
+ dep_syn,
+ dep_proc_macro2,
+ ],
+)
+
+dep_bilge_impl = declare_dependency(
+ link_with: _bilge_impl_rs,
+)
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/bitsize.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/bitsize.rs
new file mode 100644
index 0000000000..66660c3e30
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/bitsize.rs
@@ -0,0 +1,187 @@
+mod split;
+
+use proc_macro2::{Ident, TokenStream};
+use proc_macro_error::{abort, abort_call_site};
+use quote::quote;
+use split::SplitAttributes;
+use syn::{punctuated::Iter, spanned::Spanned, Fields, Item, ItemEnum, ItemStruct, Type, Variant};
+
+use crate::shared::{self, enum_fills_bitsize, is_fallback_attribute, unreachable, BitSize, MAX_ENUM_BIT_SIZE};
+
+/// Intermediate Representation, just for bundling these together
+struct ItemIr {
+ /// generated item (and size check)
+ expanded: TokenStream,
+}
+
+pub(super) fn bitsize(args: TokenStream, item: TokenStream) -> TokenStream {
+ let (item, declared_bitsize) = parse(item, args);
+ let attrs = SplitAttributes::from_item(&item);
+ let ir = match item {
+ Item::Struct(mut item) => {
+ modify_special_field_names(&mut item.fields);
+ analyze_struct(&item.fields);
+ let expanded = generate_struct(&item, declared_bitsize);
+ ItemIr { expanded }
+ }
+ Item::Enum(item) => {
+ analyze_enum(declared_bitsize, item.variants.iter());
+ let expanded = generate_enum(&item);
+ ItemIr { expanded }
+ }
+ _ => unreachable(()),
+ };
+ generate_common(ir, attrs, declared_bitsize)
+}
+
+fn parse(item: TokenStream, args: TokenStream) -> (Item, BitSize) {
+ let item = syn::parse2(item).unwrap_or_else(unreachable);
+
+ if args.is_empty() {
+ abort_call_site!("missing attribute value"; help = "you need to define the size like this: `#[bitsize(32)]`")
+ }
+
+ let (declared_bitsize, _arb_int) = shared::bitsize_and_arbitrary_int_from(args);
+ (item, declared_bitsize)
+}
+
+fn check_type_is_supported(ty: &Type) {
+ use Type::*;
+ match ty {
+ Tuple(tuple) => tuple.elems.iter().for_each(check_type_is_supported),
+ Array(array) => check_type_is_supported(&array.elem),
+ // Probably okay (compilation would validate that this type is also Bitsized)
+ Path(_) => (),
+ // These don't work with structs or aren't useful in bitfields.
+ BareFn(_) | Group(_) | ImplTrait(_) | Infer(_) | Macro(_) | Never(_) |
+ // We could provide some info on error as to why Ptr/Reference won't work due to safety.
+ Ptr(_) | Reference(_) |
+ // The bitsize must be known at compile time.
+ Slice(_) |
+ // Something to investigate, but doesn't seem useful/usable here either.
+ TraitObject(_) |
+ // I have no idea where this is used.
+ Verbatim(_) | Paren(_) => abort!(ty, "This field type is not supported"),
+ _ => abort!(ty, "This field type is currently not supported"),
+ }
+}
+
+/// Allows you to give multiple fields the name `reserved` or `padding`
+/// by numbering them for you.
+fn modify_special_field_names(fields: &mut Fields) {
+ // We could have just counted up, i.e. `reserved_0`, but people might interpret this as "reserved to zero".
+ // Using some other, more useful unique info as postfix would be nice.
+ // Also, it might be useful to generate no getters or setters for these fields and skipping some calc.
+ let mut reserved_count = 0;
+ let mut padding_count = 0;
+ let field_idents_mut = fields.iter_mut().filter_map(|field| field.ident.as_mut());
+ for ident in field_idents_mut {
+ if ident == "reserved" || ident == "_reserved" {
+ reserved_count += 1;
+ let span = ident.span();
+ let name = format!("reserved_{}", "i".repeat(reserved_count));
+ *ident = Ident::new(&name, span)
+ } else if ident == "padding" || ident == "_padding" {
+ padding_count += 1;
+ let span = ident.span();
+ let name = format!("padding_{}", "i".repeat(padding_count));
+ *ident = Ident::new(&name, span)
+ }
+ }
+}
+
+fn analyze_struct(fields: &Fields) {
+ if fields.is_empty() {
+ abort_call_site!("structs without fields are not supported")
+ }
+
+ // don't move this. we validate all nested field types here as well
+ // and later assume this was checked.
+ for field in fields {
+ check_type_is_supported(&field.ty)
+ }
+}
+
+fn analyze_enum(bitsize: BitSize, variants: Iter<Variant>) {
+ if bitsize > MAX_ENUM_BIT_SIZE {
+ abort_call_site!("enum bitsize is limited to {}", MAX_ENUM_BIT_SIZE)
+ }
+
+ let variant_count = variants.clone().count();
+ if variant_count == 0 {
+ abort_call_site!("empty enums are not supported");
+ }
+
+ let has_fallback = variants.flat_map(|variant| &variant.attrs).any(is_fallback_attribute);
+
+ if !has_fallback {
+ // this has a side-effect of validating the enum count
+ let _ = enum_fills_bitsize(bitsize, variant_count);
+ }
+}
+
+fn generate_struct(item: &ItemStruct, declared_bitsize: u8) -> TokenStream {
+ let ItemStruct { vis, ident, fields, .. } = item;
+ let declared_bitsize = declared_bitsize as usize;
+
+ let computed_bitsize = fields.iter().fold(quote!(0), |acc, next| {
+ let field_size = shared::generate_type_bitsize(&next.ty);
+ quote!(#acc + #field_size)
+ });
+
+ // we could remove this if the whole struct gets passed
+ let is_tuple_struct = fields.iter().any(|field| field.ident.is_none());
+ let fields_def = if is_tuple_struct {
+ let fields = fields.iter();
+ quote! {
+ ( #(#fields,)* );
+ }
+ } else {
+ let fields = fields.iter();
+ quote! {
+ { #(#fields,)* }
+ }
+ };
+
+ quote! {
+ #vis struct #ident #fields_def
+
+ // constness: when we get const blocks evaluated at compile time, add a const computed_bitsize
+ const _: () = assert!(
+ (#computed_bitsize) == (#declared_bitsize),
+ concat!("struct size and declared bit size differ: ",
+ // stringify!(#computed_bitsize),
+ " != ",
+ stringify!(#declared_bitsize))
+ );
+ }
+}
+
+// attributes are handled in `generate_common`
+fn generate_enum(item: &ItemEnum) -> TokenStream {
+ let ItemEnum { vis, ident, variants, .. } = item;
+ quote! {
+ #vis enum #ident {
+ #variants
+ }
+ }
+}
+
+/// we have _one_ generate_common function, which holds everything that struct and enum have _in common_.
+/// Everything else has its own generate_ functions.
+fn generate_common(ir: ItemIr, attrs: SplitAttributes, declared_bitsize: u8) -> TokenStream {
+ let ItemIr { expanded } = ir;
+ let SplitAttributes {
+ before_compression,
+ after_compression,
+ } = attrs;
+
+ let bitsize_internal_attr = quote! {#[::bilge::bitsize_internal(#declared_bitsize)]};
+
+ quote! {
+ #(#before_compression)*
+ #bitsize_internal_attr
+ #(#after_compression)*
+ #expanded
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/bitsize/split.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/bitsize/split.rs
new file mode 100644
index 0000000000..3848ba2c24
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/bitsize/split.rs
@@ -0,0 +1,185 @@
+use proc_macro_error::{abort, abort_call_site};
+use quote::ToTokens;
+use syn::{meta::ParseNestedMeta, parse_quote, Attribute, Item, Meta, Path};
+
+use crate::shared::{unreachable, util::PathExt};
+
+/// Since we want to be maximally interoperable, we need to handle attributes in a special way.
+/// We use `#[bitsize]` as a sort of scope for all attributes below it and
+/// the whole family of `-Bits` macros only works when used in that scope.
+///
+/// Let's visualize why this is the case, starting with some user-code:
+/// ```ignore
+/// #[bitsize(6)]
+/// #[derive(Clone, Copy, PartialEq, DebugBits, FromBits)]
+/// struct Example {
+/// field1: u2,
+/// field2: u4,
+/// }
+/// ```
+/// First, the attributes get sorted, depending on their name.
+/// Every attribute in need of field information gets resolved first,
+/// in this case `DebugBits` and `FromBits`.
+///
+/// Now, after resolving all `before_compression` attributes, the halfway-resolved
+/// code looks like this:
+/// ```ignore
+/// #[::bilge::bitsize_internal(6)]
+/// #[derive(Clone, Copy, PartialEq)]
+/// struct Example {
+/// field1: u2,
+/// field2: u4,
+/// }
+/// ```
+/// This `#[bitsize_internal]` attribute is the one actually doing the compression and generating
+/// all the getters, setters and a constructor.
+///
+/// Finally, the struct ends up like this (excluding the generated impl blocks):
+/// ```ignore
+/// struct Example {
+/// value: u6,
+/// }
+/// ```
+pub struct SplitAttributes {
+ pub before_compression: Vec<Attribute>,
+ pub after_compression: Vec<Attribute>,
+}
+
+impl SplitAttributes {
+ /// Split item attributes into those applied before bitfield-compression and those applied after.
+ /// Also, abort on any invalid configuration.
+ ///
+ /// Any derives with suffix `Bits` will be able to access field information.
+ /// This way, users of `bilge` can define their own derives working on the uncompressed bitfield.
+ pub fn from_item(item: &Item) -> SplitAttributes {
+ let attrs = match item {
+ Item::Enum(item) => &item.attrs,
+ Item::Struct(item) => &item.attrs,
+ _ => abort_call_site!("item is not a struct or enum"; help = "`#[bitsize]` can only be used on structs and enums"),
+ };
+
+ let parsed = attrs.iter().map(parse_attribute);
+
+ let is_struct = matches!(item, Item::Struct(..));
+
+ let mut from_bytes = None;
+ let mut has_frombits = false;
+
+ let mut before_compression = vec![];
+ let mut after_compression = vec![];
+
+ for parsed_attr in parsed {
+ match parsed_attr {
+ ParsedAttribute::DeriveList(derives) => {
+ for mut derive in derives {
+ if derive.matches(&["zerocopy", "FromBytes"]) {
+ from_bytes = Some(derive.clone());
+ } else if derive.matches(&["bilge", "FromBits"]) {
+ has_frombits = true;
+ } else if derive.matches_core_or_std(&["fmt", "Debug"]) && is_struct {
+ abort!(derive.0, "use derive(DebugBits) for structs")
+ } else if derive.matches_core_or_std(&["default", "Default"]) && is_struct {
+ // emit_warning!(derive.0, "use derive(DefaultBits) for structs")
+ derive.0 = syn::parse_quote!(::bilge::DefaultBits);
+ }
+
+ if derive.is_custom_bitfield_derive() {
+ before_compression.push(derive.into_attribute());
+ } else {
+ // It is most probable that basic derive macros work if we put them on after compression
+ after_compression.push(derive.into_attribute());
+ }
+ }
+ }
+
+ ParsedAttribute::BitsizeInternal(attr) => {
+ abort!(attr, "remove bitsize_internal"; help = "attribute bitsize_internal can only be applied internally by the bitsize macros")
+ }
+
+ ParsedAttribute::Other(attr) => {
+ // I don't know with which attrs I can hit Path and NameValue,
+ // so let's just put them on after compression.
+ after_compression.push(attr.to_owned())
+ }
+ };
+ }
+
+ if let Some(from_bytes) = from_bytes {
+ if !has_frombits {
+ abort!(from_bytes.0, "a bitfield with zerocopy::FromBytes also needs to have FromBits")
+ }
+ }
+
+ // currently, enums don't need special handling - so just put all attributes before compression
+ if !is_struct {
+ before_compression.append(&mut after_compression)
+ }
+
+ SplitAttributes {
+ before_compression,
+ after_compression,
+ }
+ }
+}
+
+fn parse_attribute(attribute: &Attribute) -> ParsedAttribute {
+ match &attribute.meta {
+ Meta::List(list) if list.path.is_ident("derive") => {
+ let mut derives = Vec::new();
+ let add_derive = |meta: ParseNestedMeta| {
+ let derive = Derive(meta.path);
+ derives.push(derive);
+
+ Ok(())
+ };
+
+ list.parse_nested_meta(add_derive)
+ .unwrap_or_else(|e| abort!(list.tokens, "failed to parse derive: {}", e));
+
+ ParsedAttribute::DeriveList(derives)
+ }
+
+ meta if contains_anywhere(meta, "bitsize_internal") => ParsedAttribute::BitsizeInternal(attribute),
+
+ _ => ParsedAttribute::Other(attribute),
+ }
+}
+
+/// a crude approximation of things we currently consider in item attributes
+enum ParsedAttribute<'attr> {
+ DeriveList(Vec<Derive>),
+ BitsizeInternal(&'attr Attribute),
+ Other(&'attr Attribute),
+}
+
+/// the path of a single derive attribute, parsed from a list which may have contained several
+#[derive(Clone)]
+struct Derive(Path);
+
+impl Derive {
+ /// a new `#[derive]` attribute containing only this derive
+ fn into_attribute(self) -> Attribute {
+ let path = self.0;
+ parse_quote! { #[derive(#path)] }
+ }
+
+ /// by `bilge` convention, any derive satisfying this condition is able
+ /// to access bitfield structure information pre-compression,
+ /// allowing for user derives
+ fn is_custom_bitfield_derive(&self) -> bool {
+ let last_segment = self.0.segments.last().unwrap_or_else(|| unreachable(()));
+
+ last_segment.ident.to_string().ends_with("Bits")
+ }
+}
+
+impl PathExt for Derive {
+ fn matches(&self, str_segments: &[&str]) -> bool {
+ self.0.matches(str_segments)
+ }
+}
+
+/// slightly hacky. attempts to recognize cases where an ident is deeply-nested in the meta.
+fn contains_anywhere(meta: &Meta, ident: &str) -> bool {
+ meta.to_token_stream().to_string().contains(ident)
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal.rs
new file mode 100644
index 0000000000..ad10350372
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal.rs
@@ -0,0 +1,235 @@
+use proc_macro2::{Ident, TokenStream};
+use quote::quote;
+use syn::{Attribute, Field, Item, ItemEnum, ItemStruct, Type};
+
+use crate::shared::{self, unreachable};
+
+pub(crate) mod struct_gen;
+
+/// Intermediate Representation, just for bundling these together
+struct ItemIr<'a> {
+ attrs: &'a Vec<Attribute>,
+ name: &'a Ident,
+ /// generated item (and setters, getters, constructor, impl Bitsized)
+ expanded: TokenStream,
+}
+
+pub(super) fn bitsize_internal(args: TokenStream, item: TokenStream) -> TokenStream {
+ let (item, arb_int) = parse(item, args);
+ let ir = match item {
+ Item::Struct(ref item) => {
+ let expanded = generate_struct(item, &arb_int);
+ let attrs = &item.attrs;
+ let name = &item.ident;
+ ItemIr { attrs, name, expanded }
+ }
+ Item::Enum(ref item) => {
+ let expanded = generate_enum(item);
+ let attrs = &item.attrs;
+ let name = &item.ident;
+ ItemIr { attrs, name, expanded }
+ }
+ _ => unreachable(()),
+ };
+ generate_common(ir, &arb_int)
+}
+
+fn parse(item: TokenStream, args: TokenStream) -> (Item, TokenStream) {
+ let item = syn::parse2(item).unwrap_or_else(unreachable);
+ let (_declared_bitsize, arb_int) = shared::bitsize_and_arbitrary_int_from(args);
+ (item, arb_int)
+}
+
+fn generate_struct(struct_data: &ItemStruct, arb_int: &TokenStream) -> TokenStream {
+ let ItemStruct { vis, ident, fields, .. } = struct_data;
+
+ let mut fieldless_next_int = 0;
+ let mut previous_field_sizes = vec![];
+ let (accessors, (constructor_args, constructor_parts)): (Vec<TokenStream>, (Vec<TokenStream>, Vec<TokenStream>)) = fields
+ .iter()
+ .map(|field| {
+ // offset is needed for bit-shifting
+ // struct Example { field1: u8, field2: u4, field3: u4 }
+ // previous_field_sizes = [] -> unwrap_or_else -> field_offset = 0
+ // previous_field_sizes = [8] -> reduce -> field_offset = 0 + 8 = 8
+ // previous_field_sizes = [8, 4] -> reduce -> field_offset = 0 + 8 + 4 = 12
+ let field_offset = previous_field_sizes
+ .iter()
+ .cloned()
+ .reduce(|acc, next| quote!(#acc + #next))
+ .unwrap_or_else(|| quote!(0));
+ let field_size = shared::generate_type_bitsize(&field.ty);
+ previous_field_sizes.push(field_size);
+ generate_field(field, &field_offset, &mut fieldless_next_int)
+ })
+ .unzip();
+
+ let const_ = if cfg!(feature = "nightly") { quote!(const) } else { quote!() };
+
+ quote! {
+ #vis struct #ident {
+ /// WARNING: modifying this value directly can break invariants
+ value: #arb_int,
+ }
+ impl #ident {
+ // #[inline]
+ #[allow(clippy::too_many_arguments, clippy::type_complexity, unused_parens)]
+ pub #const_ fn new(#( #constructor_args )*) -> Self {
+ type ArbIntOf<T> = <T as Bitsized>::ArbitraryInt;
+ type BaseIntOf<T> = <ArbIntOf<T> as Number>::UnderlyingType;
+
+ let mut offset = 0;
+ let raw_value = #( #constructor_parts )|*;
+ let value = #arb_int::new(raw_value);
+ Self { value }
+ }
+ #( #accessors )*
+ }
+ }
+}
+
+fn generate_field(field: &Field, field_offset: &TokenStream, fieldless_next_int: &mut usize) -> (TokenStream, (TokenStream, TokenStream)) {
+ let Field { ident, ty, .. } = field;
+ let name = if let Some(ident) = ident {
+ ident.clone()
+ } else {
+ let name = format!("val_{fieldless_next_int}");
+ *fieldless_next_int += 1;
+ syn::parse_str(&name).unwrap_or_else(unreachable)
+ };
+
+ // skip reserved fields in constructors and setters
+ let name_str = name.to_string();
+ if name_str.contains("reserved_") || name_str.contains("padding_") {
+ // needed for `DebugBits`
+ let getter = generate_getter(field, field_offset, &name);
+ let size = shared::generate_type_bitsize(ty);
+ let accessors = quote!(#getter);
+ let constructor_arg = quote!();
+ let constructor_part = quote! { {
+ // we still need to shift by the element's size
+ offset += #size;
+ 0
+ } };
+ return (accessors, (constructor_arg, constructor_part));
+ }
+
+ let getter = generate_getter(field, field_offset, &name);
+ let setter = generate_setter(field, field_offset, &name);
+ let (constructor_arg, constructor_part) = generate_constructor_stuff(ty, &name);
+
+ let accessors = quote! {
+ #getter
+ #setter
+ };
+
+ (accessors, (constructor_arg, constructor_part))
+}
+
+fn generate_getter(field: &Field, offset: &TokenStream, name: &Ident) -> TokenStream {
+ let Field { attrs, vis, ty, .. } = field;
+
+ let getter_value = struct_gen::generate_getter_value(ty, offset, false);
+
+ let const_ = if cfg!(feature = "nightly") { quote!(const) } else { quote!() };
+
+ let array_at = if let Type::Array(array) = ty {
+ let elem_ty = &array.elem;
+ let len_expr = &array.len;
+ let name: Ident = syn::parse_str(&format!("{name}_at")).unwrap_or_else(unreachable);
+ let getter_value = struct_gen::generate_getter_value(elem_ty, offset, true);
+ quote! {
+ // #[inline]
+ #(#attrs)*
+ #[allow(clippy::type_complexity, unused_parens)]
+ #vis #const_ fn #name(&self, index: usize) -> #elem_ty {
+ ::core::assert!(index < #len_expr);
+ #getter_value
+ }
+ }
+ } else {
+ quote!()
+ };
+
+ quote! {
+ // #[inline]
+ #(#attrs)*
+ #[allow(clippy::type_complexity, unused_parens)]
+ #vis #const_ fn #name(&self) -> #ty {
+ #getter_value
+ }
+
+ #array_at
+ }
+}
+
+fn generate_setter(field: &Field, offset: &TokenStream, name: &Ident) -> TokenStream {
+ let Field { attrs, vis, ty, .. } = field;
+ let setter_value = struct_gen::generate_setter_value(ty, offset, false);
+
+ let name: Ident = syn::parse_str(&format!("set_{name}")).unwrap_or_else(unreachable);
+
+ let const_ = if cfg!(feature = "nightly") { quote!(const) } else { quote!() };
+
+ let array_at = if let Type::Array(array) = ty {
+ let elem_ty = &array.elem;
+ let len_expr = &array.len;
+ let name: Ident = syn::parse_str(&format!("{name}_at")).unwrap_or_else(unreachable);
+ let setter_value = struct_gen::generate_setter_value(elem_ty, offset, true);
+ quote! {
+ // #[inline]
+ #(#attrs)*
+ #[allow(clippy::type_complexity, unused_parens)]
+ #vis #const_ fn #name(&mut self, index: usize, value: #elem_ty) {
+ ::core::assert!(index < #len_expr);
+ #setter_value
+ }
+ }
+ } else {
+ quote!()
+ };
+
+ quote! {
+ // #[inline]
+ #(#attrs)*
+ #[allow(clippy::type_complexity, unused_parens)]
+ #vis #const_ fn #name(&mut self, value: #ty) {
+ #setter_value
+ }
+
+ #array_at
+ }
+}
+
+fn generate_constructor_stuff(ty: &Type, name: &Ident) -> (TokenStream, TokenStream) {
+ let constructor_arg = quote! {
+ #name: #ty,
+ };
+ let constructor_part = struct_gen::generate_constructor_part(ty, name);
+ (constructor_arg, constructor_part)
+}
+
+fn generate_enum(enum_data: &ItemEnum) -> TokenStream {
+ let ItemEnum { vis, ident, variants, .. } = enum_data;
+ quote! {
+ #vis enum #ident {
+ #variants
+ }
+ }
+}
+
+/// We have _one_ `generate_common` function, which holds everything struct and enum have _in common_.
+/// Everything else has its own `generate_` functions.
+fn generate_common(ir: ItemIr, arb_int: &TokenStream) -> TokenStream {
+ let ItemIr { attrs, name, expanded } = ir;
+
+ quote! {
+ #(#attrs)*
+ #expanded
+ impl ::bilge::Bitsized for #name {
+ type ArbitraryInt = #arb_int;
+ const BITS: usize = <Self::ArbitraryInt as Bitsized>::BITS;
+ const MAX: Self::ArbitraryInt = <Self::ArbitraryInt as Bitsized>::MAX;
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal/struct_gen.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal/struct_gen.rs
new file mode 100644
index 0000000000..74cd65fec1
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal/struct_gen.rs
@@ -0,0 +1,402 @@
+//! We're keeping most of the generating together, to ease reading here and in `cargo_expand`.
+//! For this reason, we also use more locals and types.
+//! These locals, types, casts should be optimized away.
+//! In simple cases they indeed are optimized away, but if some case is not, please report.
+//!
+//! ## Important
+//!
+//! We often do thing like:
+//! ```ignore
+//! quote! {
+//! #value_shifted
+//! value_shifted
+//! }
+//! ```
+//! By convention, `#value_shifted` has its name because we define a `let value_shifted` inside that `TokenStream`.
+//! So the above code means we're returning the value of `let value_shifted`.
+//! Earlier on, we would have done something like this:
+//! ```ignore
+//! quote! {
+//! let value_shifted = { #value_shifted };
+//! value_shifted
+//! }
+//! ```
+//! which aids in reading this here macro code, but doesn't help reading the generated code since it introduces
+//! lots of new scopes (curly brackets). We need the scope since `#value_shifted` expands to multiple lines.
+use super::*;
+
+/// Top-level function which initializes the cursor and offsets it to what we want to read
+///
+/// `is_array_elem_getter` allows us to generate an array_at getter more easily
+pub(crate) fn generate_getter_value(ty: &Type, offset: &TokenStream, is_array_elem_getter: bool) -> TokenStream {
+ // if we generate `fn array_at(index)`, we need to offset to the array element
+ let elem_offset = if is_array_elem_getter {
+ let size = shared::generate_type_bitsize(ty);
+ quote! {
+ let size = #size;
+ // cursor now starts at this element
+ cursor >>= size * index;
+ }
+ } else {
+ quote!()
+ };
+
+ let inner = generate_getter_inner(ty, true);
+ quote! {
+ // for ease of reading
+ type ArbIntOf<T> = <T as Bitsized>::ArbitraryInt;
+ type BaseIntOf<T> = <ArbIntOf<T> as Number>::UnderlyingType;
+ // cursor is the value we read from and starts at the struct's first field
+ let mut cursor = self.value.value();
+ // this field's offset
+ let field_offset = #offset;
+ // cursor now starts at this field
+ cursor >>= field_offset;
+ #elem_offset
+
+ #inner
+ }
+}
+
+/// We heavily rely on the fact that transmuting into a nested array [[T; N1]; N2] can
+/// be done in the same way as transmuting into an array [T; N1*N2].
+/// Otherwise, nested arrays would generate even more code.
+///
+/// `is_getter` allows us to generate a try_from impl more easily
+pub(crate) fn generate_getter_inner(ty: &Type, is_getter: bool) -> TokenStream {
+ use Type::*;
+ match ty {
+ Tuple(tuple) => {
+ let unbraced = tuple
+ .elems
+ .iter()
+ .map(|elem| {
+ // for every tuple element, generate its getter code
+ let getter = generate_getter_inner(elem, is_getter);
+ // and add a scope around it
+ quote! { {#getter} }
+ })
+ .reduce(|acc, next| {
+ // join all getter codes with:
+ if is_getter {
+ // comma, to later produce (val_1, val_2, ...)
+ quote!(#acc, #next)
+ } else {
+ // bool-and, since for try_from we just generate bools
+ quote!(#acc && #next)
+ }
+ })
+ // `field: (),` will be handled like this:
+ .unwrap_or_else(|| quote!());
+ // add tuple braces, to produce (val_1, val_2, ...)
+ quote! { (#unbraced) }
+ }
+ Array(array) => {
+ // [[T; N1]; N2] -> (N1*N2, T)
+ let (len_expr, elem_ty) = length_and_type_of_nested_array(array);
+ // generate the getter code for one array element
+ let array_elem = generate_getter_inner(&elem_ty, is_getter);
+ // either generate an array or only check each value
+ if is_getter {
+ quote! {
+ // constness: iter, array::from_fn, for-loop, range are not const, so we're using while loops
+ // Modified version of the array init example in [`MaybeUninit`]:
+ let array = {
+ // [T; N1*N2]
+ let mut array: [::core::mem::MaybeUninit<#elem_ty>; #len_expr] = unsafe {
+ ::core::mem::MaybeUninit::uninit().assume_init()
+ };
+ let mut i = 0;
+ while i < #len_expr {
+ // for every element, get its value
+ let elem_value = {
+ #array_elem
+ };
+ // and write it to the output array
+ array[i].write(elem_value);
+ i += 1;
+ }
+ // [T; N1*N2] -> [[T; N1]; N2]
+ unsafe { ::core::mem::transmute(array) }
+ };
+ array
+ }
+ } else {
+ quote! { {
+ let mut is_filled = true;
+ let mut i = 0;
+ // TODO: this could be simplified for always-filled values
+ while i < #len_expr {
+ // for every element, get its filled check
+ let elem_filled = {
+ #array_elem
+ };
+ // and join it with the others
+ is_filled = is_filled && elem_filled;
+ i += 1;
+ }
+ is_filled
+ } }
+ }
+ }
+ Path(_) => {
+ // get the size, so we can shift to the next element's offset
+ let size = shared::generate_type_bitsize(ty);
+ // get the mask, so we can get this element's value
+ let mask = generate_ty_mask(ty);
+
+ // do all steps until conversion
+ let elem_value = quote! {
+ // the element's mask
+ let mask = #mask;
+ // the cursor starts at this element's offset, now get its value
+ let raw_value = cursor & mask;
+ // after getting the value, we can shift by the element's size
+ // TODO: we could move this into tuple/array (and try_from, below)
+ let size = #size;
+ cursor = cursor.wrapping_shr(size as u32);
+ // cast the element value (e.g. u32 -> u8),
+ let raw_value: BaseIntOf<#ty> = raw_value as BaseIntOf<#ty>;
+ // which allows it to be used here (e.g. u4::new(u8))
+ let elem_value = <#ty as Bitsized>::ArbitraryInt::new(raw_value);
+ };
+
+ if is_getter {
+ // generate the real value from the arbint `elem_value`
+ quote! {
+ #elem_value
+ match #ty::try_from(elem_value) {
+ Ok(v) => v,
+ Err(_) => panic!("unreachable"),
+ }
+ }
+ } else {
+ // generate only the filled check
+ if shared::is_always_filled(ty) {
+ // skip the obviously filled values
+ quote! {
+ // we still need to shift by the element's size
+ let size = #size;
+ cursor = cursor.wrapping_shr(size as u32);
+ true
+ }
+ } else {
+ // handle structs, enums - everything which can be unfilled
+ quote! { {
+ #elem_value
+ // so, has try_from impl
+ // note this is available even if the type is `From`
+ #ty::try_from(elem_value).is_ok()
+ } }
+ }
+ }
+ }
+ _ => unreachable(()),
+ }
+}
+
+/// Top-level function which initializes the offset, masks other values and combines the final value
+///
+/// `is_array_elem_setter` allows us to generate a set_array_at setter more easily
+pub(crate) fn generate_setter_value(ty: &Type, offset: &TokenStream, is_array_elem_setter: bool) -> TokenStream {
+ // if we generate `fn set_array_at(index, value)`, we need to offset to the array element
+ let elem_offset = if is_array_elem_setter {
+ let size = shared::generate_type_bitsize(ty);
+ quote! {
+ let size = #size;
+ // offset now starts at this element
+ offset += size * index;
+ }
+ } else {
+ quote!()
+ };
+
+ let value_shifted = generate_setter_inner(ty);
+ // get the mask, so we can set this field's value
+ let mask = generate_ty_mask(ty);
+ quote! {
+ type ArbIntOf<T> = <T as Bitsized>::ArbitraryInt;
+ type BaseIntOf<T> = <ArbIntOf<T> as Number>::UnderlyingType;
+
+ // offset now starts at this field
+ let mut offset = #offset;
+ #elem_offset
+
+ let field_mask = #mask;
+ // shift the mask into place
+ let field_mask: BaseIntOf<Self> = field_mask << offset;
+ // all other fields as a mask
+ let others_mask: BaseIntOf<Self> = !field_mask;
+ // the current struct value
+ let struct_value: BaseIntOf<Self> = self.value.value();
+ // mask off the field getting set
+ let others_values: BaseIntOf<Self> = struct_value & others_mask;
+
+ // get the new field value, shifted into place
+ #value_shifted
+
+ // join the values using bit-or
+ let new_struct_value = others_values | value_shifted;
+ self.value = <ArbIntOf<Self>>::new(new_struct_value);
+ }
+}
+
+/// We heavily rely on the fact that transmuting into a nested array [[T; N1]; N2] can
+/// be done in the same way as transmuting into an array [T; N1*N2].
+/// Otherwise, nested arrays would generate even more code.
+fn generate_setter_inner(ty: &Type) -> TokenStream {
+ use Type::*;
+ match ty {
+ Tuple(tuple) => {
+ // to index into the tuple value
+ let mut tuple_index = syn::Index::from(0);
+ let value_shifted = tuple
+ .elems
+ .iter()
+ .map(|elem| {
+ let elem_name = quote!(value.#tuple_index);
+ tuple_index.index += 1;
+ // for every tuple element, generate its setter code
+ let value_shifted = generate_setter_inner(elem);
+ // set the value and add a scope around it
+ quote! { {
+ let value = #elem_name;
+ #value_shifted
+ value_shifted
+ } }
+ })
+ // join all setter codes with bit-or
+ .reduce(|acc, next| quote!(#acc | #next))
+ // `field: (),` will be handled like this:
+ .unwrap_or_else(|| quote!(0));
+ quote! {
+ let value_shifted = #value_shifted;
+ }
+ }
+ Array(array) => {
+ // [[T; N1]; N2] -> (N1*N2, T)
+ let (len_expr, elem_ty) = length_and_type_of_nested_array(array);
+ // generate the setter code for one array element
+ let value_shifted = generate_setter_inner(&elem_ty);
+ quote! {
+ // [[T; N1]; N2] -> [T; N1*N2], for example: [[(u2, u2); 3]; 4] -> [(u2, u2); 12]
+ #[allow(clippy::useless_transmute)]
+ let value: [#elem_ty; #len_expr] = unsafe { ::core::mem::transmute(value) };
+ // constness: iter, for-loop, range are not const, so we're using while loops
+ // [u4; 8] -> u32
+ let mut acc = 0;
+ let mut i = 0;
+ while i < #len_expr {
+ let value = value[i];
+ // for every element, shift its value into its place
+ #value_shifted
+ // and bit-or them together
+ acc |= value_shifted;
+ i += 1;
+ }
+ let value_shifted = acc;
+ }
+ }
+ Path(_) => {
+ // get the size, so we can reach the next element afterwards
+ let size = shared::generate_type_bitsize(ty);
+ quote! {
+ // the element's value as it's underlying type
+ let value: BaseIntOf<#ty> = <ArbIntOf<#ty>>::from(value).value();
+ // cast the element value (e.g. u8 -> u32),
+ // which allows it to be combined with the struct's value later
+ let value: BaseIntOf<Self> = value as BaseIntOf<Self>;
+ let value_shifted = value << offset;
+ // increase the offset to allow the next element to be read
+ offset += #size;
+ }
+ }
+ _ => unreachable(()),
+ }
+}
+
+/// The constructor code just needs every field setter.
+///
+/// [`super::generate_struct`] contains the initialization of `offset`.
+pub(crate) fn generate_constructor_part(ty: &Type, name: &Ident) -> TokenStream {
+ let value_shifted = generate_setter_inner(ty);
+ // setters look like this: `fn set_field1(&mut self, value: u3)`
+ // constructors like this: `fn new(field1: u3, field2: u4) -> Self`
+ // so we need to rename `field1` -> `value` and put this in a scope
+ quote! { {
+ let value = #name;
+ #value_shifted
+ value_shifted
+ } }
+}
+
+/// We mostly need this in [`generate_setter_value`], to mask the whole field.
+/// It basically combines a bunch of `Bitsized::MAX` values into a mask.
+fn generate_ty_mask(ty: &Type) -> TokenStream {
+ use Type::*;
+ match ty {
+ Tuple(tuple) => {
+ let mut previous_elem_sizes = vec![];
+ tuple
+ .elems
+ .iter()
+ .map(|elem| {
+ // for every element, generate a mask
+ let mask = generate_ty_mask(elem);
+ // get it's size
+ let elem_size = shared::generate_type_bitsize(elem);
+ // generate it's offset from all previous sizes
+ let elem_offset = previous_elem_sizes.iter().cloned().reduce(|acc, next| quote!((#acc + #next)));
+ previous_elem_sizes.push(elem_size);
+ // the first field doesn't need to be shifted
+ if let Some(elem_offset) = elem_offset {
+ quote!(#mask << #elem_offset)
+ } else {
+ quote!(#mask)
+ }
+ })
+ // join all shifted masks with bit-or
+ .reduce(|acc, next| quote!(#acc | #next))
+ // `field: (),` will be handled like this:
+ .unwrap_or_else(|| quote!(0))
+ }
+ Array(array) => {
+ let elem_ty = &array.elem;
+ let len_expr = &array.len;
+ // generate the mask for one array element
+ let mask = generate_ty_mask(elem_ty);
+ // and the size
+ let ty_size = shared::generate_type_bitsize(elem_ty);
+ quote! { {
+ let mask = #mask;
+ let mut field_mask = 0;
+ let mut i = 0;
+ while i < #len_expr {
+ // for every element, shift its mask into its place
+ // and bit-or them together
+ field_mask |= mask << (i * #ty_size);
+ i += 1;
+ }
+ field_mask
+ } }
+ }
+ Path(_) => quote! {
+ // Casting this is needed in some places, but it might not be needed in some others.
+ // (u2, u12) -> u8 << 0 | u16 << 2 -> u8 | u16 not possible
+ (<#ty as Bitsized>::MAX.value() as BaseIntOf<Self>)
+ },
+ _ => unreachable(()),
+ }
+}
+
+/// We compute nested length here, to fold [[T; N]; M] to [T; N * M].
+fn length_and_type_of_nested_array(array: &syn::TypeArray) -> (TokenStream, Type) {
+ let elem_ty = &array.elem;
+ let len_expr = &array.len;
+ if let Type::Array(array) = &**elem_ty {
+ let (child_len, child_ty) = length_and_type_of_nested_array(array);
+ (quote!((#len_expr) * (#child_len)), child_ty)
+ } else {
+ (quote!(#len_expr), *elem_ty.clone())
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/debug_bits.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/debug_bits.rs
new file mode 100644
index 0000000000..95ba9c73c1
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/debug_bits.rs
@@ -0,0 +1,55 @@
+use proc_macro2::{Ident, TokenStream};
+use proc_macro_error::abort_call_site;
+use quote::quote;
+use syn::{Data, Fields};
+
+use crate::shared::{self, unreachable};
+
+pub(super) fn debug_bits(item: TokenStream) -> TokenStream {
+ let derive_input = shared::parse_derive(item);
+ let name = &derive_input.ident;
+ let name_str = name.to_string();
+ let mut fieldless_next_int = 0;
+ let struct_data = match derive_input.data {
+ Data::Struct(s) => s,
+ Data::Enum(_) => abort_call_site!("use derive(Debug) for enums"),
+ Data::Union(_) => unreachable(()),
+ };
+
+ let fmt_impl = match struct_data.fields {
+ Fields::Named(fields) => {
+ let calls = fields.named.iter().map(|f| {
+ // We can unwrap since this is a named field
+ let call = f.ident.as_ref().unwrap();
+ let name = call.to_string();
+ quote!(.field(#name, &self.#call()))
+ });
+ quote! {
+ f.debug_struct(#name_str)
+ // .field("field1", &self.field1()).field("field2", &self.field2()).field("field3", &self.field3()).finish()
+ #(#calls)*.finish()
+ }
+ }
+ Fields::Unnamed(fields) => {
+ let calls = fields.unnamed.iter().map(|_| {
+ let call: Ident = syn::parse_str(&format!("val_{}", fieldless_next_int)).unwrap_or_else(unreachable);
+ fieldless_next_int += 1;
+ quote!(.field(&self.#call()))
+ });
+ quote! {
+ f.debug_tuple(#name_str)
+ // .field(&self.val0()).field(&self.val1()).finish()
+ #(#calls)*.finish()
+ }
+ }
+ Fields::Unit => todo!("this is a unit struct, which is not supported right now"),
+ };
+
+ quote! {
+ impl ::core::fmt::Debug for #name {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+ #fmt_impl
+ }
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/default_bits.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/default_bits.rs
new file mode 100644
index 0000000000..f664accf36
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/default_bits.rs
@@ -0,0 +1,92 @@
+use proc_macro2::{Ident, TokenStream};
+use proc_macro_error::abort_call_site;
+use quote::quote;
+use syn::{Data, DeriveInput, Fields, Type};
+
+use crate::shared::{self, fallback::Fallback, unreachable, BitSize};
+
+pub(crate) fn default_bits(item: TokenStream) -> TokenStream {
+ let derive_input = parse(item);
+ //TODO: does fallback need handling?
+ let (derive_data, _, name, ..) = analyze(&derive_input);
+
+ match derive_data {
+ Data::Struct(data) => generate_struct_default_impl(name, &data.fields),
+ Data::Enum(_) => abort_call_site!("use derive(Default) for enums"),
+ _ => unreachable(()),
+ }
+}
+
+fn generate_struct_default_impl(struct_name: &Ident, fields: &Fields) -> TokenStream {
+ let default_value = fields
+ .iter()
+ .map(|field| generate_default_inner(&field.ty))
+ .reduce(|acc, next| quote!(#acc | #next));
+
+ quote! {
+ impl ::core::default::Default for #struct_name {
+ fn default() -> Self {
+ let mut offset = 0;
+ let value = #default_value;
+ let value = <#struct_name as Bitsized>::ArbitraryInt::new(value);
+ Self { value }
+ }
+ }
+ }
+}
+
+fn generate_default_inner(ty: &Type) -> TokenStream {
+ use Type::*;
+ match ty {
+ // TODO?: we could optimize nested arrays here like in `struct_gen.rs`
+ // NOTE: in std, Default is only derived for arrays with up to 32 elements, but we allow more
+ Array(array) => {
+ let len_expr = &array.len;
+ let elem_ty = &*array.elem;
+ // generate the default value code for one array element
+ let value_shifted = generate_default_inner(elem_ty);
+ quote! {{
+ // constness: iter, array::from_fn, for-loop, range are not const, so we're using while loops
+ let mut acc = 0;
+ let mut i = 0;
+ while i < #len_expr {
+ // for every element, shift its value into its place
+ let value_shifted = #value_shifted;
+ // and bit-or them together
+ acc |= value_shifted;
+ i += 1;
+ }
+ acc
+ }}
+ }
+ Path(path) => {
+ let field_size = shared::generate_type_bitsize(ty);
+ // u2::from(HaveFun::default()).value() as u32;
+ quote! {{
+ let as_int = <#path as Bitsized>::ArbitraryInt::from(<#path as ::core::default::Default>::default()).value();
+ let as_base_int = as_int as <<Self as Bitsized>::ArbitraryInt as Number>::UnderlyingType;
+ let shifted = as_base_int << offset;
+ offset += #field_size;
+ shifted
+ }}
+ }
+ Tuple(tuple) => {
+ tuple
+ .elems
+ .iter()
+ .map(generate_default_inner)
+ .reduce(|acc, next| quote!(#acc | #next))
+ // `field: (),` will be handled like this:
+ .unwrap_or_else(|| quote!(0))
+ }
+ _ => unreachable(()),
+ }
+}
+
+fn parse(item: TokenStream) -> DeriveInput {
+ shared::parse_derive(item)
+}
+
+fn analyze(derive_input: &DeriveInput) -> (&Data, TokenStream, &Ident, BitSize, Option<Fallback>) {
+ shared::analyze_derive(derive_input, false)
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/fmt_bits.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/fmt_bits.rs
new file mode 100644
index 0000000000..527691ed65
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/fmt_bits.rs
@@ -0,0 +1,112 @@
+use proc_macro2::{Ident, TokenStream};
+use quote::quote;
+use syn::{punctuated::Iter, Data, DeriveInput, Fields, Variant};
+
+use crate::shared::{self, discriminant_assigner::DiscriminantAssigner, fallback::Fallback, unreachable, BitSize};
+
+pub(crate) fn binary(item: TokenStream) -> TokenStream {
+ let derive_input = parse(item);
+ let (derive_data, arb_int, name, bitsize, fallback) = analyze(&derive_input);
+
+ match derive_data {
+ Data::Struct(data) => generate_struct_binary_impl(name, &data.fields),
+ Data::Enum(data) => generate_enum_binary_impl(name, data.variants.iter(), arb_int, bitsize, fallback),
+ _ => unreachable(()),
+ }
+}
+
+fn generate_struct_binary_impl(struct_name: &Ident, fields: &Fields) -> TokenStream {
+ let write_underscore = quote! { write!(f, "_")?; };
+
+ // fields are printed from most significant to least significant, separated by an underscore
+ let writes = fields
+ .iter()
+ .rev()
+ .map(|field| {
+ let field_size = shared::generate_type_bitsize(&field.ty);
+
+ // `extracted` is `field_size` bits of `value`, starting from index `first_bit_pos` (counting from LSB)
+ quote! {
+ let field_size = #field_size;
+ let field_mask = mask >> (struct_size - field_size);
+ let first_bit_pos = last_bit_pos - field_size;
+ last_bit_pos -= field_size;
+ let extracted = field_mask & (self.value >> first_bit_pos);
+ write!(f, "{:0width$b}", extracted, width = field_size)?;
+ }
+ })
+ .reduce(|acc, next| quote!(#acc #write_underscore #next));
+
+ quote! {
+ impl ::core::fmt::Binary for #struct_name {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ let struct_size = <#struct_name as Bitsized>::BITS;
+ let mut last_bit_pos = struct_size;
+ let mask = <#struct_name as Bitsized>::MAX;
+ #writes
+ Ok(())
+ }
+ }
+ }
+}
+
+fn generate_enum_binary_impl(
+ enum_name: &Ident, variants: Iter<Variant>, arb_int: TokenStream, bitsize: BitSize, fallback: Option<Fallback>,
+) -> TokenStream {
+ let to_int_match_arms = generate_to_int_match_arms(variants, enum_name, bitsize, arb_int, fallback);
+
+ let body = if to_int_match_arms.is_empty() {
+ quote! { Ok(()) }
+ } else {
+ quote! {
+ let value = match self {
+ #( #to_int_match_arms )*
+ };
+ write!(f, "{:0width$b}", value, width = <#enum_name as Bitsized>::BITS)
+ }
+ };
+
+ quote! {
+ impl ::core::fmt::Binary for #enum_name {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ #body
+ }
+ }
+ }
+}
+
+/// generates the arms for an (infallible) conversion from an enum to the enum's underlying arbitrary_int
+fn generate_to_int_match_arms(
+ variants: Iter<Variant>, enum_name: &Ident, bitsize: BitSize, arb_int: TokenStream, fallback: Option<Fallback>,
+) -> Vec<TokenStream> {
+ let is_value_fallback = |variant_name| {
+ if let Some(Fallback::WithValue(name)) = &fallback {
+ variant_name == name
+ } else {
+ false
+ }
+ };
+
+ let mut assigner = DiscriminantAssigner::new(bitsize);
+
+ variants
+ .map(|variant| {
+ let variant_name = &variant.ident;
+ let variant_value = assigner.assign_unsuffixed(variant);
+
+ if is_value_fallback(variant_name) {
+ quote! { #enum_name::#variant_name(number) => *number, }
+ } else {
+ shared::to_int_match_arm(enum_name, variant_name, &arb_int, variant_value)
+ }
+ })
+ .collect()
+}
+
+fn parse(item: TokenStream) -> DeriveInput {
+ shared::parse_derive(item)
+}
+
+fn analyze(derive_input: &DeriveInput) -> (&Data, TokenStream, &Ident, BitSize, Option<Fallback>) {
+ shared::analyze_derive(derive_input, false)
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/from_bits.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/from_bits.rs
new file mode 100644
index 0000000000..e58b921521
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/from_bits.rs
@@ -0,0 +1,222 @@
+use itertools::Itertools;
+use proc_macro2::{Ident, TokenStream};
+use proc_macro_error::{abort, abort_call_site};
+use quote::quote;
+use syn::{punctuated::Iter, Data, DeriveInput, Fields, Type, Variant};
+
+use crate::shared::{
+ self, discriminant_assigner::DiscriminantAssigner, enum_fills_bitsize, fallback::Fallback,
+ unreachable, BitSize,
+};
+
+pub(super) fn from_bits(item: TokenStream) -> TokenStream {
+ let derive_input = parse(item);
+ let (derive_data, arb_int, name, internal_bitsize, fallback) = analyze(&derive_input);
+ let expanded = match &derive_data {
+ Data::Struct(struct_data) => generate_struct(arb_int, name, &struct_data.fields),
+ Data::Enum(enum_data) => {
+ let variants = enum_data.variants.iter();
+ let match_arms = analyze_enum(
+ variants,
+ name,
+ internal_bitsize,
+ fallback.as_ref(),
+ &arb_int,
+ );
+ generate_enum(arb_int, name, match_arms, fallback)
+ }
+ _ => unreachable(()),
+ };
+ generate_common(expanded)
+}
+
+fn parse(item: TokenStream) -> DeriveInput {
+ shared::parse_derive(item)
+}
+
+fn analyze(
+ derive_input: &DeriveInput,
+) -> (&syn::Data, TokenStream, &Ident, BitSize, Option<Fallback>) {
+ shared::analyze_derive(derive_input, false)
+}
+
+fn analyze_enum(
+ variants: Iter<Variant>,
+ name: &Ident,
+ internal_bitsize: BitSize,
+ fallback: Option<&Fallback>,
+ arb_int: &TokenStream,
+) -> (Vec<TokenStream>, Vec<TokenStream>) {
+ validate_enum_variants(variants.clone(), fallback);
+
+ let enum_is_filled = enum_fills_bitsize(internal_bitsize, variants.len());
+ if !enum_is_filled && fallback.is_none() {
+ abort_call_site!("enum doesn't fill its bitsize"; help = "you need to use `#[derive(TryFromBits)]` instead, or specify one of the variants as #[fallback]")
+ }
+ if enum_is_filled && fallback.is_some() {
+ // NOTE: I've shortly tried pointing to `#[fallback]` here but it wasn't easy enough
+ abort_call_site!("enum already has {} variants", variants.len(); help = "remove the `#[fallback]` attribute")
+ }
+
+ let mut assigner = DiscriminantAssigner::new(internal_bitsize);
+
+ let is_fallback = |variant_name| {
+ if let Some(Fallback::Unit(name) | Fallback::WithValue(name)) = fallback {
+ variant_name == name
+ } else {
+ false
+ }
+ };
+
+ let is_value_fallback = |variant_name| {
+ if let Some(Fallback::WithValue(name)) = fallback {
+ variant_name == name
+ } else {
+ false
+ }
+ };
+
+ variants
+ .map(|variant| {
+ let variant_name = &variant.ident;
+ let variant_value = assigner.assign_unsuffixed(variant);
+
+ let from_int_match_arm = if is_fallback(variant_name) {
+ // this value will be handled by the catch-all arm
+ quote!()
+ } else {
+ quote! { #variant_value => Self::#variant_name, }
+ };
+
+ let to_int_match_arm = if is_value_fallback(variant_name) {
+ quote! { #name::#variant_name(number) => number, }
+ } else {
+ shared::to_int_match_arm(name, variant_name, arb_int, variant_value)
+ };
+
+ (from_int_match_arm, to_int_match_arm)
+ })
+ .unzip()
+}
+
+fn generate_enum(
+ arb_int: TokenStream,
+ enum_type: &Ident,
+ match_arms: (Vec<TokenStream>, Vec<TokenStream>),
+ fallback: Option<Fallback>,
+) -> TokenStream {
+ let (from_int_match_arms, to_int_match_arms) = match_arms;
+
+ let const_ = if cfg!(feature = "nightly") {
+ quote!(const)
+ } else {
+ quote!()
+ };
+
+ let from_enum_impl =
+ shared::generate_from_enum_impl(&arb_int, enum_type, to_int_match_arms, &const_);
+
+ let catch_all_arm = match fallback {
+ Some(Fallback::WithValue(fallback_ident)) => quote! {
+ _ => Self::#fallback_ident(number),
+ },
+ Some(Fallback::Unit(fallback_ident)) => quote! {
+ _ => Self::#fallback_ident,
+ },
+ None => quote! {
+ // constness: unreachable!() is not const yet
+ _ => ::core::panic!("unreachable: arbitrary_int already validates that this is unreachable")
+ },
+ };
+
+ quote! {
+ impl #const_ ::core::convert::From<#arb_int> for #enum_type {
+ fn from(number: #arb_int) -> Self {
+ match number.value() {
+ #( #from_int_match_arms )*
+ #catch_all_arm
+ }
+ }
+ }
+ #from_enum_impl
+ }
+}
+
+/// a type is considered "filled" if it implements `Bitsized` with `BITS == N`,
+/// and additionally is allowed to have any unsigned value from `0` to `2^N - 1`.
+/// such a type can then safely implement `From<uN>`.
+/// a filled type automatically implements the trait `Filled` thanks to a blanket impl.
+/// the check generated by this function will prevent compilation if `ty` is not `Filled`.
+fn generate_filled_check_for(ty: &Type, vec: &mut Vec<TokenStream>) {
+ use Type::*;
+ match ty {
+ Path(_) => {
+ let assume = quote! { ::bilge::assume_filled::<#ty>(); };
+ vec.push(assume);
+ }
+ Tuple(tuple) => {
+ for elem in &tuple.elems {
+ generate_filled_check_for(elem, vec)
+ }
+ }
+ Array(array) => generate_filled_check_for(&array.elem, vec),
+ _ => unreachable(()),
+ }
+}
+
+fn generate_struct(arb_int: TokenStream, struct_type: &Ident, fields: &Fields) -> TokenStream {
+ let const_ = if cfg!(feature = "nightly") {
+ quote!(const)
+ } else {
+ quote!()
+ };
+
+ let mut assumes = Vec::new();
+ for field in fields {
+ generate_filled_check_for(&field.ty, &mut assumes)
+ }
+
+ // a single check per type is enough, so the checks can be deduped
+ let assumes = assumes.into_iter().unique_by(TokenStream::to_string);
+
+ quote! {
+ impl #const_ ::core::convert::From<#arb_int> for #struct_type {
+ fn from(value: #arb_int) -> Self {
+ #( #assumes )*
+ Self { value }
+ }
+ }
+ impl #const_ ::core::convert::From<#struct_type> for #arb_int {
+ fn from(value: #struct_type) -> Self {
+ value.value
+ }
+ }
+ }
+}
+
+fn generate_common(expanded: TokenStream) -> TokenStream {
+ quote! {
+ #expanded
+ }
+}
+
+fn validate_enum_variants(variants: Iter<Variant>, fallback: Option<&Fallback>) {
+ for variant in variants {
+ // we've already validated the correctness of the fallback variant, and that there's at most one such variant.
+ // this means we can safely skip a fallback variant if we find one.
+ if let Some(fallback) = &fallback {
+ if fallback.is_fallback_variant(&variant.ident) {
+ continue;
+ }
+ }
+
+ if !matches!(variant.fields, Fields::Unit) {
+ let help_message = if fallback.is_some() {
+ "change this variant to a unit"
+ } else {
+ "add a fallback variant or change this variant to a unit"
+ };
+ abort!(variant, "FromBits only supports unit variants for variants without `#[fallback]`"; help = help_message);
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/lib.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/lib.rs
new file mode 100644
index 0000000000..4b34b4f306
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/lib.rs
@@ -0,0 +1,79 @@
+extern crate itertools;
+extern crate proc_macro_error;
+extern crate proc_macro_error_attr;
+use proc_macro::TokenStream;
+use proc_macro_error::proc_macro_error;
+
+mod bitsize;
+mod bitsize_internal;
+mod debug_bits;
+mod default_bits;
+mod fmt_bits;
+mod from_bits;
+mod try_from_bits;
+
+mod shared;
+
+/// Defines the bitsize of a struct or an enum.
+///
+/// e.g. `#[bitsize(4)]` represents the item as a u4, which is UInt<u8, 4> underneath.
+/// The size of structs is currently limited to 128 bits.
+/// The size of enums is limited to 64 bits.
+/// Please open an issue if you have a usecase for bigger bitfields.
+#[proc_macro_error]
+#[proc_macro_attribute]
+pub fn bitsize(args: TokenStream, item: TokenStream) -> TokenStream {
+ bitsize::bitsize(args.into(), item.into()).into()
+}
+
+/// This is internally used, not to be used by anything besides `bitsize`.
+/// No guarantees are given.
+#[proc_macro_error]
+#[proc_macro_attribute]
+pub fn bitsize_internal(args: TokenStream, item: TokenStream) -> TokenStream {
+ bitsize_internal::bitsize_internal(args.into(), item.into()).into()
+}
+
+/// Generate an `impl TryFrom<uN>` for unfilled bitfields.
+///
+/// This should be used when your enum or enums nested in
+/// a struct don't fill their given `bitsize`.
+#[proc_macro_error]
+#[proc_macro_derive(TryFromBits, attributes(bitsize_internal, fallback))]
+pub fn derive_try_from_bits(item: TokenStream) -> TokenStream {
+ try_from_bits::try_from_bits(item.into()).into()
+}
+
+/// Generate an `impl From<uN>` for filled bitfields.
+///
+/// This should be used when your enum or enums nested in
+/// a struct fill their given `bitsize` or if you're not
+/// using enums.
+#[proc_macro_error]
+#[proc_macro_derive(FromBits, attributes(bitsize_internal, fallback))]
+pub fn derive_from_bits(item: TokenStream) -> TokenStream {
+ from_bits::from_bits(item.into()).into()
+}
+
+/// Generate an `impl core::fmt::Debug` for bitfield structs.
+///
+/// Please use normal #[derive(Debug)] for enums.
+#[proc_macro_error]
+#[proc_macro_derive(DebugBits, attributes(bitsize_internal))]
+pub fn debug_bits(item: TokenStream) -> TokenStream {
+ debug_bits::debug_bits(item.into()).into()
+}
+
+/// Generate an `impl core::fmt::Binary` for bitfields.
+#[proc_macro_error]
+#[proc_macro_derive(BinaryBits)]
+pub fn derive_binary_bits(item: TokenStream) -> TokenStream {
+ fmt_bits::binary(item.into()).into()
+}
+
+/// Generate an `impl core::default::Default` for bitfield structs.
+#[proc_macro_error]
+#[proc_macro_derive(DefaultBits)]
+pub fn derive_default_bits(item: TokenStream) -> TokenStream {
+ default_bits::default_bits(item.into()).into()
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/shared.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/shared.rs
new file mode 100644
index 0000000000..2e54e0d787
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/shared.rs
@@ -0,0 +1,196 @@
+pub mod discriminant_assigner;
+pub mod fallback;
+pub mod util;
+
+use fallback::{fallback_variant, Fallback};
+use proc_macro2::{Ident, Literal, TokenStream};
+use proc_macro_error::{abort, abort_call_site};
+use quote::quote;
+use syn::{Attribute, DeriveInput, LitInt, Meta, Type};
+use util::PathExt;
+
+/// As arbitrary_int is limited to basic rust primitives, the maximum is u128.
+/// Is there a true usecase for bitfields above this size?
+/// This would also be change-worthy when rust starts supporting LLVM's arbitrary integers.
+pub const MAX_STRUCT_BIT_SIZE: BitSize = 128;
+/// As `#[repr(u128)]` is unstable and currently no real usecase for higher sizes exists, the maximum is u64.
+pub const MAX_ENUM_BIT_SIZE: BitSize = 64;
+pub type BitSize = u8;
+
+pub(crate) fn parse_derive(item: TokenStream) -> DeriveInput {
+ syn::parse2(item).unwrap_or_else(unreachable)
+}
+
+// allow since we want `if try_from` blocks to stand out
+#[allow(clippy::collapsible_if)]
+pub(crate) fn analyze_derive(derive_input: &DeriveInput, try_from: bool) -> (&syn::Data, TokenStream, &Ident, BitSize, Option<Fallback>) {
+ let DeriveInput {
+ attrs,
+ ident,
+ // generics,
+ data,
+ ..
+ } = derive_input;
+
+ if !try_from {
+ if attrs.iter().any(is_non_exhaustive_attribute) {
+ abort_call_site!("Item can't be FromBits and non_exhaustive"; help = "remove #[non_exhaustive] or derive(FromBits) here")
+ }
+ } else {
+ // currently not allowed, would need some thinking:
+ if let syn::Data::Struct(_) = data {
+ if attrs.iter().any(is_non_exhaustive_attribute) {
+ abort_call_site!("Using #[non_exhaustive] on structs is currently not supported"; help = "open an issue on our repository if needed")
+ }
+ }
+ }
+
+ // parsing the #[bitsize_internal(num)] attribute macro
+ let args = attrs
+ .iter()
+ .find_map(bitsize_internal_arg)
+ .unwrap_or_else(|| abort_call_site!("add #[bitsize] attribute above your derive attribute"));
+ let (bitsize, arb_int) = bitsize_and_arbitrary_int_from(args);
+
+ let fallback = fallback_variant(data, bitsize);
+ if fallback.is_some() && try_from {
+ abort_call_site!("fallback is not allowed with `TryFromBits`"; help = "use `#[derive(FromBits)]` or remove this `#[fallback]`")
+ }
+
+ (data, arb_int, ident, bitsize, fallback)
+}
+
+// If we want to support bitsize(u4) besides bitsize(4), do that here.
+pub fn bitsize_and_arbitrary_int_from(bitsize_arg: TokenStream) -> (BitSize, TokenStream) {
+ let bitsize: LitInt = syn::parse2(bitsize_arg.clone())
+ .unwrap_or_else(|_| abort!(bitsize_arg, "attribute value is not a number"; help = "you need to define the size like this: `#[bitsize(32)]`"));
+ // without postfix
+ let bitsize = bitsize
+ .base10_parse()
+ .ok()
+ .filter(|&n| n != 0 && n <= MAX_STRUCT_BIT_SIZE)
+ .unwrap_or_else(|| abort!(bitsize_arg, "attribute value is not a valid number"; help = "currently, numbers from 1 to {} are allowed", MAX_STRUCT_BIT_SIZE));
+ let arb_int = syn::parse_str(&format!("u{bitsize}")).unwrap_or_else(unreachable);
+ (bitsize, arb_int)
+}
+
+pub fn generate_type_bitsize(ty: &Type) -> TokenStream {
+ use Type::*;
+ match ty {
+ Tuple(tuple) => {
+ tuple
+ .elems
+ .iter()
+ .map(generate_type_bitsize)
+ .reduce(|acc, next| quote!((#acc + #next)))
+ // `field: (),` will be handled like this:
+ .unwrap_or_else(|| quote!(0))
+ }
+ Array(array) => {
+ let elem_bitsize = generate_type_bitsize(&array.elem);
+ let len_expr = &array.len;
+ quote!((#elem_bitsize * #len_expr))
+ }
+ Path(_) => {
+ quote!(<#ty as Bitsized>::BITS)
+ }
+ _ => unreachable(()),
+ }
+}
+
+pub(crate) fn generate_from_enum_impl(
+ arb_int: &TokenStream, enum_type: &Ident, to_int_match_arms: Vec<TokenStream>, const_: &TokenStream,
+) -> TokenStream {
+ quote! {
+ impl #const_ ::core::convert::From<#enum_type> for #arb_int {
+ fn from(enum_value: #enum_type) -> Self {
+ match enum_value {
+ #( #to_int_match_arms )*
+ }
+ }
+ }
+ }
+}
+
+/// Filters fields which are always `FILLED`, meaning all bit-patterns are possible,
+/// meaning they are (should be) From<uN>, not TryFrom<uN>
+///
+/// Currently, this is exactly the set of types we can extract a bitsize out of, just by looking at their ident: `uN` and `bool`.
+pub fn is_always_filled(ty: &Type) -> bool {
+ last_ident_of_path(ty).and_then(bitsize_from_type_ident).is_some()
+}
+
+pub fn last_ident_of_path(ty: &Type) -> Option<&Ident> {
+ if let Type::Path(type_path) = ty {
+ // the type may have a qualified path, so I don't think we can use `get_ident()` here
+ let last_segment = type_path.path.segments.last()?;
+ Some(&last_segment.ident)
+ } else {
+ None
+ }
+}
+
+/// in enums, internal_bitsize <= 64; u64::MAX + 1 = u128
+/// therefore the bitshift would not overflow.
+pub fn enum_fills_bitsize(bitsize: u8, variants_count: usize) -> bool {
+ let max_variants_count = 1u128 << bitsize;
+ if variants_count as u128 > max_variants_count {
+ abort_call_site!("enum overflows its bitsize"; help = "there should only be at most {} variants defined", max_variants_count);
+ }
+ variants_count as u128 == max_variants_count
+}
+
+#[inline]
+pub fn unreachable<T, U>(_: T) -> U {
+ unreachable!("should have already been validated")
+}
+
+pub fn is_attribute(attr: &Attribute, name: &str) -> bool {
+ if let Meta::Path(path) = &attr.meta {
+ path.is_ident(name)
+ } else {
+ false
+ }
+}
+
+fn is_non_exhaustive_attribute(attr: &Attribute) -> bool {
+ is_attribute(attr, "non_exhaustive")
+}
+
+pub(crate) fn is_fallback_attribute(attr: &Attribute) -> bool {
+ is_attribute(attr, "fallback")
+}
+
+/// attempts to extract the bitsize from an ident equal to `uN` or `bool`.
+/// should return `Result` instead of `Option`, if we decide to add more descriptive error handling.
+pub fn bitsize_from_type_ident(type_name: &Ident) -> Option<BitSize> {
+ let type_name = type_name.to_string();
+
+ if type_name == "bool" {
+ Some(1)
+ } else if let Some(suffix) = type_name.strip_prefix('u') {
+ // characters which may appear in this suffix are digits, letters and underscores.
+ // parse() will reject letters and underscores, so this should be correct.
+ let bitsize = suffix.parse().ok();
+
+ // the namespace contains u2 up to u{MAX_STRUCT_BIT_SIZE}. can't make assumptions about larger values
+ bitsize.filter(|&n| n <= MAX_STRUCT_BIT_SIZE)
+ } else {
+ None
+ }
+}
+
+pub fn to_int_match_arm(enum_name: &Ident, variant_name: &Ident, arb_int: &TokenStream, variant_value: Literal) -> TokenStream {
+ quote! { #enum_name::#variant_name => #arb_int::new(#variant_value), }
+}
+
+pub(crate) fn bitsize_internal_arg(attr: &Attribute) -> Option<TokenStream> {
+ if let Meta::List(list) = &attr.meta {
+ if list.path.matches(&["bilge", "bitsize_internal"]) {
+ let arg = list.tokens.to_owned();
+ return Some(arg);
+ }
+ }
+
+ None
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/shared/discriminant_assigner.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/shared/discriminant_assigner.rs
new file mode 100644
index 0000000000..5825baa4f1
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/shared/discriminant_assigner.rs
@@ -0,0 +1,56 @@
+use proc_macro2::Literal;
+use proc_macro_error::abort;
+use syn::{Expr, ExprLit, Lit, Variant};
+
+use super::{unreachable, BitSize};
+
+pub(crate) struct DiscriminantAssigner {
+ bitsize: BitSize,
+ next_expected_assignment: u128,
+}
+
+impl DiscriminantAssigner {
+ pub fn new(bitsize: u8) -> DiscriminantAssigner {
+ DiscriminantAssigner {
+ bitsize,
+ next_expected_assignment: 0,
+ }
+ }
+
+ fn max_value(&self) -> u128 {
+ (1u128 << self.bitsize) - 1
+ }
+
+ fn value_from_discriminant(&self, variant: &Variant) -> Option<u128> {
+ let discriminant = variant.discriminant.as_ref()?;
+ let discriminant_expr = &discriminant.1;
+ let variant_name = &variant.ident;
+
+ let Expr::Lit(ExprLit { lit: Lit::Int(int), .. }) = discriminant_expr else {
+ abort!(
+ discriminant_expr,
+ "variant `{}` is not a number", variant_name;
+ help = "only literal integers currently supported"
+ )
+ };
+
+ let discriminant_value: u128 = int.base10_parse().unwrap_or_else(unreachable);
+ if discriminant_value > self.max_value() {
+ abort!(variant, "Value of variant exceeds the given number of bits")
+ }
+
+ Some(discriminant_value)
+ }
+
+ fn assign(&mut self, variant: &Variant) -> u128 {
+ let value = self.value_from_discriminant(variant).unwrap_or(self.next_expected_assignment);
+ self.next_expected_assignment = value + 1;
+ value
+ }
+
+ /// syn adds a suffix when printing Rust integers. we use an unsuffixed `Literal` for better-looking codegen
+ pub fn assign_unsuffixed(&mut self, variant: &Variant) -> Literal {
+ let next = self.assign(variant);
+ Literal::u128_unsuffixed(next)
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/shared/fallback.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/shared/fallback.rs
new file mode 100644
index 0000000000..893919659e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/shared/fallback.rs
@@ -0,0 +1,92 @@
+use itertools::Itertools;
+use proc_macro2::Ident;
+use proc_macro_error::{abort, abort_call_site};
+use syn::{Data, Variant};
+
+use super::{bitsize_from_type_ident, is_fallback_attribute, last_ident_of_path, unreachable, BitSize};
+
+pub enum Fallback {
+ Unit(Ident),
+ WithValue(Ident),
+}
+
+impl Fallback {
+ fn from_variant(variant: &Variant, enum_bitsize: BitSize, is_last_variant: bool) -> Fallback {
+ use syn::Fields::*;
+
+ let ident = variant.ident.to_owned();
+
+ match &variant.fields {
+ Named(_) => {
+ abort!(variant, "`#[fallback]` does not support variants with named fields"; help = "use a tuple variant or remove this `#[fallback]`")
+ }
+ Unnamed(fields) => {
+ let variant_fields = fields.unnamed.iter();
+ let Ok(fallback_value) = variant_fields.exactly_one() else {
+ abort!(variant, "fallback variant must have exactly one field"; help = "use only one field or change to a unit variant")
+ };
+
+ if !is_last_variant {
+ abort!(variant, "value fallback is not the last variant"; help = "a fallback variant with value must be the last variant of the enum")
+ }
+
+ // here we validate that the fallback variant field type matches the bitsize
+ let size_from_type = last_ident_of_path(&fallback_value.ty).and_then(bitsize_from_type_ident);
+
+ match size_from_type {
+ Some(bitsize) if bitsize == enum_bitsize => Fallback::WithValue(ident),
+ Some(bitsize) => abort!(
+ variant.fields,
+ "bitsize of fallback field ({}) does not match bitsize of enum ({})",
+ bitsize,
+ enum_bitsize
+ ),
+ None => abort!(variant.fields, "`#[fallback]` only supports arbitrary_int or bool types"),
+ }
+ }
+ Unit => Fallback::Unit(ident),
+ }
+ }
+
+ pub fn is_fallback_variant(&self, variant_ident: &Ident) -> bool {
+ matches!(self, Fallback::Unit(fallback_ident) | Fallback::WithValue(fallback_ident) if variant_ident == fallback_ident)
+ }
+}
+
+/// finds a single enum variant with the attribute "fallback".
+/// a "fallback variant" may come in one of two forms:
+/// 1. `#[fallback] Foo`, which we map to `Fallback::Unit`
+/// 2. `#[fallback] Foo(uN)`, where `N` is the enum's bitsize and `Foo` is the enum's last variant,
+/// which we map to `Fallback::WithValue`
+pub fn fallback_variant(data: &Data, enum_bitsize: BitSize) -> Option<Fallback> {
+ match data {
+ Data::Enum(enum_data) => {
+ let variants_with_fallback = enum_data
+ .variants
+ .iter()
+ .filter(|variant| variant.attrs.iter().any(is_fallback_attribute));
+
+ match variants_with_fallback.at_most_one() {
+ Ok(None) => None,
+ Ok(Some(variant)) => {
+ let is_last_variant = variant.ident == enum_data.variants.last().unwrap().ident;
+ let fallback = Fallback::from_variant(variant, enum_bitsize, is_last_variant);
+ Some(fallback)
+ }
+ Err(_) => {
+ abort_call_site!("only one enum variant may be `#[fallback]`"; help = "remove #[fallback] attributes until you only have one")
+ }
+ }
+ }
+ Data::Struct(struct_data) => {
+ let mut field_attrs = struct_data.fields.iter().flat_map(|field| &field.attrs);
+
+ if field_attrs.any(is_fallback_attribute) {
+ abort_call_site!("`#[fallback]` is only applicable to enums"; help = "remove all `#[fallback]` from this struct")
+ } else {
+ None
+ }
+ }
+ _ => unreachable(()),
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/shared/util.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/shared/util.rs
new file mode 100644
index 0000000000..31a9be1f2a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/shared/util.rs
@@ -0,0 +1,91 @@
+use syn::Path;
+#[cfg(test)]
+use syn_path::path;
+
+pub trait PathExt {
+ /// match path segments. `str_segments` should contain the entire
+ /// qualified path from the crate root, for example `["bilge", "FromBits"]`.
+ /// allows partial matches - `["std", "default", "Default"]` will also match
+ /// the paths `Default` or `default::Default`.
+ fn matches(&self, str_segments: &[&str]) -> bool;
+
+ /// match path segments, but also allow first segment to be either "core" or "std"
+ fn matches_core_or_std(&self, str_segments: &[&str]) -> bool {
+ let mut str_segments = str_segments.to_owned();
+
+ // try matching with "std" as first segment
+ // first, make "std" the first segment
+ match str_segments.first().copied() {
+ None => return false, // since path is non-empty, this is trivially false
+ Some("std") => (),
+ _ => str_segments.insert(0, "std"),
+ };
+
+ if self.matches(&str_segments) {
+ return true;
+ }
+
+ // try matching with "core" as first segment
+ str_segments[0] = "core";
+ self.matches(&str_segments)
+ }
+}
+
+impl PathExt for Path {
+ fn matches(&self, str_segments: &[&str]) -> bool {
+ if self.segments.len() > str_segments.len() {
+ return false;
+ }
+
+ let segments = self.segments.iter().map(|seg| seg.ident.to_string()).rev();
+ let str_segments = str_segments.iter().copied().rev();
+
+ segments.zip(str_segments).all(|(a, b)| a == b)
+ }
+}
+
+#[test]
+fn path_matching() {
+ let paths = [
+ path!(::std::default::Default),
+ path!(std::default::Default),
+ path!(default::Default),
+ path!(Default),
+ ];
+
+ let str_segments = &["std", "default", "Default"];
+
+ for path in paths {
+ assert!(path.matches(str_segments));
+ }
+}
+
+#[test]
+fn partial_does_not_match() {
+ let full_path = path!(std::foo::bar::fizz::Buzz);
+
+ let str_segments = ["std", "foo", "bar", "fizz", "Buzz"];
+
+ for i in 1..str_segments.len() {
+ let partial_str_segments = &str_segments[i..];
+ assert!(!full_path.matches(partial_str_segments))
+ }
+}
+
+#[test]
+fn path_matching_without_root() {
+ let paths = [
+ path!(::core::fmt::Debug),
+ path!(core::fmt::Debug),
+ path!(::std::fmt::Debug),
+ path!(std::fmt::Debug),
+ path!(fmt::Debug),
+ path!(Debug),
+ ];
+
+ let str_segments_without_root = &["fmt", "Debug"];
+
+ for path in paths {
+ assert!(path.matches_core_or_std(str_segments_without_root));
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/bilge-impl/src/try_from_bits.rs b/rust/hw/char/pl011/vendor/bilge-impl/src/try_from_bits.rs
new file mode 100644
index 0000000000..b27a5567c5
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge-impl/src/try_from_bits.rs
@@ -0,0 +1,143 @@
+use proc_macro2::{Ident, TokenStream};
+use proc_macro_error::{abort, emit_call_site_warning};
+use quote::quote;
+use syn::{punctuated::Iter, Data, DeriveInput, Fields, Type, Variant};
+
+use crate::shared::{self, discriminant_assigner::DiscriminantAssigner, enum_fills_bitsize, fallback::Fallback, unreachable, BitSize};
+use crate::shared::{bitsize_from_type_ident, last_ident_of_path};
+
+pub(super) fn try_from_bits(item: TokenStream) -> TokenStream {
+ let derive_input = parse(item);
+ let (derive_data, arb_int, name, internal_bitsize, ..) = analyze(&derive_input);
+ match derive_data {
+ Data::Struct(ref data) => codegen_struct(arb_int, name, &data.fields),
+ Data::Enum(ref enum_data) => {
+ let variants = enum_data.variants.iter();
+ let match_arms = analyze_enum(variants, name, internal_bitsize, &arb_int);
+ codegen_enum(arb_int, name, match_arms)
+ }
+ _ => unreachable(()),
+ }
+}
+
+fn parse(item: TokenStream) -> DeriveInput {
+ shared::parse_derive(item)
+}
+
+fn analyze(derive_input: &DeriveInput) -> (&syn::Data, TokenStream, &Ident, BitSize, Option<Fallback>) {
+ shared::analyze_derive(derive_input, true)
+}
+
+fn analyze_enum(variants: Iter<Variant>, name: &Ident, internal_bitsize: BitSize, arb_int: &TokenStream) -> (Vec<TokenStream>, Vec<TokenStream>) {
+ validate_enum_variants(variants.clone());
+
+ if enum_fills_bitsize(internal_bitsize, variants.len()) {
+ emit_call_site_warning!("enum fills its bitsize"; help = "you can use `#[derive(FromBits)]` instead, rust will provide `TryFrom` for you (so you don't necessarily have to update call-sites)");
+ }
+
+ let mut assigner = DiscriminantAssigner::new(internal_bitsize);
+
+ variants
+ .map(|variant| {
+ let variant_name = &variant.ident;
+ let variant_value = assigner.assign_unsuffixed(variant);
+
+ let from_int_match_arm = quote! {
+ #variant_value => Ok(Self::#variant_name),
+ };
+
+ let to_int_match_arm = shared::to_int_match_arm(name, variant_name, arb_int, variant_value);
+
+ (from_int_match_arm, to_int_match_arm)
+ })
+ .unzip()
+}
+
+fn codegen_enum(arb_int: TokenStream, enum_type: &Ident, match_arms: (Vec<TokenStream>, Vec<TokenStream>)) -> TokenStream {
+ let (from_int_match_arms, to_int_match_arms) = match_arms;
+
+ let const_ = if cfg!(feature = "nightly") { quote!(const) } else { quote!() };
+
+ let from_enum_impl = shared::generate_from_enum_impl(&arb_int, enum_type, to_int_match_arms, &const_);
+ quote! {
+ impl #const_ ::core::convert::TryFrom<#arb_int> for #enum_type {
+ type Error = ::bilge::BitsError;
+
+ fn try_from(number: #arb_int) -> ::core::result::Result<Self, Self::Error> {
+ match number.value() {
+ #( #from_int_match_arms )*
+ i => Err(::bilge::give_me_error()),
+ }
+ }
+ }
+
+ // this other direction is needed for get/set/new
+ #from_enum_impl
+ }
+}
+
+fn generate_field_check(ty: &Type) -> TokenStream {
+ // Yes, this is hacky module management.
+ crate::bitsize_internal::struct_gen::generate_getter_inner(ty, false)
+}
+
+fn codegen_struct(arb_int: TokenStream, struct_type: &Ident, fields: &Fields) -> TokenStream {
+ let is_ok: TokenStream = fields
+ .iter()
+ .map(|field| {
+ let ty = &field.ty;
+ let size_from_type = last_ident_of_path(ty).and_then(bitsize_from_type_ident);
+ if let Some(size) = size_from_type {
+ quote! { {
+ // we still need to shift by the element's size
+ let size = #size;
+ cursor = cursor.wrapping_shr(size as u32);
+ true
+ } }
+ } else {
+ generate_field_check(ty)
+ }
+ })
+ .reduce(|acc, next| quote!((#acc && #next)))
+ // `Struct {}` would be handled like this:
+ .unwrap_or_else(|| quote!(true));
+
+ let const_ = if cfg!(feature = "nightly") { quote!(const) } else { quote!() };
+
+ quote! {
+ impl #const_ ::core::convert::TryFrom<#arb_int> for #struct_type {
+ type Error = ::bilge::BitsError;
+
+ // validates all values, which means enums, even in inner structs (TODO: and reserved fields?)
+ fn try_from(value: #arb_int) -> ::core::result::Result<Self, Self::Error> {
+ type ArbIntOf<T> = <T as Bitsized>::ArbitraryInt;
+ type BaseIntOf<T> = <ArbIntOf<T> as Number>::UnderlyingType;
+
+ // cursor starts at value's first field
+ let mut cursor = value.value();
+
+ let is_ok: bool = {#is_ok};
+
+ if is_ok {
+ Ok(Self { value })
+ } else {
+ Err(::bilge::give_me_error())
+ }
+ }
+ }
+
+ impl #const_ ::core::convert::From<#struct_type> for #arb_int {
+ fn from(struct_value: #struct_type) -> Self {
+ struct_value.value
+ }
+ }
+ }
+}
+
+fn validate_enum_variants(variants: Iter<Variant>) {
+ for variant in variants {
+ if !matches!(variant.fields, Fields::Unit) {
+ abort!(variant, "TryFromBits only supports unit variants in enums"; help = "change this variant to a unit");
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/bilge/.cargo-checksum.json b/rust/hw/char/pl011/vendor/bilge/.cargo-checksum.json
new file mode 100644
index 0000000000..39c4922340
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"3bb4a52531b944f44649567e4308c98efe1a908ca15558eaf9139fe260c22184","LICENSE-APACHE":"2514772e5475f208616174f81b67168179a7c51bdcb9570a96a9dc5962b83116","LICENSE-MIT":"7363fc7e2596998f3fc0109b6908575bf1cd8f6fa2fc97aff6bd9d17177f50bb","README.md":"6d4fcc631ed47bbe8e654649185ce987e9630192ea25c84edd264674e30efa4d","src/lib.rs":"4c8546a19b3255895058b4d5a2e8f17b36d196275bbc6831fe1a8b8cbeb258dc"},"package":"dc707ed8ebf81de5cd6c7f48f54b4c8621760926cdf35a57000747c512e67b57"}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/bilge/Cargo.toml b/rust/hw/char/pl011/vendor/bilge/Cargo.toml
new file mode 100644
index 0000000000..3e4900f08c
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge/Cargo.toml
@@ -0,0 +1,69 @@
+# 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"
+name = "bilge"
+version = "0.2.0"
+authors = ["Hecatia Elegua"]
+include = [
+ "src/lib.rs",
+ "LICENSE-*",
+ "README.md",
+]
+description = "Use bitsized types as if they were a feature of rust."
+documentation = "https://docs.rs/bilge"
+readme = "README.md"
+keywords = [
+ "bilge",
+ "bitfield",
+ "bits",
+ "register",
+]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/hecatia-elegua/bilge"
+
+[lib]
+bench = false
+
+[[bench]]
+name = "compared"
+path = "benches/compared/main.rs"
+bench = false
+harness = false
+
+[dependencies.arbitrary-int]
+version = "1.2.6"
+
+[dependencies.bilge-impl]
+version = "=0.2.0"
+
+[dev-dependencies.assert_matches]
+version = "1.5.0"
+
+[dev-dependencies.rustversion]
+version = "1.0"
+
+[dev-dependencies.trybuild]
+version = "1.0"
+
+[dev-dependencies.volatile]
+version = "0.5.1"
+
+[dev-dependencies.zerocopy]
+version = "0.5.0"
+
+[features]
+default = []
+nightly = [
+ "arbitrary-int/const_convert_and_const_trait_impl",
+ "bilge-impl/nightly",
+]
diff --git a/rust/hw/char/pl011/vendor/bilge/LICENSE-APACHE b/rust/hw/char/pl011/vendor/bilge/LICENSE-APACHE
new file mode 100644
index 0000000000..21254fc75d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge/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
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/bilge/LICENSE-MIT b/rust/hw/char/pl011/vendor/bilge/LICENSE-MIT
new file mode 100644
index 0000000000..2b1af07674
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge/LICENSE-MIT
@@ -0,0 +1,17 @@
+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.
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/bilge/README.md b/rust/hw/char/pl011/vendor/bilge/README.md
new file mode 100644
index 0000000000..48daad0fcb
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge/README.md
@@ -0,0 +1,327 @@
+# bilge: the most readable bitfields
+
+[](https://crates.io/crates/bilge)
+[](https://docs.rs/bilge)
+[](https://github.com/Aaronepower/tokei#badges)
+
+_Y e s_, this is yet another bitfield crate, but hear me out:
+
+This is a _**bit**_ better than what we had before.
+
+I wanted a design fitting rust:
+
+- **safe**
+ - types model as much of the functionality as possible and don't allow false usage
+- **fast**
+ - like handwritten bit fiddling code
+- **simple to complex**
+ - obvious and readable basic frontend, like normal structs
+ - only minimally and gradually introduce advanced concepts
+ - provide extension mechanisms
+
+The lib is **no-std** (and fully `const` behind a `"nightly"` feature gate).
+
+For some more explanations on the "why" and "how": [blog post](https://hecatia-elegua.github.io/blog/no-more-bit-fiddling/) and [reddit comments](https://www.reddit.com/r/rust/comments/13ic0mf/no_more_bit_fiddling_and_introducing_bilge/).
+
+## WARNING
+
+Our current version is still pre 1.0, which means nothing is completely stable.
+
+However, constructors, getters, setters and From/TryFrom should stay the same, since their semantics are very clear.
+
+[//]: # (keep this fixed to the version in .github/workflows/ci.yml, rust-toolchain.toml)
+
+The nightly feature is tested on `nightly-2022-11-03` and [will not work on the newest nightly until const_convert comes back](https://github.com/rust-lang/rust/issues/110395#issuecomment-1524775763).
+
+## Usage
+
+To make your life easier:
+
+```rust
+use bilge::prelude::*;
+```
+
+### Infallible (From)
+
+You can just specify bitsized fields like normal fields:
+
+```rust
+#[bitsize(14)]
+struct Register {
+ header: u4,
+ body: u7,
+ footer: Footer,
+}
+```
+
+The attribute `bitsize` generates the bitfield, while `14` works as a failsafe, emitting a compile error if your struct definition doesn't declare 14 bits.
+Let's define the nested struct `Footer` as well:
+
+```rust
+#[bitsize(3)]
+#[derive(FromBits)]
+struct Footer {
+ is_last: bool,
+ code: Code,
+}
+```
+
+As you can see, we added `#[derive(FromBits)]`, which is needed for `Register`'s getters and setters.
+Due to how rust macros work (outside-in), it needs to be below `#[bitsize]`.
+Also, `bool` can be used as one bit.
+
+`Code` is another nesting, this time an enum:
+
+```rust
+#[bitsize(2)]
+#[derive(FromBits)]
+enum Code { Success, Error, IoError, GoodExample }
+```
+
+Now we can construct `Register`:
+
+```rust
+let reg1 = Register::new(
+ u4::new(0b1010),
+ u7::new(0b010_1010),
+ Footer::new(true, Code::GoodExample)
+);
+```
+
+Or, if we add `#[derive(FromBits)]` to `Register` and want to parse a raw register value:
+
+```rust
+let mut reg2 = Register::from(u14::new(0b11_1_0101010_1010));
+```
+
+And getting and setting fields is done like this:
+
+```rust
+let header = reg2.header();
+reg2.set_footer(Footer::new(false, Code::Success));
+```
+
+Any kinds of tuple and array are also supported:
+
+```rust
+#[bitsize(32)]
+#[derive(FromBits)]
+struct InterruptSetEnables([bool; 32]);
+```
+
+Which produces the usual getter and setter, but also element accessors:
+
+```rust
+let mut ise = InterruptSetEnables::from(0b0000_0000_0000_0000_0000_0000_0001_0000);
+let ise5 = ise.val_0_at(4);
+ise.set_val_0_at(2, ise5);
+assert_eq!(0b0000_0000_0000_0000_0000_0000_0001_0100, ise.value);
+```
+
+Depending on what you're working with, only a subset of enum values might be clear, or some values might be reserved.
+In that case, you can use a fallback variant, defined like this:
+
+```rust
+#[bitsize(32)]
+#[derive(FromBits, Debug, PartialEq)]
+enum Subclass {
+ Mouse,
+ Keyboard,
+ Speakers,
+ #[fallback]
+ Reserved,
+}
+```
+
+which will convert any undeclared bits to `Reserved`:
+
+```rust
+assert_eq!(Subclass::Reserved, Subclass::from(3));
+assert_eq!(Subclass::Reserved, Subclass::from(42));
+let num = u32::from(Subclass::from(42));
+assert_eq!(3, num);
+assert_ne!(42, num);
+```
+
+or, if you need to keep the exact number saved, use:
+
+```rust
+#[fallback]
+Reserved(u32),
+```
+
+```rust
+assert_eq!(Subclass2::Reserved(3), Subclass2::from(3));
+assert_eq!(Subclass2::Reserved(42), Subclass2::from(42));
+let num = u32::from(Subclass2::from(42));
+assert_eq!(42, num);
+assert_ne!(3, num);
+```
+
+### Fallible (TryFrom)
+
+In contrast to structs, enums don't have to declare all of their bits:
+
+```rust
+#[bitsize(2)]
+#[derive(TryFromBits)]
+enum Class {
+ Mobile, Semimobile, /* 0x2 undefined */ Stationary = 0x3
+}
+```
+
+meaning this will work:
+
+```rust
+let class = Class::try_from(u2::new(2));
+assert!(class.is_err());
+```
+
+except we first need to `#[derive(Debug, PartialEq)]` on `Class`, since `assert_eq!` needs those.
+
+Let's do that, and use `Class` as a field:
+
+```rust
+#[bitsize(8)]
+#[derive(TryFromBits)]
+struct Device {
+ reserved: u2,
+ class: Class,
+ reserved: u4,
+}
+```
+
+This shows `TryFrom` being propagated upward. There's also another small help: `reserved` fields (which are often used in registers) can all have the same name.
+
+Again, let's try to print this:
+
+```rust
+println!("{:?}", Device::try_from(0b0000_11_00));
+println!("{:?}", Device::new(Class::Mobile));
+```
+
+And again, `Device` doesn't implement `Debug`:
+
+### DebugBits
+
+For structs, you need to add `#[derive(DebugBits)]` to get an output like this:
+
+```rust
+Ok(Device { reserved_i: 0, class: Stationary, reserved_ii: 0 })
+Device { reserved_i: 0, class: Mobile, reserved_ii: 0 }
+```
+
+For testing + overview, the full readme example code is in `/examples/readme.rs`.
+
+### Custom -Bits derives
+
+One of the main advantages of our approach is that we can keep `#[bitsize]` pretty slim, offloading all the other features to derive macros.
+Besides the derive macros shown above, you can extend `bilge` with your own derive crates working on bitfields.
+An example of this is given in [`/tests/custom_derive.rs`](https://github.com/hecatia-elegua/bilge/blob/main/tests/custom_derive.rs), with its implementation in [`tests/custom_bits`](https://github.com/hecatia-elegua/bilge/blob/1dfb6cf7d278d102d3f96ac31a9374e2b27fafc7/tests/custom_bits/custom_bits_derive/src/lib.rs).
+
+## Back- and Forwards Compatibility
+
+The syntax is kept very similar to usual rust structs for a simple reason:
+
+The endgoal of this library is to support the adoption of LLVM's arbitrary bitwidth integers into rust,
+thereby allowing rust-native bitfields.
+Until then, bilge is using the wonderful [`arbitrary-int` crate by danlehmann](https://github.com/danlehmann/arbitrary-int).
+
+After all attribute expansions, our generated bitfield contains a single field, somewhat like:
+
+```rust
+struct Register { value: u14 }
+```
+
+This means you _could_ modify the inner value directly, but it breaks type safety guarantees (e.g. unfilled or read-only fields).
+So if you need to modify the whole field, instead use the type-safe conversions `u14::from(register)` and `Register::from(u14)`.
+It is possible that this inner type will be made private.
+
+For some more examples and an overview of functionality, take a look at `/examples` and `/tests`.
+
+## Alternatives
+
+### benchmarks, performance, asm line count
+
+First of all, [basic benchmarking](https://github.com/hecatia-elegua/bilge/blob/main/benches/compared/main.rs) reveals that all alternatives mentioned here (besides deku) have about the same performance and line count. This includes a handwritten version.
+
+### build-time
+
+Measuring build time of the crate inself (both with its dependencies and without), yields these numbers on my machine:
+| | debug | debug single crate | release | release single crate |
+|-----------------------|-------|--------------------|-----------|----------------------|
+| bilge 1.67-nightly | 8 | 1.8 | 6 | 0.8 |
+| bitbybit 1.69 | 4.5 | 1.3 | 13.5 [^*] | 9.5 [^*] |
+| modular-bitfield 1.69 | 8 | 2.2 | 7.2 | 1.6 |
+
+[^*]: This is just a weird rustc regression or my setup or sth, not representative.
+
+This was measured with `cargo clean && cargo build [--release] --quiet --timings`.
+Of course, the actual codegen time on an example project needs to be measured, too.
+
+
+### handwritten implementation
+
+The common handwritten implementation pattern for bitfields in rust looks [somewhat like benches/compared/handmade.rs](https://github.com/hecatia-elegua/bilge/blob/main/benches/compared/handmade.rs), sometimes also throwing around a lot of consts for field offsets. The problems with this approach are:
+- readability suffers
+- offset, cast or masking errors could go unnoticed
+- bit fiddling, shifting and masking is done all over the place, in contrast to bitfields
+- beginners suffer, although I would argue even seniors, since it's more like: "Why do we need to learn and debug bit fiddling if we can get most of it done by using structs?"
+- reimplementing different kinds of _fallible nested-struct enum-tuple array field access_ might not be so fun
+
+### modular-bitfield
+
+The often used and very inspiring [`modular-bitfield`](https://github.com/robbepop/modular-bitfield) has a few
+problems:
+- it is unmaintained and has a quirky structure
+- constructors use the builder pattern
+ - makes user code unreadable if you have many fields
+ - can accidentally leave things uninitialized
+- `from_bytes` can easily take invalid arguments, which turns verification inside-out:
+ - modular-bitfield flow: `u16` -> `PackedData::from_bytes([u16])` -> `PackedData::status_or_err()?`
+ - needs to check for `Err` on every single access
+ - adds duplicate getters and setters with postfix `_or_err`
+ - reinvents `From<u16>`/`TryFrom<u16>` as a kind of hybrid
+ - bilge: usual type-system centric flow: `u16` -> `PackedData::try_from(u16)?` -> `PackedData::status()`
+ - just works, needs to check nothing on access
+ - some more general info on this: [Parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/)
+- big god-macro
+ - powerful, but less readable to the devs of modular-bitfield
+ - needs to cover many derives in itself, like `impl Debug` (other bitfield crates do this as well)
+ - bilge: solves this by providing a kind of scope for `-Bits`-derives
+
+and implementation differences:
+- underlying type is a byte array
+ - can be useful for bitfields larger than u128
+ - bilge: if your bitfields get larger than u128, you can most often split them into multiple bitfields of a primitive size (like u64) and put those in a parent struct which is not a bitfield
+
+Still, modular-bitfield is pretty good and I had set out to build something equal or hopefully better than it.
+Tell me where I can do better, I will try.
+
+### bitbybit
+
+One of the libs inspired by the same crate is [`bitbybit`](https://github.com/danlehmann/bitfield), which is much more readable and up-to-date. Actually, I even helped and am still helping on that one as well. After experimenting and hacking around in their code though, I realized it would need to be severely changed for the features and structure I had in mind.
+
+implementation differences (as of 26.04.23):
+- it can do read/write-only, array strides and repeat the same bits for multiple fields
+ - bilge: these will be added the moment someone needs it
+- redundant bit-offset specification, which can help or annoy, the same way bilge's `reserved` fields can help or annoy
+
+### deku
+
+After looking at a ton of bitfield libs on crates.io, I _didn't_ find [`deku`](https://github.com/sharksforarms/deku).
+I will still mention it here because it uses a very interesting crate underneath (bitvec).
+Currently (as of 26.04.23), it generates far more assembly and takes longer to run, since parts of the API are not `const`.
+I've opened an issue on their repo about that.
+
+### most others
+
+Besides that, many bitfield libs try to imitate or look like C bitfields, even though these are hated by many.
+I argue most beginners would have the idea to specify bits with basic primitives like u1, u2, ...
+This also opens up some possibilities for calculation and conversion on those primitives.
+
+Something similar can be said about `bitflags`, which, under this model, can be turned into simple structs with bools and enums.
+
+Basically, `bilge` tries to convert bit fiddling, shifting and masking into more widely known concepts like struct access.
+
+About the name: a bilge is one of the "lowest" parts of a ship, nothing else to it :)
diff --git a/rust/hw/char/pl011/vendor/bilge/meson.build b/rust/hw/char/pl011/vendor/bilge/meson.build
new file mode 100644
index 0000000000..906cec7764
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge/meson.build
@@ -0,0 +1,17 @@
+_bilge_rs = static_library(
+ 'bilge',
+ files('src/lib.rs'),
+ gnu_symbol_visibility: 'hidden',
+ rust_abi: 'rust',
+ rust_args: rust_args + [
+ '--edition', '2021',
+ ],
+ dependencies: [
+ dep_arbitrary_int,
+ dep_bilge_impl,
+ ],
+)
+
+dep_bilge = declare_dependency(
+ link_with: _bilge_rs,
+)
diff --git a/rust/hw/char/pl011/vendor/bilge/src/lib.rs b/rust/hw/char/pl011/vendor/bilge/src/lib.rs
new file mode 100644
index 0000000000..c6c9752ea5
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/bilge/src/lib.rs
@@ -0,0 +1,80 @@
+#![cfg_attr(not(doctest), doc = include_str!("../README.md"))]
+#![no_std]
+
+#[doc(no_inline)]
+pub use arbitrary_int;
+pub use bilge_impl::{bitsize, bitsize_internal, BinaryBits, DebugBits, DefaultBits, FromBits, TryFromBits};
+
+/// used for `use bilge::prelude::*;`
+pub mod prelude {
+ #[rustfmt::skip]
+ #[doc(no_inline)]
+ pub use super::{
+ bitsize, Bitsized,
+ FromBits, TryFromBits, DebugBits, BinaryBits, DefaultBits,
+ // we control the version, so this should not be a problem
+ arbitrary_int::*,
+ };
+}
+
+/// This is internally used, but might be useful. No guarantees are given (for now).
+pub trait Bitsized {
+ type ArbitraryInt;
+ const BITS: usize;
+ const MAX: Self::ArbitraryInt;
+}
+
+/// Internally used marker trait.
+/// # Safety
+///
+/// Avoid implementing this for your types. Implementing this trait could break invariants.
+pub unsafe trait Filled: Bitsized {}
+unsafe impl<T> Filled for T where T: Bitsized + From<<T as Bitsized>::ArbitraryInt> {}
+
+/// This is generated to statically validate that a type implements `FromBits`.
+pub const fn assume_filled<T: Filled>() {}
+
+#[non_exhaustive]
+#[derive(Debug, PartialEq)]
+pub struct BitsError;
+
+/// Internally used for generating the `Result::Err` type in `TryFrom`.
+///
+/// This is needed since we don't want users to be able to create `BitsError` right now.
+/// We'll be able to turn `BitsError` into an enum later, or anything else really.
+pub const fn give_me_error() -> BitsError {
+ BitsError
+}
+
+/// Only basing this on Number did not work, as bool and others are not Number.
+/// We could remove the whole macro_rules thing if it worked, though.
+/// Maybe there is some way to do this, I'm not deep into types.
+/// Finding some way to combine Number and Bitsized would be good as well.
+impl<BaseType, const BITS: usize> Bitsized for arbitrary_int::UInt<BaseType, BITS>
+where
+ arbitrary_int::UInt<BaseType, BITS>: arbitrary_int::Number,
+{
+ type ArbitraryInt = Self;
+ const BITS: usize = BITS;
+ const MAX: Self::ArbitraryInt = <Self as arbitrary_int::Number>::MAX;
+}
+
+macro_rules! bitsized_impl {
+ ($(($name:ident, $bits:expr)),+) => {
+ $(
+ impl Bitsized for $name {
+ type ArbitraryInt = Self;
+ const BITS: usize = $bits;
+ const MAX: Self::ArbitraryInt = <Self as arbitrary_int::Number>::MAX;
+ }
+ )+
+ };
+}
+bitsized_impl!((u8, 8), (u16, 16), (u32, 32), (u64, 64), (u128, 128));
+
+/// Handle bool as a u1
+impl Bitsized for bool {
+ type ArbitraryInt = arbitrary_int::u1;
+ const BITS: usize = 1;
+ const MAX: Self::ArbitraryInt = <arbitrary_int::u1 as arbitrary_int::Number>::MAX;
+}
diff --git a/rust/hw/char/pl011/vendor/either/.cargo-checksum.json b/rust/hw/char/pl011/vendor/either/.cargo-checksum.json
new file mode 100644
index 0000000000..d145aae980
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/either/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"96ca858a773ab30021cc60d1838bfccfc83b10e1279d8148187c8a049f18dbd6","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README-crates.io.md":"b775991a01ab4a0a8de6169f597775319d9ce8178f5c74ccdc634f13a286b20c","README.rst":"4fef58c3451b2eac9fd941f1fa0135d5df8183c124d75681497fa14bd1872b8b","src/into_either.rs":"0477f226bbba78ef017de08b87d421d3cd99fbc95b90ba4e6e3e803e3d15254e","src/iterator.rs":"fa2a6d14141980ce8a0bfcf7df2113d1e056d0f9815773dc9c2fb92a88923f4a","src/lib.rs":"4fbfa03b22b84d877610dfce1c7f279c97d80f4dc2c079c7dda364e4cf56ef13","src/serde_untagged.rs":"e826ee0ab31616e49c3e3f3711c8441001ee424b3e7a8c4c466cfcc4f8a7701a","src/serde_untagged_optional.rs":"86265f09d0795428bb2ce013b070d1badf1e2210217844a9ff3f04b2795868ab"},"package":"3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/either/Cargo.toml b/rust/hw/char/pl011/vendor/either/Cargo.toml
new file mode 100644
index 0000000000..1bfc7d42f1
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/either/Cargo.toml
@@ -0,0 +1,54 @@
+# 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 = "2018"
+rust-version = "1.37"
+name = "either"
+version = "1.12.0"
+authors = ["bluss"]
+description = """
+The enum `Either` with variants `Left` and `Right` is a general purpose sum type with two cases.
+"""
+documentation = "https://docs.rs/either/1/"
+readme = "README-crates.io.md"
+keywords = [
+ "data-structure",
+ "no_std",
+]
+categories = [
+ "data-structures",
+ "no-std",
+]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/rayon-rs/either"
+
+[package.metadata.docs.rs]
+features = ["serde"]
+
+[package.metadata.playground]
+features = ["serde"]
+
+[package.metadata.release]
+no-dev-version = true
+tag-name = "{{version}}"
+
+[dependencies.serde]
+version = "1.0"
+features = ["derive"]
+optional = true
+
+[dev-dependencies.serde_json]
+version = "1.0.0"
+
+[features]
+default = ["use_std"]
+use_std = []
diff --git a/rust/hw/char/pl011/vendor/either/LICENSE-APACHE b/rust/hw/char/pl011/vendor/either/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/either/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ 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
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/rust/hw/char/pl011/vendor/either/LICENSE-MIT b/rust/hw/char/pl011/vendor/either/LICENSE-MIT
new file mode 100644
index 0000000000..9203baa055
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/either/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2015
+
+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/rust/hw/char/pl011/vendor/either/README-crates.io.md b/rust/hw/char/pl011/vendor/either/README-crates.io.md
new file mode 100644
index 0000000000..d36890278b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/either/README-crates.io.md
@@ -0,0 +1,10 @@
+The enum `Either` with variants `Left` and `Right` is a general purpose
+sum type with two cases.
+
+Either has methods that are similar to Option and Result, and it also implements
+traits like `Iterator`.
+
+Includes macros `try_left!()` and `try_right!()` to use for
+short-circuiting logic, similar to how the `?` operator is used with `Result`.
+Note that `Either` is general purpose. For describing success or error, use the
+regular `Result`.
diff --git a/rust/hw/char/pl011/vendor/either/meson.build b/rust/hw/char/pl011/vendor/either/meson.build
new file mode 100644
index 0000000000..2d2d3057bc
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/either/meson.build
@@ -0,0 +1,16 @@
+_either_rs = static_library(
+ 'either',
+ files('src/lib.rs'),
+ gnu_symbol_visibility: 'hidden',
+ rust_abi: 'rust',
+ rust_args: rust_args + [
+ '--edition', '2018',
+ '--cfg', 'feature="use_std"',
+ '--cfg', 'feature="use_alloc"',
+ ],
+ dependencies: [],
+)
+
+dep_either = declare_dependency(
+ link_with: _either_rs,
+)
diff --git a/rust/hw/char/pl011/vendor/either/src/into_either.rs b/rust/hw/char/pl011/vendor/either/src/into_either.rs
new file mode 100644
index 0000000000..73746c80f1
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/either/src/into_either.rs
@@ -0,0 +1,64 @@
+//! The trait [`IntoEither`] provides methods for converting a type `Self`, whose
+//! size is constant and known at compile-time, into an [`Either`] variant.
+
+use super::{Either, Left, Right};
+
+/// Provides methods for converting a type `Self` into either a [`Left`] or [`Right`]
+/// variant of [`Either<Self, Self>`](Either).
+///
+/// The [`into_either`](IntoEither::into_either) method takes a [`bool`] to determine
+/// whether to convert to [`Left`] or [`Right`].
+///
+/// The [`into_either_with`](IntoEither::into_either_with) method takes a
+/// [predicate function](FnOnce) to determine whether to convert to [`Left`] or [`Right`].
+pub trait IntoEither: Sized {
+ /// Converts `self` into a [`Left`] variant of [`Either<Self, Self>`](Either)
+ /// if `into_left` is `true`.
+ /// Converts `self` into a [`Right`] variant of [`Either<Self, Self>`](Either)
+ /// otherwise.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use either::{IntoEither, Left, Right};
+ ///
+ /// let x = 0;
+ /// assert_eq!(x.into_either(true), Left(x));
+ /// assert_eq!(x.into_either(false), Right(x));
+ /// ```
+ fn into_either(self, into_left: bool) -> Either<Self, Self> {
+ if into_left {
+ Left(self)
+ } else {
+ Right(self)
+ }
+ }
+
+ /// Converts `self` into a [`Left`] variant of [`Either<Self, Self>`](Either)
+ /// if `into_left(&self)` returns `true`.
+ /// Converts `self` into a [`Right`] variant of [`Either<Self, Self>`](Either)
+ /// otherwise.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use either::{IntoEither, Left, Right};
+ ///
+ /// fn is_even(x: &u8) -> bool {
+ /// x % 2 == 0
+ /// }
+ ///
+ /// let x = 0;
+ /// assert_eq!(x.into_either_with(is_even), Left(x));
+ /// assert_eq!(x.into_either_with(|x| !is_even(x)), Right(x));
+ /// ```
+ fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
+ where
+ F: FnOnce(&Self) -> bool,
+ {
+ let into_left = into_left(&self);
+ self.into_either(into_left)
+ }
+}
+
+impl<T> IntoEither for T {}
diff --git a/rust/hw/char/pl011/vendor/either/src/iterator.rs b/rust/hw/char/pl011/vendor/either/src/iterator.rs
new file mode 100644
index 0000000000..9c5a83f9a5
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/either/src/iterator.rs
@@ -0,0 +1,315 @@
+use super::{for_both, Either, Left, Right};
+use core::iter;
+
+macro_rules! wrap_either {
+ ($value:expr => $( $tail:tt )*) => {
+ match $value {
+ Left(inner) => inner.map(Left) $($tail)*,
+ Right(inner) => inner.map(Right) $($tail)*,
+ }
+ };
+}
+
+/// Iterator that maps left or right iterators to corresponding `Either`-wrapped items.
+///
+/// This struct is created by the [`Either::factor_into_iter`],
+/// [`factor_iter`][Either::factor_iter],
+/// and [`factor_iter_mut`][Either::factor_iter_mut] methods.
+#[derive(Clone, Debug)]
+pub struct IterEither<L, R> {
+ inner: Either<L, R>,
+}
+
+impl<L, R> IterEither<L, R> {
+ pub(crate) fn new(inner: Either<L, R>) -> Self {
+ IterEither { inner }
+ }
+}
+
+impl<L, R, A> Extend<A> for Either<L, R>
+where
+ L: Extend<A>,
+ R: Extend<A>,
+{
+ fn extend<T>(&mut self, iter: T)
+ where
+ T: IntoIterator<Item = A>,
+ {
+ for_both!(*self, ref mut inner => inner.extend(iter))
+ }
+}
+
+/// `Either<L, R>` is an iterator if both `L` and `R` are iterators.
+impl<L, R> Iterator for Either<L, R>
+where
+ L: Iterator,
+ R: Iterator<Item = L::Item>,
+{
+ type Item = L::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ for_both!(*self, ref mut inner => inner.next())
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ for_both!(*self, ref inner => inner.size_hint())
+ }
+
+ fn fold<Acc, G>(self, init: Acc, f: G) -> Acc
+ where
+ G: FnMut(Acc, Self::Item) -> Acc,
+ {
+ for_both!(self, inner => inner.fold(init, f))
+ }
+
+ fn for_each<F>(self, f: F)
+ where
+ F: FnMut(Self::Item),
+ {
+ for_both!(self, inner => inner.for_each(f))
+ }
+
+ fn count(self) -> usize {
+ for_both!(self, inner => inner.count())
+ }
+
+ fn last(self) -> Option<Self::Item> {
+ for_both!(self, inner => inner.last())
+ }
+
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ for_both!(*self, ref mut inner => inner.nth(n))
+ }
+
+ fn collect<B>(self) -> B
+ where
+ B: iter::FromIterator<Self::Item>,
+ {
+ for_both!(self, inner => inner.collect())
+ }
+
+ fn partition<B, F>(self, f: F) -> (B, B)
+ where
+ B: Default + Extend<Self::Item>,
+ F: FnMut(&Self::Item) -> bool,
+ {
+ for_both!(self, inner => inner.partition(f))
+ }
+
+ fn all<F>(&mut self, f: F) -> bool
+ where
+ F: FnMut(Self::Item) -> bool,
+ {
+ for_both!(*self, ref mut inner => inner.all(f))
+ }
+
+ fn any<F>(&mut self, f: F) -> bool
+ where
+ F: FnMut(Self::Item) -> bool,
+ {
+ for_both!(*self, ref mut inner => inner.any(f))
+ }
+
+ fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
+ where
+ P: FnMut(&Self::Item) -> bool,
+ {
+ for_both!(*self, ref mut inner => inner.find(predicate))
+ }
+
+ fn find_map<B, F>(&mut self, f: F) -> Option<B>
+ where
+ F: FnMut(Self::Item) -> Option<B>,
+ {
+ for_both!(*self, ref mut inner => inner.find_map(f))
+ }
+
+ fn position<P>(&mut self, predicate: P) -> Option<usize>
+ where
+ P: FnMut(Self::Item) -> bool,
+ {
+ for_both!(*self, ref mut inner => inner.position(predicate))
+ }
+}
+
+impl<L, R> DoubleEndedIterator for Either<L, R>
+where
+ L: DoubleEndedIterator,
+ R: DoubleEndedIterator<Item = L::Item>,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ for_both!(*self, ref mut inner => inner.next_back())
+ }
+
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ for_both!(*self, ref mut inner => inner.nth_back(n))
+ }
+
+ fn rfold<Acc, G>(self, init: Acc, f: G) -> Acc
+ where
+ G: FnMut(Acc, Self::Item) -> Acc,
+ {
+ for_both!(self, inner => inner.rfold(init, f))
+ }
+
+ fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
+ where
+ P: FnMut(&Self::Item) -> bool,
+ {
+ for_both!(*self, ref mut inner => inner.rfind(predicate))
+ }
+}
+
+impl<L, R> ExactSizeIterator for Either<L, R>
+where
+ L: ExactSizeIterator,
+ R: ExactSizeIterator<Item = L::Item>,
+{
+ fn len(&self) -> usize {
+ for_both!(*self, ref inner => inner.len())
+ }
+}
+
+impl<L, R> iter::FusedIterator for Either<L, R>
+where
+ L: iter::FusedIterator,
+ R: iter::FusedIterator<Item = L::Item>,
+{
+}
+
+impl<L, R> Iterator for IterEither<L, R>
+where
+ L: Iterator,
+ R: Iterator,
+{
+ type Item = Either<L::Item, R::Item>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ Some(map_either!(self.inner, ref mut inner => inner.next()?))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ for_both!(self.inner, ref inner => inner.size_hint())
+ }
+
+ fn fold<Acc, G>(self, init: Acc, f: G) -> Acc
+ where
+ G: FnMut(Acc, Self::Item) -> Acc,
+ {
+ wrap_either!(self.inner => .fold(init, f))
+ }
+
+ fn for_each<F>(self, f: F)
+ where
+ F: FnMut(Self::Item),
+ {
+ wrap_either!(self.inner => .for_each(f))
+ }
+
+ fn count(self) -> usize {
+ for_both!(self.inner, inner => inner.count())
+ }
+
+ fn last(self) -> Option<Self::Item> {
+ Some(map_either!(self.inner, inner => inner.last()?))
+ }
+
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ Some(map_either!(self.inner, ref mut inner => inner.nth(n)?))
+ }
+
+ fn collect<B>(self) -> B
+ where
+ B: iter::FromIterator<Self::Item>,
+ {
+ wrap_either!(self.inner => .collect())
+ }
+
+ fn partition<B, F>(self, f: F) -> (B, B)
+ where
+ B: Default + Extend<Self::Item>,
+ F: FnMut(&Self::Item) -> bool,
+ {
+ wrap_either!(self.inner => .partition(f))
+ }
+
+ fn all<F>(&mut self, f: F) -> bool
+ where
+ F: FnMut(Self::Item) -> bool,
+ {
+ wrap_either!(&mut self.inner => .all(f))
+ }
+
+ fn any<F>(&mut self, f: F) -> bool
+ where
+ F: FnMut(Self::Item) -> bool,
+ {
+ wrap_either!(&mut self.inner => .any(f))
+ }
+
+ fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
+ where
+ P: FnMut(&Self::Item) -> bool,
+ {
+ wrap_either!(&mut self.inner => .find(predicate))
+ }
+
+ fn find_map<B, F>(&mut self, f: F) -> Option<B>
+ where
+ F: FnMut(Self::Item) -> Option<B>,
+ {
+ wrap_either!(&mut self.inner => .find_map(f))
+ }
+
+ fn position<P>(&mut self, predicate: P) -> Option<usize>
+ where
+ P: FnMut(Self::Item) -> bool,
+ {
+ wrap_either!(&mut self.inner => .position(predicate))
+ }
+}
+
+impl<L, R> DoubleEndedIterator for IterEither<L, R>
+where
+ L: DoubleEndedIterator,
+ R: DoubleEndedIterator,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ Some(map_either!(self.inner, ref mut inner => inner.next_back()?))
+ }
+
+ fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+ Some(map_either!(self.inner, ref mut inner => inner.nth_back(n)?))
+ }
+
+ fn rfold<Acc, G>(self, init: Acc, f: G) -> Acc
+ where
+ G: FnMut(Acc, Self::Item) -> Acc,
+ {
+ wrap_either!(self.inner => .rfold(init, f))
+ }
+
+ fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
+ where
+ P: FnMut(&Self::Item) -> bool,
+ {
+ wrap_either!(&mut self.inner => .rfind(predicate))
+ }
+}
+
+impl<L, R> ExactSizeIterator for IterEither<L, R>
+where
+ L: ExactSizeIterator,
+ R: ExactSizeIterator,
+{
+ fn len(&self) -> usize {
+ for_both!(self.inner, ref inner => inner.len())
+ }
+}
+
+impl<L, R> iter::FusedIterator for IterEither<L, R>
+where
+ L: iter::FusedIterator,
+ R: iter::FusedIterator,
+{
+}
diff --git a/rust/hw/char/pl011/vendor/either/src/lib.rs b/rust/hw/char/pl011/vendor/either/src/lib.rs
new file mode 100644
index 0000000000..e0792f2631
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/either/src/lib.rs
@@ -0,0 +1,1519 @@
+//! The enum [`Either`] with variants `Left` and `Right` is a general purpose
+//! sum type with two cases.
+//!
+//! [`Either`]: enum.Either.html
+//!
+//! **Crate features:**
+//!
+//! * `"use_std"`
+//! Enabled by default. Disable to make the library `#![no_std]`.
+//!
+//! * `"serde"`
+//! Disabled by default. Enable to `#[derive(Serialize, Deserialize)]` for `Either`
+//!
+
+#![doc(html_root_url = "https://docs.rs/either/1/")]
+#![no_std]
+
+#[cfg(any(test, feature = "use_std"))]
+extern crate std;
+
+#[cfg(feature = "serde")]
+pub mod serde_untagged;
+
+#[cfg(feature = "serde")]
+pub mod serde_untagged_optional;
+
+use core::convert::{AsMut, AsRef};
+use core::fmt;
+use core::future::Future;
+use core::ops::Deref;
+use core::ops::DerefMut;
+use core::pin::Pin;
+
+#[cfg(any(test, feature = "use_std"))]
+use std::error::Error;
+#[cfg(any(test, feature = "use_std"))]
+use std::io::{self, BufRead, Read, Seek, SeekFrom, Write};
+
+pub use crate::Either::{Left, Right};
+
+/// The enum `Either` with variants `Left` and `Right` is a general purpose
+/// sum type with two cases.
+///
+/// The `Either` type is symmetric and treats its variants the same way, without
+/// preference.
+/// (For representing success or error, use the regular `Result` enum instead.)
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum Either<L, R> {
+ /// A value of type `L`.
+ Left(L),
+ /// A value of type `R`.
+ Right(R),
+}
+
+/// Evaluate the provided expression for both [`Either::Left`] and [`Either::Right`].
+///
+/// This macro is useful in cases where both sides of [`Either`] can be interacted with
+/// in the same way even though the don't share the same type.
+///
+/// Syntax: `either::for_both!(` *expression* `,` *pattern* `=>` *expression* `)`
+///
+/// # Example
+///
+/// ```
+/// use either::Either;
+///
+/// fn length(owned_or_borrowed: Either<String, &'static str>) -> usize {
+/// either::for_both!(owned_or_borrowed, s => s.len())
+/// }
+///
+/// fn main() {
+/// let borrowed = Either::Right("Hello world!");
+/// let owned = Either::Left("Hello world!".to_owned());
+///
+/// assert_eq!(length(borrowed), 12);
+/// assert_eq!(length(owned), 12);
+/// }
+/// ```
+#[macro_export]
+macro_rules! for_both {
+ ($value:expr, $pattern:pat => $result:expr) => {
+ match $value {
+ $crate::Either::Left($pattern) => $result,
+ $crate::Either::Right($pattern) => $result,
+ }
+ };
+}
+
+/// Macro for unwrapping the left side of an [`Either`], which fails early
+/// with the opposite side. Can only be used in functions that return
+/// `Either` because of the early return of `Right` that it provides.
+///
+/// See also [`try_right!`] for its dual, which applies the same just to the
+/// right side.
+///
+/// # Example
+///
+/// ```
+/// use either::{Either, Left, Right};
+///
+/// fn twice(wrapper: Either<u32, &str>) -> Either<u32, &str> {
+/// let value = either::try_left!(wrapper);
+/// Left(value * 2)
+/// }
+///
+/// fn main() {
+/// assert_eq!(twice(Left(2)), Left(4));
+/// assert_eq!(twice(Right("ups")), Right("ups"));
+/// }
+/// ```
+#[macro_export]
+macro_rules! try_left {
+ ($expr:expr) => {
+ match $expr {
+ $crate::Left(val) => val,
+ $crate::Right(err) => return $crate::Right(::core::convert::From::from(err)),
+ }
+ };
+}
+
+/// Dual to [`try_left!`], see its documentation for more information.
+#[macro_export]
+macro_rules! try_right {
+ ($expr:expr) => {
+ match $expr {
+ $crate::Left(err) => return $crate::Left(::core::convert::From::from(err)),
+ $crate::Right(val) => val,
+ }
+ };
+}
+
+macro_rules! map_either {
+ ($value:expr, $pattern:pat => $result:expr) => {
+ match $value {
+ Left($pattern) => Left($result),
+ Right($pattern) => Right($result),
+ }
+ };
+}
+
+mod iterator;
+pub use self::iterator::IterEither;
+
+mod into_either;
+pub use self::into_either::IntoEither;
+
+impl<L: Clone, R: Clone> Clone for Either<L, R> {
+ fn clone(&self) -> Self {
+ match self {
+ Left(inner) => Left(inner.clone()),
+ Right(inner) => Right(inner.clone()),
+ }
+ }
+
+ fn clone_from(&mut self, source: &Self) {
+ match (self, source) {
+ (Left(dest), Left(source)) => dest.clone_from(source),
+ (Right(dest), Right(source)) => dest.clone_from(source),
+ (dest, source) => *dest = source.clone(),
+ }
+ }
+}
+
+impl<L, R> Either<L, R> {
+ /// Return true if the value is the `Left` variant.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let values = [Left(1), Right("the right value")];
+ /// assert_eq!(values[0].is_left(), true);
+ /// assert_eq!(values[1].is_left(), false);
+ /// ```
+ pub fn is_left(&self) -> bool {
+ match *self {
+ Left(_) => true,
+ Right(_) => false,
+ }
+ }
+
+ /// Return true if the value is the `Right` variant.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let values = [Left(1), Right("the right value")];
+ /// assert_eq!(values[0].is_right(), false);
+ /// assert_eq!(values[1].is_right(), true);
+ /// ```
+ pub fn is_right(&self) -> bool {
+ !self.is_left()
+ }
+
+ /// Convert the left side of `Either<L, R>` to an `Option<L>`.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let left: Either<_, ()> = Left("some value");
+ /// assert_eq!(left.left(), Some("some value"));
+ ///
+ /// let right: Either<(), _> = Right(321);
+ /// assert_eq!(right.left(), None);
+ /// ```
+ pub fn left(self) -> Option<L> {
+ match self {
+ Left(l) => Some(l),
+ Right(_) => None,
+ }
+ }
+
+ /// Convert the right side of `Either<L, R>` to an `Option<R>`.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let left: Either<_, ()> = Left("some value");
+ /// assert_eq!(left.right(), None);
+ ///
+ /// let right: Either<(), _> = Right(321);
+ /// assert_eq!(right.right(), Some(321));
+ /// ```
+ pub fn right(self) -> Option<R> {
+ match self {
+ Left(_) => None,
+ Right(r) => Some(r),
+ }
+ }
+
+ /// Convert `&Either<L, R>` to `Either<&L, &R>`.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let left: Either<_, ()> = Left("some value");
+ /// assert_eq!(left.as_ref(), Left(&"some value"));
+ ///
+ /// let right: Either<(), _> = Right("some value");
+ /// assert_eq!(right.as_ref(), Right(&"some value"));
+ /// ```
+ pub fn as_ref(&self) -> Either<&L, &R> {
+ match *self {
+ Left(ref inner) => Left(inner),
+ Right(ref inner) => Right(inner),
+ }
+ }
+
+ /// Convert `&mut Either<L, R>` to `Either<&mut L, &mut R>`.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// fn mutate_left(value: &mut Either<u32, u32>) {
+ /// if let Some(l) = value.as_mut().left() {
+ /// *l = 999;
+ /// }
+ /// }
+ ///
+ /// let mut left = Left(123);
+ /// let mut right = Right(123);
+ /// mutate_left(&mut left);
+ /// mutate_left(&mut right);
+ /// assert_eq!(left, Left(999));
+ /// assert_eq!(right, Right(123));
+ /// ```
+ pub fn as_mut(&mut self) -> Either<&mut L, &mut R> {
+ match *self {
+ Left(ref mut inner) => Left(inner),
+ Right(ref mut inner) => Right(inner),
+ }
+ }
+
+ /// Convert `Pin<&Either<L, R>>` to `Either<Pin<&L>, Pin<&R>>`,
+ /// pinned projections of the inner variants.
+ pub fn as_pin_ref(self: Pin<&Self>) -> Either<Pin<&L>, Pin<&R>> {
+ // SAFETY: We can use `new_unchecked` because the `inner` parts are
+ // guaranteed to be pinned, as they come from `self` which is pinned.
+ unsafe {
+ match *Pin::get_ref(self) {
+ Left(ref inner) => Left(Pin::new_unchecked(inner)),
+ Right(ref inner) => Right(Pin::new_unchecked(inner)),
+ }
+ }
+ }
+
+ /// Convert `Pin<&mut Either<L, R>>` to `Either<Pin<&mut L>, Pin<&mut R>>`,
+ /// pinned projections of the inner variants.
+ pub fn as_pin_mut(self: Pin<&mut Self>) -> Either<Pin<&mut L>, Pin<&mut R>> {
+ // SAFETY: `get_unchecked_mut` is fine because we don't move anything.
+ // We can use `new_unchecked` because the `inner` parts are guaranteed
+ // to be pinned, as they come from `self` which is pinned, and we never
+ // offer an unpinned `&mut L` or `&mut R` through `Pin<&mut Self>`. We
+ // also don't have an implementation of `Drop`, nor manual `Unpin`.
+ unsafe {
+ match *Pin::get_unchecked_mut(self) {
+ Left(ref mut inner) => Left(Pin::new_unchecked(inner)),
+ Right(ref mut inner) => Right(Pin::new_unchecked(inner)),
+ }
+ }
+ }
+
+ /// Convert `Either<L, R>` to `Either<R, L>`.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let left: Either<_, ()> = Left(123);
+ /// assert_eq!(left.flip(), Right(123));
+ ///
+ /// let right: Either<(), _> = Right("some value");
+ /// assert_eq!(right.flip(), Left("some value"));
+ /// ```
+ pub fn flip(self) -> Either<R, L> {
+ match self {
+ Left(l) => Right(l),
+ Right(r) => Left(r),
+ }
+ }
+
+ /// Apply the function `f` on the value in the `Left` variant if it is present rewrapping the
+ /// result in `Left`.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let left: Either<_, u32> = Left(123);
+ /// assert_eq!(left.map_left(|x| x * 2), Left(246));
+ ///
+ /// let right: Either<u32, _> = Right(123);
+ /// assert_eq!(right.map_left(|x| x * 2), Right(123));
+ /// ```
+ pub fn map_left<F, M>(self, f: F) -> Either<M, R>
+ where
+ F: FnOnce(L) -> M,
+ {
+ match self {
+ Left(l) => Left(f(l)),
+ Right(r) => Right(r),
+ }
+ }
+
+ /// Apply the function `f` on the value in the `Right` variant if it is present rewrapping the
+ /// result in `Right`.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let left: Either<_, u32> = Left(123);
+ /// assert_eq!(left.map_right(|x| x * 2), Left(123));
+ ///
+ /// let right: Either<u32, _> = Right(123);
+ /// assert_eq!(right.map_right(|x| x * 2), Right(246));
+ /// ```
+ pub fn map_right<F, S>(self, f: F) -> Either<L, S>
+ where
+ F: FnOnce(R) -> S,
+ {
+ match self {
+ Left(l) => Left(l),
+ Right(r) => Right(f(r)),
+ }
+ }
+
+ /// Apply the functions `f` and `g` to the `Left` and `Right` variants
+ /// respectively. This is equivalent to
+ /// [bimap](https://hackage.haskell.org/package/bifunctors-5/docs/Data-Bifunctor.html)
+ /// in functional programming.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let f = |s: String| s.len();
+ /// let g = |u: u8| u.to_string();
+ ///
+ /// let left: Either<String, u8> = Left("loopy".into());
+ /// assert_eq!(left.map_either(f, g), Left(5));
+ ///
+ /// let right: Either<String, u8> = Right(42);
+ /// assert_eq!(right.map_either(f, g), Right("42".into()));
+ /// ```
+ pub fn map_either<F, G, M, S>(self, f: F, g: G) -> Either<M, S>
+ where
+ F: FnOnce(L) -> M,
+ G: FnOnce(R) -> S,
+ {
+ match self {
+ Left(l) => Left(f(l)),
+ Right(r) => Right(g(r)),
+ }
+ }
+
+ /// Similar to [`map_either`][Self::map_either], with an added context `ctx` accessible to
+ /// both functions.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let mut sum = 0;
+ ///
+ /// // Both closures want to update the same value, so pass it as context.
+ /// let mut f = |sum: &mut usize, s: String| { *sum += s.len(); s.to_uppercase() };
+ /// let mut g = |sum: &mut usize, u: usize| { *sum += u; u.to_string() };
+ ///
+ /// let left: Either<String, usize> = Left("loopy".into());
+ /// assert_eq!(left.map_either_with(&mut sum, &mut f, &mut g), Left("LOOPY".into()));
+ ///
+ /// let right: Either<String, usize> = Right(42);
+ /// assert_eq!(right.map_either_with(&mut sum, &mut f, &mut g), Right("42".into()));
+ ///
+ /// assert_eq!(sum, 47);
+ /// ```
+ pub fn map_either_with<Ctx, F, G, M, S>(self, ctx: Ctx, f: F, g: G) -> Either<M, S>
+ where
+ F: FnOnce(Ctx, L) -> M,
+ G: FnOnce(Ctx, R) -> S,
+ {
+ match self {
+ Left(l) => Left(f(ctx, l)),
+ Right(r) => Right(g(ctx, r)),
+ }
+ }
+
+ /// Apply one of two functions depending on contents, unifying their result. If the value is
+ /// `Left(L)` then the first function `f` is applied; if it is `Right(R)` then the second
+ /// function `g` is applied.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// fn square(n: u32) -> i32 { (n * n) as i32 }
+ /// fn negate(n: i32) -> i32 { -n }
+ ///
+ /// let left: Either<u32, i32> = Left(4);
+ /// assert_eq!(left.either(square, negate), 16);
+ ///
+ /// let right: Either<u32, i32> = Right(-4);
+ /// assert_eq!(right.either(square, negate), 4);
+ /// ```
+ pub fn either<F, G, T>(self, f: F, g: G) -> T
+ where
+ F: FnOnce(L) -> T,
+ G: FnOnce(R) -> T,
+ {
+ match self {
+ Left(l) => f(l),
+ Right(r) => g(r),
+ }
+ }
+
+ /// Like [`either`][Self::either], but provide some context to whichever of the
+ /// functions ends up being called.
+ ///
+ /// ```
+ /// // In this example, the context is a mutable reference
+ /// use either::*;
+ ///
+ /// let mut result = Vec::new();
+ ///
+ /// let values = vec![Left(2), Right(2.7)];
+ ///
+ /// for value in values {
+ /// value.either_with(&mut result,
+ /// |ctx, integer| ctx.push(integer),
+ /// |ctx, real| ctx.push(f64::round(real) as i32));
+ /// }
+ ///
+ /// assert_eq!(result, vec![2, 3]);
+ /// ```
+ pub fn either_with<Ctx, F, G, T>(self, ctx: Ctx, f: F, g: G) -> T
+ where
+ F: FnOnce(Ctx, L) -> T,
+ G: FnOnce(Ctx, R) -> T,
+ {
+ match self {
+ Left(l) => f(ctx, l),
+ Right(r) => g(ctx, r),
+ }
+ }
+
+ /// Apply the function `f` on the value in the `Left` variant if it is present.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let left: Either<_, u32> = Left(123);
+ /// assert_eq!(left.left_and_then::<_,()>(|x| Right(x * 2)), Right(246));
+ ///
+ /// let right: Either<u32, _> = Right(123);
+ /// assert_eq!(right.left_and_then(|x| Right::<(), _>(x * 2)), Right(123));
+ /// ```
+ pub fn left_and_then<F, S>(self, f: F) -> Either<S, R>
+ where
+ F: FnOnce(L) -> Either<S, R>,
+ {
+ match self {
+ Left(l) => f(l),
+ Right(r) => Right(r),
+ }
+ }
+
+ /// Apply the function `f` on the value in the `Right` variant if it is present.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let left: Either<_, u32> = Left(123);
+ /// assert_eq!(left.right_and_then(|x| Right(x * 2)), Left(123));
+ ///
+ /// let right: Either<u32, _> = Right(123);
+ /// assert_eq!(right.right_and_then(|x| Right(x * 2)), Right(246));
+ /// ```
+ pub fn right_and_then<F, S>(self, f: F) -> Either<L, S>
+ where
+ F: FnOnce(R) -> Either<L, S>,
+ {
+ match self {
+ Left(l) => Left(l),
+ Right(r) => f(r),
+ }
+ }
+
+ /// Convert the inner value to an iterator.
+ ///
+ /// This requires the `Left` and `Right` iterators to have the same item type.
+ /// See [`factor_into_iter`][Either::factor_into_iter] to iterate different types.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let left: Either<_, Vec<u32>> = Left(vec![1, 2, 3, 4, 5]);
+ /// let mut right: Either<Vec<u32>, _> = Right(vec![]);
+ /// right.extend(left.into_iter());
+ /// assert_eq!(right, Right(vec![1, 2, 3, 4, 5]));
+ /// ```
+ #[allow(clippy::should_implement_trait)]
+ pub fn into_iter(self) -> Either<L::IntoIter, R::IntoIter>
+ where
+ L: IntoIterator,
+ R: IntoIterator<Item = L::Item>,
+ {
+ map_either!(self, inner => inner.into_iter())
+ }
+
+ /// Borrow the inner value as an iterator.
+ ///
+ /// This requires the `Left` and `Right` iterators to have the same item type.
+ /// See [`factor_iter`][Either::factor_iter] to iterate different types.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let left: Either<_, &[u32]> = Left(vec![2, 3]);
+ /// let mut right: Either<Vec<u32>, _> = Right(&[4, 5][..]);
+ /// let mut all = vec![1];
+ /// all.extend(left.iter());
+ /// all.extend(right.iter());
+ /// assert_eq!(all, vec![1, 2, 3, 4, 5]);
+ /// ```
+ pub fn iter(&self) -> Either<<&L as IntoIterator>::IntoIter, <&R as IntoIterator>::IntoIter>
+ where
+ for<'a> &'a L: IntoIterator,
+ for<'a> &'a R: IntoIterator<Item = <&'a L as IntoIterator>::Item>,
+ {
+ map_either!(self, inner => inner.into_iter())
+ }
+
+ /// Mutably borrow the inner value as an iterator.
+ ///
+ /// This requires the `Left` and `Right` iterators to have the same item type.
+ /// See [`factor_iter_mut`][Either::factor_iter_mut] to iterate different types.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let mut left: Either<_, &mut [u32]> = Left(vec![2, 3]);
+ /// for l in left.iter_mut() {
+ /// *l *= *l
+ /// }
+ /// assert_eq!(left, Left(vec![4, 9]));
+ ///
+ /// let mut inner = [4, 5];
+ /// let mut right: Either<Vec<u32>, _> = Right(&mut inner[..]);
+ /// for r in right.iter_mut() {
+ /// *r *= *r
+ /// }
+ /// assert_eq!(inner, [16, 25]);
+ /// ```
+ pub fn iter_mut(
+ &mut self,
+ ) -> Either<<&mut L as IntoIterator>::IntoIter, <&mut R as IntoIterator>::IntoIter>
+ where
+ for<'a> &'a mut L: IntoIterator,
+ for<'a> &'a mut R: IntoIterator<Item = <&'a mut L as IntoIterator>::Item>,
+ {
+ map_either!(self, inner => inner.into_iter())
+ }
+
+ /// Converts an `Either` of `Iterator`s to be an `Iterator` of `Either`s
+ ///
+ /// Unlike [`into_iter`][Either::into_iter], this does not require the
+ /// `Left` and `Right` iterators to have the same item type.
+ ///
+ /// ```
+ /// use either::*;
+ /// let left: Either<_, Vec<u8>> = Left(&["hello"]);
+ /// assert_eq!(left.factor_into_iter().next(), Some(Left(&"hello")));
+
+ /// let right: Either<&[&str], _> = Right(vec![0, 1]);
+ /// assert_eq!(right.factor_into_iter().collect::<Vec<_>>(), vec![Right(0), Right(1)]);
+ ///
+ /// ```
+ // TODO(MSRV): doc(alias) was stabilized in Rust 1.48
+ // #[doc(alias = "transpose")]
+ pub fn factor_into_iter(self) -> IterEither<L::IntoIter, R::IntoIter>
+ where
+ L: IntoIterator,
+ R: IntoIterator,
+ {
+ IterEither::new(map_either!(self, inner => inner.into_iter()))
+ }
+
+ /// Borrows an `Either` of `Iterator`s to be an `Iterator` of `Either`s
+ ///
+ /// Unlike [`iter`][Either::iter], this does not require the
+ /// `Left` and `Right` iterators to have the same item type.
+ ///
+ /// ```
+ /// use either::*;
+ /// let left: Either<_, Vec<u8>> = Left(["hello"]);
+ /// assert_eq!(left.factor_iter().next(), Some(Left(&"hello")));
+
+ /// let right: Either<[&str; 2], _> = Right(vec![0, 1]);
+ /// assert_eq!(right.factor_iter().collect::<Vec<_>>(), vec![Right(&0), Right(&1)]);
+ ///
+ /// ```
+ pub fn factor_iter(
+ &self,
+ ) -> IterEither<<&L as IntoIterator>::IntoIter, <&R as IntoIterator>::IntoIter>
+ where
+ for<'a> &'a L: IntoIterator,
+ for<'a> &'a R: IntoIterator,
+ {
+ IterEither::new(map_either!(self, inner => inner.into_iter()))
+ }
+
+ /// Mutably borrows an `Either` of `Iterator`s to be an `Iterator` of `Either`s
+ ///
+ /// Unlike [`iter_mut`][Either::iter_mut], this does not require the
+ /// `Left` and `Right` iterators to have the same item type.
+ ///
+ /// ```
+ /// use either::*;
+ /// let mut left: Either<_, Vec<u8>> = Left(["hello"]);
+ /// left.factor_iter_mut().for_each(|x| *x.unwrap_left() = "goodbye");
+ /// assert_eq!(left, Left(["goodbye"]));
+
+ /// let mut right: Either<[&str; 2], _> = Right(vec![0, 1, 2]);
+ /// right.factor_iter_mut().for_each(|x| if let Right(r) = x { *r = -*r; });
+ /// assert_eq!(right, Right(vec![0, -1, -2]));
+ ///
+ /// ```
+ pub fn factor_iter_mut(
+ &mut self,
+ ) -> IterEither<<&mut L as IntoIterator>::IntoIter, <&mut R as IntoIterator>::IntoIter>
+ where
+ for<'a> &'a mut L: IntoIterator,
+ for<'a> &'a mut R: IntoIterator,
+ {
+ IterEither::new(map_either!(self, inner => inner.into_iter()))
+ }
+
+ /// Return left value or given value
+ ///
+ /// Arguments passed to `left_or` are eagerly evaluated; if you are passing
+ /// the result of a function call, it is recommended to use
+ /// [`left_or_else`][Self::left_or_else], which is lazily evaluated.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use either::*;
+ /// let left: Either<&str, &str> = Left("left");
+ /// assert_eq!(left.left_or("foo"), "left");
+ ///
+ /// let right: Either<&str, &str> = Right("right");
+ /// assert_eq!(right.left_or("left"), "left");
+ /// ```
+ pub fn left_or(self, other: L) -> L {
+ match self {
+ Either::Left(l) => l,
+ Either::Right(_) => other,
+ }
+ }
+
+ /// Return left or a default
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use either::*;
+ /// let left: Either<String, u32> = Left("left".to_string());
+ /// assert_eq!(left.left_or_default(), "left");
+ ///
+ /// let right: Either<String, u32> = Right(42);
+ /// assert_eq!(right.left_or_default(), String::default());
+ /// ```
+ pub fn left_or_default(self) -> L
+ where
+ L: Default,
+ {
+ match self {
+ Either::Left(l) => l,
+ Either::Right(_) => L::default(),
+ }
+ }
+
+ /// Returns left value or computes it from a closure
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use either::*;
+ /// let left: Either<String, u32> = Left("3".to_string());
+ /// assert_eq!(left.left_or_else(|_| unreachable!()), "3");
+ ///
+ /// let right: Either<String, u32> = Right(3);
+ /// assert_eq!(right.left_or_else(|x| x.to_string()), "3");
+ /// ```
+ pub fn left_or_else<F>(self, f: F) -> L
+ where
+ F: FnOnce(R) -> L,
+ {
+ match self {
+ Either::Left(l) => l,
+ Either::Right(r) => f(r),
+ }
+ }
+
+ /// Return right value or given value
+ ///
+ /// Arguments passed to `right_or` are eagerly evaluated; if you are passing
+ /// the result of a function call, it is recommended to use
+ /// [`right_or_else`][Self::right_or_else], which is lazily evaluated.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use either::*;
+ /// let right: Either<&str, &str> = Right("right");
+ /// assert_eq!(right.right_or("foo"), "right");
+ ///
+ /// let left: Either<&str, &str> = Left("left");
+ /// assert_eq!(left.right_or("right"), "right");
+ /// ```
+ pub fn right_or(self, other: R) -> R {
+ match self {
+ Either::Left(_) => other,
+ Either::Right(r) => r,
+ }
+ }
+
+ /// Return right or a default
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use either::*;
+ /// let left: Either<String, u32> = Left("left".to_string());
+ /// assert_eq!(left.right_or_default(), u32::default());
+ ///
+ /// let right: Either<String, u32> = Right(42);
+ /// assert_eq!(right.right_or_default(), 42);
+ /// ```
+ pub fn right_or_default(self) -> R
+ where
+ R: Default,
+ {
+ match self {
+ Either::Left(_) => R::default(),
+ Either::Right(r) => r,
+ }
+ }
+
+ /// Returns right value or computes it from a closure
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use either::*;
+ /// let left: Either<String, u32> = Left("3".to_string());
+ /// assert_eq!(left.right_or_else(|x| x.parse().unwrap()), 3);
+ ///
+ /// let right: Either<String, u32> = Right(3);
+ /// assert_eq!(right.right_or_else(|_| unreachable!()), 3);
+ /// ```
+ pub fn right_or_else<F>(self, f: F) -> R
+ where
+ F: FnOnce(L) -> R,
+ {
+ match self {
+ Either::Left(l) => f(l),
+ Either::Right(r) => r,
+ }
+ }
+
+ /// Returns the left value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use either::*;
+ /// let left: Either<_, ()> = Left(3);
+ /// assert_eq!(left.unwrap_left(), 3);
+ /// ```
+ ///
+ /// # Panics
+ ///
+ /// When `Either` is a `Right` value
+ ///
+ /// ```should_panic
+ /// # use either::*;
+ /// let right: Either<(), _> = Right(3);
+ /// right.unwrap_left();
+ /// ```
+ pub fn unwrap_left(self) -> L
+ where
+ R: core::fmt::Debug,
+ {
+ match self {
+ Either::Left(l) => l,
+ Either::Right(r) => {
+ panic!("called `Either::unwrap_left()` on a `Right` value: {:?}", r)
+ }
+ }
+ }
+
+ /// Returns the right value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use either::*;
+ /// let right: Either<(), _> = Right(3);
+ /// assert_eq!(right.unwrap_right(), 3);
+ /// ```
+ ///
+ /// # Panics
+ ///
+ /// When `Either` is a `Left` value
+ ///
+ /// ```should_panic
+ /// # use either::*;
+ /// let left: Either<_, ()> = Left(3);
+ /// left.unwrap_right();
+ /// ```
+ pub fn unwrap_right(self) -> R
+ where
+ L: core::fmt::Debug,
+ {
+ match self {
+ Either::Right(r) => r,
+ Either::Left(l) => panic!("called `Either::unwrap_right()` on a `Left` value: {:?}", l),
+ }
+ }
+
+ /// Returns the left value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use either::*;
+ /// let left: Either<_, ()> = Left(3);
+ /// assert_eq!(left.expect_left("value was Right"), 3);
+ /// ```
+ ///
+ /// # Panics
+ ///
+ /// When `Either` is a `Right` value
+ ///
+ /// ```should_panic
+ /// # use either::*;
+ /// let right: Either<(), _> = Right(3);
+ /// right.expect_left("value was Right");
+ /// ```
+ pub fn expect_left(self, msg: &str) -> L
+ where
+ R: core::fmt::Debug,
+ {
+ match self {
+ Either::Left(l) => l,
+ Either::Right(r) => panic!("{}: {:?}", msg, r),
+ }
+ }
+
+ /// Returns the right value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use either::*;
+ /// let right: Either<(), _> = Right(3);
+ /// assert_eq!(right.expect_right("value was Left"), 3);
+ /// ```
+ ///
+ /// # Panics
+ ///
+ /// When `Either` is a `Left` value
+ ///
+ /// ```should_panic
+ /// # use either::*;
+ /// let left: Either<_, ()> = Left(3);
+ /// left.expect_right("value was Right");
+ /// ```
+ pub fn expect_right(self, msg: &str) -> R
+ where
+ L: core::fmt::Debug,
+ {
+ match self {
+ Either::Right(r) => r,
+ Either::Left(l) => panic!("{}: {:?}", msg, l),
+ }
+ }
+
+ /// Convert the contained value into `T`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use either::*;
+ /// // Both u16 and u32 can be converted to u64.
+ /// let left: Either<u16, u32> = Left(3u16);
+ /// assert_eq!(left.either_into::<u64>(), 3u64);
+ /// let right: Either<u16, u32> = Right(7u32);
+ /// assert_eq!(right.either_into::<u64>(), 7u64);
+ /// ```
+ pub fn either_into<T>(self) -> T
+ where
+ L: Into<T>,
+ R: Into<T>,
+ {
+ match self {
+ Either::Left(l) => l.into(),
+ Either::Right(r) => r.into(),
+ }
+ }
+}
+
+impl<L, R> Either<Option<L>, Option<R>> {
+ /// Factors out `None` from an `Either` of [`Option`].
+ ///
+ /// ```
+ /// use either::*;
+ /// let left: Either<_, Option<String>> = Left(Some(vec![0]));
+ /// assert_eq!(left.factor_none(), Some(Left(vec![0])));
+ ///
+ /// let right: Either<Option<Vec<u8>>, _> = Right(Some(String::new()));
+ /// assert_eq!(right.factor_none(), Some(Right(String::new())));
+ /// ```
+ // TODO(MSRV): doc(alias) was stabilized in Rust 1.48
+ // #[doc(alias = "transpose")]
+ pub fn factor_none(self) -> Option<Either<L, R>> {
+ match self {
+ Left(l) => l.map(Either::Left),
+ Right(r) => r.map(Either::Right),
+ }
+ }
+}
+
+impl<L, R, E> Either<Result<L, E>, Result<R, E>> {
+ /// Factors out a homogenous type from an `Either` of [`Result`].
+ ///
+ /// Here, the homogeneous type is the `Err` type of the [`Result`].
+ ///
+ /// ```
+ /// use either::*;
+ /// let left: Either<_, Result<String, u32>> = Left(Ok(vec![0]));
+ /// assert_eq!(left.factor_err(), Ok(Left(vec![0])));
+ ///
+ /// let right: Either<Result<Vec<u8>, u32>, _> = Right(Ok(String::new()));
+ /// assert_eq!(right.factor_err(), Ok(Right(String::new())));
+ /// ```
+ // TODO(MSRV): doc(alias) was stabilized in Rust 1.48
+ // #[doc(alias = "transpose")]
+ pub fn factor_err(self) -> Result<Either<L, R>, E> {
+ match self {
+ Left(l) => l.map(Either::Left),
+ Right(r) => r.map(Either::Right),
+ }
+ }
+}
+
+impl<T, L, R> Either<Result<T, L>, Result<T, R>> {
+ /// Factors out a homogenous type from an `Either` of [`Result`].
+ ///
+ /// Here, the homogeneous type is the `Ok` type of the [`Result`].
+ ///
+ /// ```
+ /// use either::*;
+ /// let left: Either<_, Result<u32, String>> = Left(Err(vec![0]));
+ /// assert_eq!(left.factor_ok(), Err(Left(vec![0])));
+ ///
+ /// let right: Either<Result<u32, Vec<u8>>, _> = Right(Err(String::new()));
+ /// assert_eq!(right.factor_ok(), Err(Right(String::new())));
+ /// ```
+ // TODO(MSRV): doc(alias) was stabilized in Rust 1.48
+ // #[doc(alias = "transpose")]
+ pub fn factor_ok(self) -> Result<T, Either<L, R>> {
+ match self {
+ Left(l) => l.map_err(Either::Left),
+ Right(r) => r.map_err(Either::Right),
+ }
+ }
+}
+
+impl<T, L, R> Either<(T, L), (T, R)> {
+ /// Factor out a homogeneous type from an either of pairs.
+ ///
+ /// Here, the homogeneous type is the first element of the pairs.
+ ///
+ /// ```
+ /// use either::*;
+ /// let left: Either<_, (u32, String)> = Left((123, vec![0]));
+ /// assert_eq!(left.factor_first().0, 123);
+ ///
+ /// let right: Either<(u32, Vec<u8>), _> = Right((123, String::new()));
+ /// assert_eq!(right.factor_first().0, 123);
+ /// ```
+ pub fn factor_first(self) -> (T, Either<L, R>) {
+ match self {
+ Left((t, l)) => (t, Left(l)),
+ Right((t, r)) => (t, Right(r)),
+ }
+ }
+}
+
+impl<T, L, R> Either<(L, T), (R, T)> {
+ /// Factor out a homogeneous type from an either of pairs.
+ ///
+ /// Here, the homogeneous type is the second element of the pairs.
+ ///
+ /// ```
+ /// use either::*;
+ /// let left: Either<_, (String, u32)> = Left((vec![0], 123));
+ /// assert_eq!(left.factor_second().1, 123);
+ ///
+ /// let right: Either<(Vec<u8>, u32), _> = Right((String::new(), 123));
+ /// assert_eq!(right.factor_second().1, 123);
+ /// ```
+ pub fn factor_second(self) -> (Either<L, R>, T) {
+ match self {
+ Left((l, t)) => (Left(l), t),
+ Right((r, t)) => (Right(r), t),
+ }
+ }
+}
+
+impl<T> Either<T, T> {
+ /// Extract the value of an either over two equivalent types.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let left: Either<_, u32> = Left(123);
+ /// assert_eq!(left.into_inner(), 123);
+ ///
+ /// let right: Either<u32, _> = Right(123);
+ /// assert_eq!(right.into_inner(), 123);
+ /// ```
+ pub fn into_inner(self) -> T {
+ for_both!(self, inner => inner)
+ }
+
+ /// Map `f` over the contained value and return the result in the
+ /// corresponding variant.
+ ///
+ /// ```
+ /// use either::*;
+ ///
+ /// let value: Either<_, i32> = Right(42);
+ ///
+ /// let other = value.map(|x| x * 2);
+ /// assert_eq!(other, Right(84));
+ /// ```
+ pub fn map<F, M>(self, f: F) -> Either<M, M>
+ where
+ F: FnOnce(T) -> M,
+ {
+ match self {
+ Left(l) => Left(f(l)),
+ Right(r) => Right(f(r)),
+ }
+ }
+}
+
+/// Convert from `Result` to `Either` with `Ok => Right` and `Err => Left`.
+impl<L, R> From<Result<R, L>> for Either<L, R> {
+ fn from(r: Result<R, L>) -> Self {
+ match r {
+ Err(e) => Left(e),
+ Ok(o) => Right(o),
+ }
+ }
+}
+
+/// Convert from `Either` to `Result` with `Right => Ok` and `Left => Err`.
+#[allow(clippy::from_over_into)] // From requires RFC 2451, Rust 1.41
+impl<L, R> Into<Result<R, L>> for Either<L, R> {
+ fn into(self) -> Result<R, L> {
+ match self {
+ Left(l) => Err(l),
+ Right(r) => Ok(r),
+ }
+ }
+}
+
+/// `Either<L, R>` is a future if both `L` and `R` are futures.
+impl<L, R> Future for Either<L, R>
+where
+ L: Future,
+ R: Future<Output = L::Output>,
+{
+ type Output = L::Output;
+
+ fn poll(
+ self: Pin<&mut Self>,
+ cx: &mut core::task::Context<'_>,
+ ) -> core::task::Poll<Self::Output> {
+ for_both!(self.as_pin_mut(), inner => inner.poll(cx))
+ }
+}
+
+#[cfg(any(test, feature = "use_std"))]
+/// `Either<L, R>` implements `Read` if both `L` and `R` do.
+///
+/// Requires crate feature `"use_std"`
+impl<L, R> Read for Either<L, R>
+where
+ L: Read,
+ R: Read,
+{
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ for_both!(*self, ref mut inner => inner.read(buf))
+ }
+
+ fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
+ for_both!(*self, ref mut inner => inner.read_exact(buf))
+ }
+
+ fn read_to_end(&mut self, buf: &mut std::vec::Vec<u8>) -> io::Result<usize> {
+ for_both!(*self, ref mut inner => inner.read_to_end(buf))
+ }
+
+ fn read_to_string(&mut self, buf: &mut std::string::String) -> io::Result<usize> {
+ for_both!(*self, ref mut inner => inner.read_to_string(buf))
+ }
+}
+
+#[cfg(any(test, feature = "use_std"))]
+/// `Either<L, R>` implements `Seek` if both `L` and `R` do.
+///
+/// Requires crate feature `"use_std"`
+impl<L, R> Seek for Either<L, R>
+where
+ L: Seek,
+ R: Seek,
+{
+ fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
+ for_both!(*self, ref mut inner => inner.seek(pos))
+ }
+}
+
+#[cfg(any(test, feature = "use_std"))]
+/// Requires crate feature `"use_std"`
+impl<L, R> BufRead for Either<L, R>
+where
+ L: BufRead,
+ R: BufRead,
+{
+ fn fill_buf(&mut self) -> io::Result<&[u8]> {
+ for_both!(*self, ref mut inner => inner.fill_buf())
+ }
+
+ fn consume(&mut self, amt: usize) {
+ for_both!(*self, ref mut inner => inner.consume(amt))
+ }
+
+ fn read_until(&mut self, byte: u8, buf: &mut std::vec::Vec<u8>) -> io::Result<usize> {
+ for_both!(*self, ref mut inner => inner.read_until(byte, buf))
+ }
+
+ fn read_line(&mut self, buf: &mut std::string::String) -> io::Result<usize> {
+ for_both!(*self, ref mut inner => inner.read_line(buf))
+ }
+}
+
+#[cfg(any(test, feature = "use_std"))]
+/// `Either<L, R>` implements `Write` if both `L` and `R` do.
+///
+/// Requires crate feature `"use_std"`
+impl<L, R> Write for Either<L, R>
+where
+ L: Write,
+ R: Write,
+{
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ for_both!(*self, ref mut inner => inner.write(buf))
+ }
+
+ fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+ for_both!(*self, ref mut inner => inner.write_all(buf))
+ }
+
+ fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
+ for_both!(*self, ref mut inner => inner.write_fmt(fmt))
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ for_both!(*self, ref mut inner => inner.flush())
+ }
+}
+
+impl<L, R, Target> AsRef<Target> for Either<L, R>
+where
+ L: AsRef<Target>,
+ R: AsRef<Target>,
+{
+ fn as_ref(&self) -> &Target {
+ for_both!(*self, ref inner => inner.as_ref())
+ }
+}
+
+macro_rules! impl_specific_ref_and_mut {
+ ($t:ty, $($attr:meta),* ) => {
+ $(#[$attr])*
+ impl<L, R> AsRef<$t> for Either<L, R>
+ where L: AsRef<$t>, R: AsRef<$t>
+ {
+ fn as_ref(&self) -> &$t {
+ for_both!(*self, ref inner => inner.as_ref())
+ }
+ }
+
+ $(#[$attr])*
+ impl<L, R> AsMut<$t> for Either<L, R>
+ where L: AsMut<$t>, R: AsMut<$t>
+ {
+ fn as_mut(&mut self) -> &mut $t {
+ for_both!(*self, ref mut inner => inner.as_mut())
+ }
+ }
+ };
+}
+
+impl_specific_ref_and_mut!(str,);
+impl_specific_ref_and_mut!(
+ ::std::path::Path,
+ cfg(feature = "use_std"),
+ doc = "Requires crate feature `use_std`."
+);
+impl_specific_ref_and_mut!(
+ ::std::ffi::OsStr,
+ cfg(feature = "use_std"),
+ doc = "Requires crate feature `use_std`."
+);
+impl_specific_ref_and_mut!(
+ ::std::ffi::CStr,
+ cfg(feature = "use_std"),
+ doc = "Requires crate feature `use_std`."
+);
+
+impl<L, R, Target> AsRef<[Target]> for Either<L, R>
+where
+ L: AsRef<[Target]>,
+ R: AsRef<[Target]>,
+{
+ fn as_ref(&self) -> &[Target] {
+ for_both!(*self, ref inner => inner.as_ref())
+ }
+}
+
+impl<L, R, Target> AsMut<Target> for Either<L, R>
+where
+ L: AsMut<Target>,
+ R: AsMut<Target>,
+{
+ fn as_mut(&mut self) -> &mut Target {
+ for_both!(*self, ref mut inner => inner.as_mut())
+ }
+}
+
+impl<L, R, Target> AsMut<[Target]> for Either<L, R>
+where
+ L: AsMut<[Target]>,
+ R: AsMut<[Target]>,
+{
+ fn as_mut(&mut self) -> &mut [Target] {
+ for_both!(*self, ref mut inner => inner.as_mut())
+ }
+}
+
+impl<L, R> Deref for Either<L, R>
+where
+ L: Deref,
+ R: Deref<Target = L::Target>,
+{
+ type Target = L::Target;
+
+ fn deref(&self) -> &Self::Target {
+ for_both!(*self, ref inner => &**inner)
+ }
+}
+
+impl<L, R> DerefMut for Either<L, R>
+where
+ L: DerefMut,
+ R: DerefMut<Target = L::Target>,
+{
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ for_both!(*self, ref mut inner => &mut *inner)
+ }
+}
+
+#[cfg(any(test, feature = "use_std"))]
+/// `Either` implements `Error` if *both* `L` and `R` implement it.
+///
+/// Requires crate feature `"use_std"`
+impl<L, R> Error for Either<L, R>
+where
+ L: Error,
+ R: Error,
+{
+ fn source(&self) -> Option<&(dyn Error + 'static)> {
+ for_both!(*self, ref inner => inner.source())
+ }
+
+ #[allow(deprecated)]
+ fn description(&self) -> &str {
+ for_both!(*self, ref inner => inner.description())
+ }
+
+ #[allow(deprecated)]
+ fn cause(&self) -> Option<&dyn Error> {
+ for_both!(*self, ref inner => inner.cause())
+ }
+}
+
+impl<L, R> fmt::Display for Either<L, R>
+where
+ L: fmt::Display,
+ R: fmt::Display,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ for_both!(*self, ref inner => inner.fmt(f))
+ }
+}
+
+#[test]
+fn basic() {
+ let mut e = Left(2);
+ let r = Right(2);
+ assert_eq!(e, Left(2));
+ e = r;
+ assert_eq!(e, Right(2));
+ assert_eq!(e.left(), None);
+ assert_eq!(e.right(), Some(2));
+ assert_eq!(e.as_ref().right(), Some(&2));
+ assert_eq!(e.as_mut().right(), Some(&mut 2));
+}
+
+#[test]
+fn macros() {
+ use std::string::String;
+
+ fn a() -> Either<u32, u32> {
+ let x: u32 = try_left!(Right(1337u32));
+ Left(x * 2)
+ }
+ assert_eq!(a(), Right(1337));
+
+ fn b() -> Either<String, &'static str> {
+ Right(try_right!(Left("foo bar")))
+ }
+ assert_eq!(b(), Left(String::from("foo bar")));
+}
+
+#[test]
+fn deref() {
+ use std::string::String;
+
+ fn is_str(_: &str) {}
+ let value: Either<String, &str> = Left(String::from("test"));
+ is_str(&*value);
+}
+
+#[test]
+fn iter() {
+ let x = 3;
+ let mut iter = match x {
+ 3 => Left(0..10),
+ _ => Right(17..),
+ };
+
+ assert_eq!(iter.next(), Some(0));
+ assert_eq!(iter.count(), 9);
+}
+
+#[test]
+fn seek() {
+ use std::io;
+
+ let use_empty = false;
+ let mut mockdata = [0x00; 256];
+ for i in 0..256 {
+ mockdata[i] = i as u8;
+ }
+
+ let mut reader = if use_empty {
+ // Empty didn't impl Seek until Rust 1.51
+ Left(io::Cursor::new([]))
+ } else {
+ Right(io::Cursor::new(&mockdata[..]))
+ };
+
+ let mut buf = [0u8; 16];
+ assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
+ assert_eq!(buf, mockdata[..buf.len()]);
+
+ // the first read should advance the cursor and return the next 16 bytes thus the `ne`
+ assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
+ assert_ne!(buf, mockdata[..buf.len()]);
+
+ // if the seek operation fails it should read 16..31 instead of 0..15
+ reader.seek(io::SeekFrom::Start(0)).unwrap();
+ assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
+ assert_eq!(buf, mockdata[..buf.len()]);
+}
+
+#[test]
+fn read_write() {
+ use std::io;
+
+ let use_stdio = false;
+ let mockdata = [0xff; 256];
+
+ let mut reader = if use_stdio {
+ Left(io::stdin())
+ } else {
+ Right(&mockdata[..])
+ };
+
+ let mut buf = [0u8; 16];
+ assert_eq!(reader.read(&mut buf).unwrap(), buf.len());
+ assert_eq!(&buf, &mockdata[..buf.len()]);
+
+ let mut mockbuf = [0u8; 256];
+ let mut writer = if use_stdio {
+ Left(io::stdout())
+ } else {
+ Right(&mut mockbuf[..])
+ };
+
+ let buf = [1u8; 16];
+ assert_eq!(writer.write(&buf).unwrap(), buf.len());
+}
+
+#[test]
+fn error() {
+ let invalid_utf8 = b"\xff";
+ #[allow(invalid_from_utf8)]
+ let res = if let Err(error) = ::std::str::from_utf8(invalid_utf8) {
+ Err(Left(error))
+ } else if let Err(error) = "x".parse::<i32>() {
+ Err(Right(error))
+ } else {
+ Ok(())
+ };
+ assert!(res.is_err());
+ #[allow(deprecated)]
+ res.unwrap_err().description(); // make sure this can be called
+}
+
+/// A helper macro to check if AsRef and AsMut are implemented for a given type.
+macro_rules! check_t {
+ ($t:ty) => {{
+ fn check_ref<T: AsRef<$t>>() {}
+ fn propagate_ref<T1: AsRef<$t>, T2: AsRef<$t>>() {
+ check_ref::<Either<T1, T2>>()
+ }
+ fn check_mut<T: AsMut<$t>>() {}
+ fn propagate_mut<T1: AsMut<$t>, T2: AsMut<$t>>() {
+ check_mut::<Either<T1, T2>>()
+ }
+ }};
+}
+
+// This "unused" method is here to ensure that compilation doesn't fail on given types.
+fn _unsized_ref_propagation() {
+ check_t!(str);
+
+ fn check_array_ref<T: AsRef<[Item]>, Item>() {}
+ fn check_array_mut<T: AsMut<[Item]>, Item>() {}
+
+ fn propagate_array_ref<T1: AsRef<[Item]>, T2: AsRef<[Item]>, Item>() {
+ check_array_ref::<Either<T1, T2>, _>()
+ }
+
+ fn propagate_array_mut<T1: AsMut<[Item]>, T2: AsMut<[Item]>, Item>() {
+ check_array_mut::<Either<T1, T2>, _>()
+ }
+}
+
+// This "unused" method is here to ensure that compilation doesn't fail on given types.
+#[cfg(feature = "use_std")]
+fn _unsized_std_propagation() {
+ check_t!(::std::path::Path);
+ check_t!(::std::ffi::OsStr);
+ check_t!(::std::ffi::CStr);
+}
diff --git a/rust/hw/char/pl011/vendor/either/src/serde_untagged.rs b/rust/hw/char/pl011/vendor/either/src/serde_untagged.rs
new file mode 100644
index 0000000000..72078c3ec8
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/either/src/serde_untagged.rs
@@ -0,0 +1,69 @@
+//! Untagged serialization/deserialization support for Either<L, R>.
+//!
+//! `Either` uses default, externally-tagged representation.
+//! However, sometimes it is useful to support several alternative types.
+//! For example, we may have a field which is generally Map<String, i32>
+//! but in typical cases Vec<String> would suffice, too.
+//!
+//! ```rust
+//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
+//! use either::Either;
+//! use std::collections::HashMap;
+//!
+//! #[derive(serde::Serialize, serde::Deserialize, Debug)]
+//! #[serde(transparent)]
+//! struct IntOrString {
+//! #[serde(with = "either::serde_untagged")]
+//! inner: Either<Vec<String>, HashMap<String, i32>>
+//! };
+//!
+//! // serialization
+//! let data = IntOrString {
+//! inner: Either::Left(vec!["Hello".to_string()])
+//! };
+//! // notice: no tags are emitted.
+//! assert_eq!(serde_json::to_string(&data)?, r#"["Hello"]"#);
+//!
+//! // deserialization
+//! let data: IntOrString = serde_json::from_str(
+//! r#"{"a": 0, "b": 14}"#
+//! )?;
+//! println!("found {:?}", data);
+//! # Ok(())
+//! # }
+//! ```
+
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
+
+#[derive(serde::Serialize, serde::Deserialize)]
+#[serde(untagged)]
+enum Either<L, R> {
+ Left(L),
+ Right(R),
+}
+
+pub fn serialize<L, R, S>(this: &super::Either<L, R>, serializer: S) -> Result<S::Ok, S::Error>
+where
+ S: Serializer,
+ L: Serialize,
+ R: Serialize,
+{
+ let untagged = match this {
+ super::Either::Left(left) => Either::Left(left),
+ super::Either::Right(right) => Either::Right(right),
+ };
+ untagged.serialize(serializer)
+}
+
+pub fn deserialize<'de, L, R, D>(deserializer: D) -> Result<super::Either<L, R>, D::Error>
+where
+ D: Deserializer<'de>,
+ L: Deserialize<'de>,
+ R: Deserialize<'de>,
+{
+ match Either::deserialize(deserializer) {
+ Ok(Either::Left(left)) => Ok(super::Either::Left(left)),
+ Ok(Either::Right(right)) => Ok(super::Either::Right(right)),
+ Err(error) => Err(error),
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/either/src/serde_untagged_optional.rs b/rust/hw/char/pl011/vendor/either/src/serde_untagged_optional.rs
new file mode 100644
index 0000000000..fb3239ace1
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/either/src/serde_untagged_optional.rs
@@ -0,0 +1,74 @@
+//! Untagged serialization/deserialization support for Option<Either<L, R>>.
+//!
+//! `Either` uses default, externally-tagged representation.
+//! However, sometimes it is useful to support several alternative types.
+//! For example, we may have a field which is generally Map<String, i32>
+//! but in typical cases Vec<String> would suffice, too.
+//!
+//! ```rust
+//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
+//! use either::Either;
+//! use std::collections::HashMap;
+//!
+//! #[derive(serde::Serialize, serde::Deserialize, Debug)]
+//! #[serde(transparent)]
+//! struct IntOrString {
+//! #[serde(with = "either::serde_untagged_optional")]
+//! inner: Option<Either<Vec<String>, HashMap<String, i32>>>
+//! };
+//!
+//! // serialization
+//! let data = IntOrString {
+//! inner: Some(Either::Left(vec!["Hello".to_string()]))
+//! };
+//! // notice: no tags are emitted.
+//! assert_eq!(serde_json::to_string(&data)?, r#"["Hello"]"#);
+//!
+//! // deserialization
+//! let data: IntOrString = serde_json::from_str(
+//! r#"{"a": 0, "b": 14}"#
+//! )?;
+//! println!("found {:?}", data);
+//! # Ok(())
+//! # }
+//! ```
+
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
+
+#[derive(Serialize, Deserialize)]
+#[serde(untagged)]
+enum Either<L, R> {
+ Left(L),
+ Right(R),
+}
+
+pub fn serialize<L, R, S>(
+ this: &Option<super::Either<L, R>>,
+ serializer: S,
+) -> Result<S::Ok, S::Error>
+where
+ S: Serializer,
+ L: Serialize,
+ R: Serialize,
+{
+ let untagged = match this {
+ Some(super::Either::Left(left)) => Some(Either::Left(left)),
+ Some(super::Either::Right(right)) => Some(Either::Right(right)),
+ None => None,
+ };
+ untagged.serialize(serializer)
+}
+
+pub fn deserialize<'de, L, R, D>(deserializer: D) -> Result<Option<super::Either<L, R>>, D::Error>
+where
+ D: Deserializer<'de>,
+ L: Deserialize<'de>,
+ R: Deserialize<'de>,
+{
+ match Option::deserialize(deserializer) {
+ Ok(Some(Either::Left(left))) => Ok(Some(super::Either::Left(left))),
+ Ok(Some(Either::Right(right))) => Ok(Some(super::Either::Right(right))),
+ Ok(None) => Ok(None),
+ Err(error) => Err(error),
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/.cargo-checksum.json b/rust/hw/char/pl011/vendor/itertools/.cargo-checksum.json
new file mode 100644
index 0000000000..327f66ceb5
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"9f94a3c5bdd8dd758864440205c84d73005b8619cd20833449db54f1f484c6bf","Cargo.lock":"b0443f54560491073ca861d8ed664a07a8039872568a527b2add8f362dd9734b","Cargo.toml":"e64e6e088ab537ba843f25a111af102dd434fd58cea3d446dff314cf42ad33e2","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README.md":"9de81a03c86ca4573d5d0a98eaa4d938bc6c538816f421d1b7499301efb5a454","benches/bench1.rs":"bb06f39db0544b1380cd4929139ccf521a9eecab7ca3f910b9499f965ec0a047","benches/combinations.rs":"51523ee1ca438a56f14711f0b04ee943895062d35859fbe23a2714d2fca3289d","benches/combinations_with_replacement.rs":"11f29160652a2d90ce7ca4b1c339c4457888ab6867e2456ce1c62e3adf9be737","benches/extra/mod.rs":"6ca290d72302a1945078621610b5788060b0de29639decebbdc557a80044aa97","benches/extra/zipslices.rs":"40e9f68a7c00f8429193fca463caef18851fa49b33355cc136bad3ccc840d655","benches/fold_specialization.rs":"5a517bbe29d366a15f6f751660e17ab1aa3e7b21552a1983048c662e34f0d69e","benches/powerset.rs":"6fd9d69a3483b37dc2411f99fb4efa6131577696f2dbdc8d1de9e4d7642fe3a3","benches/tree_fold1.rs":"539232e74f9aaea295a42069ac5af707811e90dc1c71c6e0a9064ffc731999de","benches/tuple_combinations.rs":"16366158743307a0289fc1df423a3cec45009807d410a9fe9922d5b6f8b7d002","benches/tuples.rs":"5a620783ae203e9ff9623d10d2c7fe9911d8b6c811cbad7613afa30e390c759d","examples/iris.data":"596ffd580471ca4d4880f8e439c7281f3b50d8249a5960353cb200b1490f63a0","examples/iris.rs":"1b465ed6a417180913104bc95a545fd9d1a3d67d121871ab737ad87e31b8be37","src/adaptors/coalesce.rs":"a0073325d40f297d29101538d18a267aef81889a999338dc09cb43a31cb4ec8b","src/adaptors/map.rs":"241971e856e468d71323071fb4a09867fbcedb83877320be132dc03516fe60e8","src/adaptors/mod.rs":"7f3bd7d011a348ce5e4bea486ef2e6346b64c7fe27540334d56d3f147f981d59","src/adaptors/multi_product.rs":"bb43e6dce68c815c21006d5b01c56e038d54b0c3bb8ee6bb8a4de11e2952c7ad","src/combinations.rs":"fb25babb459389093f886721016c72bf9f00e51d02735f638d871bb3a447ffd0","src/combinations_with_replacement.rs":"463011a574facbdd84278386b533a90e4dd517f0417e05adb82d182049db1f50","src/concat_impl.rs":"03b1ed61cbed242c286c3c4c5c848dbd57e02ab83fcef264f3a592b58107f324","src/cons_tuples_impl.rs":"c253d03b861831c01d62cacc57b49715ee62f6171e69f6886bb5a6ca0863bc3a","src/diff.rs":"a7800e9ce7a87b53ebe2338481335751fb43d44fa6a1ca719aceaaab40e5c8fe","src/duplicates_impl.rs":"f62fe4b642f501f785721ce5a505cf622a771e457210726dd0fb8b30be7ebbbc","src/either_or_both.rs":"c7ffe60772350c470fb42a5e4ff5087587985206733fe9814eeefa249983239a","src/exactly_one_err.rs":"aa50081f6a31b5109b30e3ed305e3ec2413c6908dedc8990ec5378a99cee2b39","src/extrema_set.rs":"2a25b0b86eed2fd5d05622d591a3085cab823973d450816c2c3b8cb76e9c187e","src/flatten_ok.rs":"fe209fd886ecd9cb98d99625aa0c7274af7e644eff4a10de15b4dec8bbbc934a","src/format.rs":"20fbbe35a98315ceb77ad910ff92319e163ae16452b0c24a8f1eccbc71c9e171","src/free.rs":"dfc57b7f56a08d4986a96b679018b41346576a7a34b668e008cc01109e728750","src/group_map.rs":"f7b02c964f63505d3e36280cfdc1755e05287714201efe983dacf702eee61434","src/groupbylazy.rs":"57ebf7d8a5a752045f94b76db8b80073f46964c28cc0919510fbdea102244918","src/grouping_map.rs":"cbc45ac563345c96f3ac50c78f73c83d870523436a7ab88c1c9a685d204461d3","src/impl_macros.rs":"4f829b458873bed556f1aff2ae4e88dbd576766e2b5bcc07ff3ac8756758e6f4","src/intersperse.rs":"b9717242495846a4a979c95d93d5681caccb7c07a0d889eab763ad3d49a46125","src/k_smallest.rs":"603eb34314c01769ff7f6def2a24cf7a7b38507e6f3658b7aafc23a3b2e9b322","src/kmerge_impl.rs":"a347b0f6fa7715afd8a54d85ce139ed5b14c9e58a16c2b3648f5b288fdb5375f","src/lazy_buffer.rs":"834f6ef7fdf9f00c8a6329beb38eaefb706847ceeec309c221dce705c2c1e05b","src/lib.rs":"703fa755955007c2ddf1c1abe6a20e9a762ba09746c4eeae905e6d417bf3bf31","src/merge_join.rs":"20574fbb0ca610a6ac0ad89fb7e856a629235a14f285954760386cd0de3dc687","src/minmax.rs":"96d3897c28c8c63284d4729becc9ada6855e0953cac6e1bd35cf6f38c50b0ec0","src/multipeek_impl.rs":"35162bca4456bfa20a08e8d40e4d1cc6783dc662778789fdcded60371e975122","src/pad_tail.rs":"04be2ca73abb85815b06b5524c99d6feb2919180c486a4646f9cc6c87462f67b","src/peek_nth.rs":"6a0a51f2f373ce14d3d58595c46464878a14976bf00841a7396c03f9f9ab07ac","src/peeking_take_while.rs":"2293eaba60142f427a8bd1fa6d347b21469cadaaef69a70f28daed3a4166c1b4","src/permutations.rs":"97831e7e26904c3cae68c97e74f7c6981ceb2fb2f2217282a0e5e54083a565fc","src/powerset.rs":"e0ee6b1316b4dd314c1e81502b90ae8113e1cda12168322520c5a65410e584b2","src/process_results_impl.rs":"fd51b2a4785c3b65145703dea4c088c822e5592de939cf228917c6275bee0778","src/put_back_n_impl.rs":"821e047fecd6ca0036290029f4febe7638a3abf1faa05e1e747a3bf9d80ff464","src/rciter_impl.rs":"5b156082ef2d25a94a4ad01d94cba2813c4b3e72e212515a8ad0fc8588f8045d","src/repeatn.rs":"bfc8f9145c9d8a3ea651f012b7d5a8d2fbbcbefdee76eafd098d02e7c54cda90","src/size_hint.rs":"021e57aad7df8f1e70ef588e9e9b8a1695aab183b1098f1848561f96c5dc9bcb","src/sources.rs":"61637f32c2cea2290ecfc1980c0b2d0f68463839ac09bd81006f8258ab8ecaae","src/take_while_inclusive.rs":"f567e91a7f25ed785c3132ff408e3f17b59dce98909041a8c40cd14c0f350f55","src/tee.rs":"665832aa547389a420c3441470ff2494249f0ed2841be0c6a578367fe9dbd381","src/tuple_impl.rs":"8d6c52850bf7f3b9d03fcbaed0e60e5a5becc2f8421ca4bc79e876659804a258","src/unique_impl.rs":"3b89cdd668b74cc0a0eabb1522489e2305a0d2d8da25d6a1884e8626bbdb5959","src/unziptuple.rs":"84b50e5d29b9ddbf21a46a1cc2fd7877729c7f7da9bdc8ae1966dbaf2d2f6f60","src/with_position.rs":"a3652e3e97de78c5c7eeb9a5306225b5ce517d6165b96663820b5f00fae1bff9","src/zip_eq_impl.rs":"4a41dc6dfe99359585d50ce648bdc85f15276c602048872b1d152e90841d8cad","src/zip_longest.rs":"f7cf5fffc3ca053ee80b410a05b27de1a475021f6de3181aea981010d7e8453f","src/ziptuple.rs":"7f9df12bf6556f382bbd4ad8cf17eb8b60c1c47fadbce016141133ba0f3384a1","tests/adaptors_no_collect.rs":"f459f36d54f5d475b2b2e83f5a1c98109c15062756ae822fa379486f3eeed666","tests/flatten_ok.rs":"b7894874132918b8229c7150b2637511d8e3e14197d8eeb9382d46b2a514efa2","tests/macros_hygiene.rs":"522afa0106e3f11a5149e9218f89c2329e405546d2ef0ea756d6a27e8a0e9ca3","tests/merge_join.rs":"b08c4ee6529d234c68d411a413b8781455d18a1eab17872d1828bb75a4fcf79b","tests/peeking_take_while.rs":"f834361c5520dda15eb9e9ebe87507c905462201412b21859d9f83dab91d0e0b","tests/quick.rs":"203619d7de9ae068a5c0c61c398f65f15a878b6ac759cc4575d19f0c90dfd9fa","tests/specializations.rs":"fdd16dc663330033fedcc478609b393d4aa369dc07dc8cda31a75219fb793087","tests/test_core.rs":"32576ba90aa8e5db985b6e6ffe30e3046bc6a11d392db8f6b4bdd2ba48d9b24d","tests/test_std.rs":"16a03cfe359a570685b48b80473d1947a89a49ec9ef744ea175252e2b95c0336","tests/tuples.rs":"014e4da776174bfe923270e2a359cd9c95b372fce4b952b8138909d6e2c52762","tests/zip.rs":"99af365fe6054ef1c6089d3e604e34da8fea66e55861ae4be9e7336ec8de4b56"},"package":"b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/itertools/CHANGELOG.md b/rust/hw/char/pl011/vendor/itertools/CHANGELOG.md
new file mode 100644
index 0000000000..8d7404e759
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/CHANGELOG.md
@@ -0,0 +1,409 @@
+# Changelog
+
+## 0.11.0
+
+### Breaking
+- Make `Itertools::merge_join_by` also accept functions returning bool (#704)
+- Implement `PeekingNext` transitively over mutable references (#643)
+- Change `with_position` to yield `(Position, Item)` instead of `Position<Item>` (#699)
+
+### Added
+- Add `Itertools::take_while_inclusive` (#616)
+- Implement `PeekingNext` for `PeekingTakeWhile` (#644)
+- Add `EitherOrBoth::{just_left, just_right, into_left, into_right, as_deref, as_deref_mut, left_or_insert, right_or_insert, left_or_insert_with, right_or_insert_with, insert_left, insert_right, insert_both}` (#629)
+- Implement `Clone` for `CircularTupleWindows` (#686)
+- Implement `Clone` for `Chunks` (#683)
+- Add `Itertools::process_results` (#680)
+
+### Changed
+- Use `Cell` instead of `RefCell` in `Format` and `FormatWith` (#608)
+- CI tweaks (#674, #675)
+- Document and test the difference between stable and unstable sorts (#653)
+- Fix documentation error on `Itertools::max_set_by_key` (#692)
+- Move MSRV metadata to `Cargo.toml` (#672)
+- Implement `equal` with `Iterator::eq` (#591)
+
+## 0.10.5
+ - Maintenance
+
+## 0.10.4
+ - Add `EitherOrBoth::or` and `EitherOrBoth::or_else` (#593)
+ - Add `min_set`, `max_set` et al. (#613, #323)
+ - Use `either/use_std` (#628)
+ - Documentation fixes (#612, #625, #632, #633, #634, #638)
+ - Code maintenance (#623, #624, #627, #630)
+
+## 0.10.3
+ - Maintenance
+
+## 0.10.2
+ - Add `Itertools::multiunzip` (#362, #565)
+ - Add `intersperse` and `intersperse_with` free functions (#555)
+ - Add `Itertools::sorted_by_cached_key` (#424, #575)
+ - Specialize `ProcessResults::fold` (#563)
+ - Fix subtraction overflow in `DuplicatesBy::size_hint` (#552)
+ - Fix specialization tests (#574)
+ - More `Debug` impls (#573)
+ - Deprecate `fold1` (use `reduce` instead) (#580)
+ - Documentation fixes (`HomogenousTuple`, `into_group_map`, `into_group_map_by`, `MultiPeek::peek`) (#543 et al.)
+
+## 0.10.1
+ - Add `Itertools::contains` (#514)
+ - Add `Itertools::counts_by` (#515)
+ - Add `Itertools::partition_result` (#511)
+ - Add `Itertools::all_unique` (#241)
+ - Add `Itertools::duplicates` and `Itertools::duplicates_by` (#502)
+ - Add `chain!` (#525)
+ - Add `Itertools::at_most_one` (#523)
+ - Add `Itertools::flatten_ok` (#527)
+ - Add `EitherOrBoth::or_default` (#583)
+ - Add `Itertools::find_or_last` and `Itertools::find_or_first` (#535)
+ - Implement `FusedIterator` for `FilterOk`, `FilterMapOk`, `InterleaveShortest`, `KMergeBy`, `MergeBy`, `PadUsing`, `Positions`, `Product` , `RcIter`, `TupleWindows`, `Unique`, `UniqueBy`, `Update`, `WhileSome`, `Combinations`, `CombinationsWithReplacement`, `Powerset`, `RepeatN`, and `WithPosition` (#550)
+ - Implement `FusedIterator` for `Interleave`, `IntersperseWith`, and `ZipLongest` (#548)
+
+## 0.10.0
+ - **Increase minimum supported Rust version to 1.32.0**
+ - Improve macro hygiene (#507)
+ - Add `Itertools::powerset` (#335)
+ - Add `Itertools::sorted_unstable`, `Itertools::sorted_unstable_by`, and `Itertools::sorted_unstable_by_key` (#494)
+ - Implement `Error` for `ExactlyOneError` (#484)
+ - Undeprecate `Itertools::fold_while` (#476)
+ - Tuple-related adapters work for tuples of arity up to 12 (#475)
+ - `use_alloc` feature for users who have `alloc`, but not `std` (#474)
+ - Add `Itertools::k_smallest` (#473)
+ - Add `Itertools::into_grouping_map` and `GroupingMap` (#465)
+ - Add `Itertools::into_grouping_map_by` and `GroupingMapBy` (#465)
+ - Add `Itertools::counts` (#468)
+ - Add implementation of `DoubleEndedIterator` for `Unique` (#442)
+ - Add implementation of `DoubleEndedIterator` for `UniqueBy` (#442)
+ - Add implementation of `DoubleEndedIterator` for `Zip` (#346)
+ - Add `Itertools::multipeek` (#435)
+ - Add `Itertools::dedup_with_count` and `DedupWithCount` (#423)
+ - Add `Itertools::dedup_by_with_count` and `DedupByWithCount` (#423)
+ - Add `Itertools::intersperse_with` and `IntersperseWith` (#381)
+ - Add `Itertools::filter_ok` and `FilterOk` (#377)
+ - Add `Itertools::filter_map_ok` and `FilterMapOk` (#377)
+ - Deprecate `Itertools::fold_results`, use `Itertools::fold_ok` instead (#377)
+ - Deprecate `Itertools::map_results`, use `Itertools::map_ok` instead (#377)
+ - Deprecate `FoldResults`, use `FoldOk` instead (#377)
+ - Deprecate `MapResults`, use `MapOk` instead (#377)
+ - Add `Itertools::circular_tuple_windows` and `CircularTupleWindows` (#350)
+ - Add `peek_nth` and `PeekNth` (#303)
+
+## 0.9.0
+ - Fix potential overflow in `MergeJoinBy::size_hint` (#385)
+ - Add `derive(Clone)` where possible (#382)
+ - Add `try_collect` method (#394)
+ - Add `HomogeneousTuple` trait (#389)
+ - Fix `combinations(0)` and `combinations_with_replacement(0)` (#383)
+ - Don't require `ParitalEq` to the `Item` of `DedupBy` (#397)
+ - Implement missing specializations on the `PutBack` adaptor and on the `MergeJoinBy` iterator (#372)
+ - Add `position_*` methods (#412)
+ - Derive `Hash` for `EitherOrBoth` (#417)
+ - Increase minimum supported Rust version to 1.32.0
+
+## 0.8.2
+ - Use `slice::iter` instead of `into_iter` to avoid future breakage (#378, by @LukasKalbertodt)
+## 0.8.1
+ - Added a [`.exactly_one()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.exactly_one) iterator method that, on success, extracts the single value of an iterator ; by @Xaeroxe
+ - Added combinatory iterator adaptors:
+ - [`.permutations(k)`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.permutations):
+
+ `[0, 1, 2].iter().permutations(2)` yields
+
+ ```rust
+ [
+ vec![0, 1],
+ vec![0, 2],
+ vec![1, 0],
+ vec![1, 2],
+ vec![2, 0],
+ vec![2, 1],
+ ]
+ ```
+
+ ; by @tobz1000
+
+ - [`.combinations_with_replacement(k)`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.combinations_with_replacement):
+
+ `[0, 1, 2].iter().combinations_with_replacement(2)` yields
+
+ ```rust
+ [
+ vec![0, 0],
+ vec![0, 1],
+ vec![0, 2],
+ vec![1, 1],
+ vec![1, 2],
+ vec![2, 2],
+ ]
+ ```
+
+ ; by @tommilligan
+
+ - For reference, these methods join the already existing [`.combinations(k)`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.combinations):
+
+ `[0, 1, 2].iter().combinations(2)` yields
+
+ ```rust
+ [
+ vec![0, 1],
+ vec![0, 2],
+ vec![1, 2],
+ ]
+ ```
+
+ - Improved the performance of [`.fold()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.fold)-based internal iteration for the [`.intersperse()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.intersperse) iterator ; by @jswrenn
+ - Added [`.dedup_by()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.dedup_by), [`.merge_by()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.merge_by) and [`.kmerge_by()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.kmerge_by) adaptors that work like [`.dedup()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.dedup), [`.merge()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.merge) and [`.kmerge()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.kmerge), but taking an additional custom comparison closure parameter. ; by @phimuemue
+ - Improved the performance of [`.all_equal()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.all_equal) ; by @fyrchik
+ - Loosened the bounds on [`.partition_map()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.partition_map) to take just a `FnMut` closure rather than a `Fn` closure, and made its implementation use internal iteration for better performance ; by @danielhenrymantilla
+ - Added convenience methods to [`EitherOrBoth`](https://docs.rs/itertools/0.8.1/itertools/enum.EitherOrBoth.html) elements yielded from the [`.zip_longest()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.zip_longest) iterator adaptor ; by @Avi-D-coder
+ - Added [`.sum1()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.sum1) and [`.product1()`](https://docs.rs/itertools/0.8.1/itertools/trait.Itertools.html#method.product1) iterator methods that respectively try to return the sum and the product of the elements of an iterator **when it is not empty**, otherwise they return `None` ; by @Emerentius
+## 0.8.0
+ - Added new adaptor `.map_into()` for conversions using `Into` by @vorner
+ - Improved `Itertools` docs by @JohnHeitmann
+ - The return type of `.sorted_by_by_key()` is now an iterator, not a Vec.
+ - The return type of the `izip!(x, y)` macro with exactly two arguments is now the usual `Iterator::zip`.
+ - Remove `.flatten()` in favour of std's `.flatten()`
+ - Deprecate `.foreach()` in favour of std's `.for_each()`
+ - Deprecate `.step()` in favour of std's `.step_by()`
+ - Deprecate `repeat_call` in favour of std's `repeat_with`
+ - Deprecate `.fold_while()` in favour of std's `.try_fold()`
+ - Require Rust 1.24 as minimal version.
+## 0.7.11
+ - Add convenience methods to `EitherOrBoth`, making it more similar to `Option` and `Either` by @jethrogb
+## 0.7.10
+ - No changes.
+## 0.7.9
+ - New inclusion policy: See the readme about suggesting features for std before accepting them in itertools.
+ - The `FoldWhile` type now implements `Eq` and `PartialEq` by @jturner314
+## 0.7.8
+ - Add new iterator method `.tree_fold1()` which is like `.fold1()` except items are combined in a tree structure (see its docs). By @scottmcm
+ - Add more `Debug` impls by @phimuemue: KMerge, KMergeBy, MergeJoinBy, ConsTuples, Intersperse, ProcessResults, RcIter, Tee, TupleWindows, Tee, ZipLongest, ZipEq, Zip.
+## 0.7.7
+ - Add new iterator method `.into_group_map() -> HashMap<K, Vec<V>>` which turns an iterator of `(K, V)` elements into such a hash table, where values are grouped by key. By @tobz1000
+ - Add new free function `flatten` for the `.flatten()` adaptor. **NOTE:** recent Rust nightlies have `Iterator::flatten` and thus a clash with our flatten adaptor. One workaround is to use the itertools `flatten` free function.
+## 0.7.6
+ - Add new adaptor `.multi_cartesian_product()` which is an n-ary product iterator by @tobz1000
+ - Add new method `.sorted_by_key()` by @Xion
+ - Provide simpler and faster `.count()` for `.unique()` and `.unique_by()`
+## 0.7.5
+ - `.multipeek()` now implements `PeekingNext`, by @nicopap.
+## 0.7.4
+ - Add new adaptor `.update()` by @lucasem; this adaptor is used to modify an element before passing it on in an iterator chain.
+## 0.7.3
+ - Add new method `.collect_tuple()` by @matklad; it makes a tuple out of the iterator's elements if the number of them matches **exactly**.
+ - Implement `fold` and `collect` for `.map_results()` which means it reuses the code of the standard `.map()` for these methods.
+## 0.7.2
+ - Add new adaptor `.merge_join_by` by @srijs; a heterogeneous merge join for two ordered sequences.
+## 0.7.1
+ - Iterator adaptors and iterators in itertools now use the same `must_use` reminder that the standard library adaptors do, by @matematikaedit and @bluss *“iterator adaptors are lazy and do nothing unless consumed”*.
+## 0.7.0
+ - Faster `izip!()` by @krdln
+ - `izip!()` is now a wrapper for repeated regular `.zip()` and a single `.map()`. This means it optimizes as well as the standard library `.zip()` it uses. **Note:** `multizip` and `izip!()` are now different! The former has a named type but the latter optimizes better.
+ - Faster `.unique()`
+ - `no_std` support, which is opt-in!
+ - Many lovable features are still there without std, like `izip!()` or `.format()` or `.merge()`, but not those that use collections.
+ - Trait bounds were required up front instead of just on the type: `group_by`'s `PartialEq` by @Phlosioneer and `repeat_call`'s `FnMut`.
+ - Removed deprecated constructor `Zip::new` — use `izip!()` or `multizip()`
+## 0.6.5
+ - Fix bug in `.cartesian_product()`'s fold (which only was visible for unfused iterators).
+## 0.6.4
+ - Add specific `fold` implementations for `.cartesian_product()` and `cons_tuples()`, which improves their performance in fold, foreach, and iterator consumers derived from them.
+## 0.6.3
+ - Add iterator adaptor `.positions(predicate)` by @tmccombs
+## 0.6.2
+ - Add function `process_results` which can “lift” a function of the regular values of an iterator so that it can process the `Ok` values from an iterator of `Results` instead, by @shepmaster
+ - Add iterator method `.concat()` which combines all iterator elements into a single collection using the `Extend` trait, by @srijs
+## 0.6.1
+ - Better size hint testing and subsequent size hint bugfixes by @rkarp. Fixes bugs in product, `interleave_shortest` size hints.
+ - New iterator method `.all_equal()` by @phimuemue
+## 0.6.0
+ - Deprecated names were removed in favour of their replacements
+ - `.flatten()` does not implement double ended iteration anymore
+ - `.fold_while()` uses `&mut self` and returns `FoldWhile<T>`, for composability #168
+ - `.foreach()` and `.fold1()` use `self`, like `.fold()` does.
+ - `.combinations(0)` now produces a single empty vector. #174
+## 0.5.10
+ - Add itertools method `.kmerge_by()` (and corresponding free function)
+ - Relaxed trait requirement of `.kmerge()` and `.minmax()` to PartialOrd.
+## 0.5.9
+ - Add multipeek method `.reset_peek()`
+ - Add categories
+## 0.5.8
+ - Add iterator adaptor `.peeking_take_while()` and its trait `PeekingNext`.
+## 0.5.7
+ - Add iterator adaptor `.with_position()`
+ - Fix multipeek's performance for long peeks by using `VecDeque`.
+## 0.5.6
+ - Add `.map_results()`
+## 0.5.5
+ - Many more adaptors now implement `Debug`
+ - Add free function constructor `repeat_n`. `RepeatN::new` is now deprecated.
+## 0.5.4
+ - Add infinite generator function `iterate`, that takes a seed and a closure.
+## 0.5.3
+ - Special-cased `.fold()` for flatten and put back. `.foreach()` now uses fold on the iterator, to pick up any iterator specific loop implementation.
+ - `.combinations(n)` asserts up front that `n != 0`, instead of running into an error on the second iterator element.
+## 0.5.2
+ - Add `.tuples::<T>()` that iterates by two, three or four elements at a time (where `T` is a tuple type).
+ - Add `.tuple_windows::<T>()` that iterates using a window of the two, three or four most recent elements.
+ - Add `.next_tuple::<T>()` method, that picks the next two, three or four elements in one go.
+ - `.interleave()` now has an accurate size hint.
+## 0.5.1
+ - Workaround module/function name clash that made racer crash on completing itertools. Only internal changes needed.
+## 0.5.0
+ - [Release announcement](https://bluss.github.io/rust/2016/09/26/itertools-0.5.0/)
+ - Renamed:
+ - `combinations` is now `tuple_combinations`
+ - `combinations_n` to `combinations`
+ - `group_by_lazy`, `chunks_lazy` to `group_by`, `chunks`
+ - `Unfold::new` to `unfold()`
+ - `RepeatCall::new` to `repeat_call()`
+ - `Zip::new` to `multizip`
+ - `PutBack::new`, `PutBackN::new` to `put_back`, `put_back_n`
+ - `PutBack::with_value` is now a builder setter, not a constructor
+ - `MultiPeek::new`, `.multipeek()` to `multipeek()`
+ - `format` to `format_with` and `format_default` to `format`
+ - `.into_rc()` to `rciter`
+ - `Partition` enum is now `Either`
+ - Module reorganization:
+ - All iterator structs are under `itertools::structs` but also reexported to the top level, for backwards compatibility
+ - All free functions are reexported at the root, `itertools::free` will be removed in the next version
+ - Removed:
+ - `ZipSlices`, use `.zip()` instead
+ - `.enumerate_from()`, `ZipTrusted`, due to being unstable
+ - `.mend_slices()`, moved to crate `odds`
+ - Stride, StrideMut, moved to crate `odds`
+ - `linspace()`, moved to crate `itertools-num`
+ - `.sort_by()`, use `.sorted_by()`
+ - `.is_empty_hint()`, use `.size_hint()`
+ - `.dropn()`, use `.dropping()`
+ - `.map_fn()`, use `.map()`
+ - `.slice()`, use `.take()` / `.skip()`
+ - helper traits in `misc`
+ - `new` constructors on iterator structs, use `Itertools` trait or free functions instead
+ - `itertools::size_hint` is now private
+ - Behaviour changes:
+ - `format` and `format_with` helpers now panic if you try to format them more than once.
+ - `repeat_call` is not double ended anymore
+ - New features:
+ - tuple flattening iterator is constructible with `cons_tuples`
+ - itertools reexports `Either` from the `either` crate. `Either<L, R>` is an iterator when `L, R` are.
+ - `MinMaxResult` now implements `Copy` and `Clone`
+ - `tuple_combinations` supports 1-4 tuples of combinations (previously just 2)
+## 0.4.19
+ - Add `.minmax_by()`
+ - Add `itertools::free::cloned`
+ - Add `itertools::free::rciter`
+ - Improve `.step(n)` slightly to take advantage of specialized Fuse better.
+## 0.4.18
+ - Only changes related to the "unstable" crate feature. This feature is more or less deprecated.
+ - Use deprecated warnings when unstable is enabled. `.enumerate_from()` will be removed imminently since it's using a deprecated libstd trait.
+## 0.4.17
+ - Fix bug in `.kmerge()` that caused it to often produce the wrong order #134
+## 0.4.16
+ - Improve precision of the `interleave_shortest` adaptor's size hint (it is now computed exactly when possible).
+## 0.4.15
+ - Fixup on top of the workaround in 0.4.14. A function in `itertools::free` was removed by mistake and now it is added back again.
+## 0.4.14
+ - Workaround an upstream regression in a Rust nightly build that broke compilation of of `itertools::free::{interleave, merge}`
+## 0.4.13
+ - Add `.minmax()` and `.minmax_by_key()`, iterator methods for finding both minimum and maximum in one scan.
+ - Add `.format_default()`, a simpler version of `.format()` (lazy formatting for iterators).
+## 0.4.12
+ - Add `.zip_eq()`, an adaptor like `.zip()` except it ensures iterators of inequal length don't pass silently (instead it panics).
+ - Add `.fold_while()`, an iterator method that is a fold that can short-circuit.
+ - Add `.partition_map()`, an iterator method that can separate elements into two collections.
+## 0.4.11
+ - Add `.get()` for `Stride{,Mut}` and `.get_mut()` for `StrideMut`
+## 0.4.10
+ - Improve performance of `.kmerge()`
+## 0.4.9
+ - Add k-ary merge adaptor `.kmerge()`
+ - Fix a bug in `.islice()` with ranges `a..b` where a `> b`.
+## 0.4.8
+ - Implement `Clone`, `Debug` for `Linspace`
+## 0.4.7
+ - Add function `diff_with()` that compares two iterators
+ - Add `.combinations_n()`, an n-ary combinations iterator
+ - Add methods `PutBack::with_value` and `PutBack::into_parts`.
+## 0.4.6
+ - Add method `.sorted()`
+ - Add module `itertools::free` with free function variants of common iterator adaptors and methods. For example `enumerate(iterable)`, `rev(iterable)`, and so on.
+## 0.4.5
+ - Add `.flatten()`
+## 0.4.4
+ - Allow composing `ZipSlices` with itself
+## 0.4.3
+ - Write `iproduct!()` as a single expression; this allows temporary values in its arguments.
+## 0.4.2
+ - Add `.fold_options()`
+ - Require Rust 1.1 or later
+## 0.4.1
+ - Update `.dropping()` to take advantage of `.nth()`
+## 0.4.0
+ - `.merge()`, `.unique()` and `.dedup()` now perform better due to not using function pointers
+ - Add free functions `enumerate()` and `rev()`
+ - Breaking changes:
+ - Return types of `.merge()` and `.merge_by()` renamed and changed
+ - Method `Merge::new` removed
+ - `.merge_by()` now takes a closure that returns bool.
+ - Return type of `.dedup()` changed
+ - Return type of `.mend_slices()` changed
+ - Return type of `.unique()` changed
+ - Removed function `times()`, struct `Times`: use a range instead
+ - Removed deprecated macro `icompr!()`
+ - Removed deprecated `FnMap` and method `.fn_map()`: use `.map_fn()`
+ - `.interleave_shortest()` is no longer guaranteed to act like fused
+## 0.3.25
+ - Rename `.sort_by()` to `.sorted_by()`. Old name is deprecated.
+ - Fix well-formedness warnings from RFC 1214, no user visible impact
+## 0.3.24
+ - Improve performance of `.merge()`'s ordering function slightly
+## 0.3.23
+ - Added `.chunks()`, similar to (and based on) `.group_by_lazy()`.
+ - Tweak linspace to match numpy.linspace and make it double ended.
+## 0.3.22
+ - Added `ZipSlices`, a fast zip for slices
+## 0.3.21
+ - Remove `Debug` impl for `Format`, it will have different use later
+## 0.3.20
+ - Optimize `.group_by_lazy()`
+## 0.3.19
+ - Added `.group_by_lazy()`, a possibly nonallocating group by
+ - Added `.format()`, a nonallocating formatting helper for iterators
+ - Remove uses of `RandomAccessIterator` since it has been deprecated in Rust.
+## 0.3.17
+ - Added (adopted) `Unfold` from Rust
+## 0.3.16
+ - Added adaptors `.unique()`, `.unique_by()`
+## 0.3.15
+ - Added method `.sort_by()`
+## 0.3.14
+ - Added adaptor `.while_some()`
+## 0.3.13
+ - Added adaptor `.interleave_shortest()`
+ - Added adaptor `.pad_using()`
+## 0.3.11
+ - Added `assert_equal` function
+## 0.3.10
+ - Bugfix `.combinations()` `size_hint`.
+## 0.3.8
+ - Added source `RepeatCall`
+## 0.3.7
+ - Added adaptor `PutBackN`
+ - Added adaptor `.combinations()`
+## 0.3.6
+ - Added `itertools::partition`, partition a sequence in place based on a predicate.
+ - Deprecate `icompr!()` with no replacement.
+## 0.3.5
+ - `.map_fn()` replaces deprecated `.fn_map()`.
+## 0.3.4
+ - `.take_while_ref()` *by-ref adaptor*
+ - `.coalesce()` *adaptor*
+ - `.mend_slices()` *adaptor*
+## 0.3.3
+ - `.dropping_back()` *method*
+ - `.fold1()` *method*
+ - `.is_empty_hint()` *method*
diff --git a/rust/hw/char/pl011/vendor/itertools/Cargo.lock b/rust/hw/char/pl011/vendor/itertools/Cargo.lock
new file mode 100644
index 0000000000..76936c9eea
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/Cargo.lock
@@ -0,0 +1,681 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "anes"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bumpalo"
+version = "3.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
+
+[[package]]
+name = "cast"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "ciborium"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f"
+dependencies = [
+ "ciborium-io",
+ "ciborium-ll",
+ "serde",
+]
+
+[[package]]
+name = "ciborium-io"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369"
+
+[[package]]
+name = "ciborium-ll"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b"
+dependencies = [
+ "ciborium-io",
+ "half",
+]
+
+[[package]]
+name = "clap"
+version = "3.2.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750"
+dependencies = [
+ "bitflags",
+ "clap_lex",
+ "indexmap",
+ "textwrap",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
+dependencies = [
+ "os_str_bytes",
+]
+
+[[package]]
+name = "criterion"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb"
+dependencies = [
+ "anes",
+ "atty",
+ "cast",
+ "ciborium",
+ "clap",
+ "criterion-plot",
+ "itertools 0.10.4",
+ "lazy_static",
+ "num-traits",
+ "oorandom",
+ "plotters",
+ "rayon",
+ "regex",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "tinytemplate",
+ "walkdir",
+]
+
+[[package]]
+name = "criterion-plot"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
+dependencies = [
+ "cast",
+ "itertools 0.10.4",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
+dependencies = [
+ "cfg-if",
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "crossbeam-utils",
+ "memoffset",
+ "once_cell",
+ "scopeguard",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+]
+
+[[package]]
+name = "either"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+
+[[package]]
+name = "getrandom"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "half"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8bf247779e67a9082a4790b45e71ac7cfd1321331a5c856a74a9faebdab78d0"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itertools"
+version = "0.11.0"
+dependencies = [
+ "criterion",
+ "either",
+ "paste",
+ "permutohedron",
+ "quickcheck",
+ "rand",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
+
+[[package]]
+name = "js-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.133"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966"
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memoffset"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
+
+[[package]]
+name = "oorandom"
+version = "11.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
+
+[[package]]
+name = "os_str_bytes"
+version = "6.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
+
+[[package]]
+name = "paste"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
+
+[[package]]
+name = "permutohedron"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b687ff7b5da449d39e418ad391e5e08da53ec334903ddbb921db208908fc372c"
+
+[[package]]
+name = "plotters"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97"
+dependencies = [
+ "num-traits",
+ "plotters-backend",
+ "plotters-svg",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "plotters-backend"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142"
+
+[[package]]
+name = "plotters-svg"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f"
+dependencies = [
+ "plotters-backend",
+]
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.43"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quickcheck"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f"
+dependencies = [
+ "rand",
+ "rand_core",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "getrandom",
+ "libc",
+ "rand_chacha",
+ "rand_core",
+ "rand_hc",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core",
+]
+
+[[package]]
+name = "rayon"
+version = "1.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
+dependencies = [
+ "autocfg",
+ "crossbeam-deque",
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
+dependencies = [
+ "crossbeam-channel",
+ "crossbeam-deque",
+ "crossbeam-utils",
+ "num_cpus",
+]
+
+[[package]]
+name = "regex"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
+dependencies = [
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
+
+[[package]]
+name = "ryu"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
+
+[[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 = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "serde"
+version = "1.0.144"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.144"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.85"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16"
+
+[[package]]
+name = "tinytemplate"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
+
+[[package]]
+name = "walkdir"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+
+[[package]]
+name = "web-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/rust/hw/char/pl011/vendor/itertools/Cargo.toml b/rust/hw/char/pl011/vendor/itertools/Cargo.toml
new file mode 100644
index 0000000000..df3cbd8fd3
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/Cargo.toml
@@ -0,0 +1,101 @@
+# 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 = "2018"
+rust-version = "1.36.0"
+name = "itertools"
+version = "0.11.0"
+authors = ["bluss"]
+exclude = ["/bors.toml"]
+description = "Extra iterator adaptors, iterator methods, free functions, and macros."
+documentation = "https://docs.rs/itertools/"
+readme = "README.md"
+keywords = [
+ "iterator",
+ "data-structure",
+ "zip",
+ "product",
+ "group-by",
+]
+categories = [
+ "algorithms",
+ "rust-patterns",
+]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/rust-itertools/itertools"
+
+[profile.bench]
+debug = 2
+
+[lib]
+test = false
+bench = false
+
+[[bench]]
+name = "tuple_combinations"
+harness = false
+
+[[bench]]
+name = "tuples"
+harness = false
+
+[[bench]]
+name = "fold_specialization"
+harness = false
+
+[[bench]]
+name = "combinations_with_replacement"
+harness = false
+
+[[bench]]
+name = "tree_fold1"
+harness = false
+
+[[bench]]
+name = "bench1"
+harness = false
+
+[[bench]]
+name = "combinations"
+harness = false
+
+[[bench]]
+name = "powerset"
+harness = false
+
+[dependencies.either]
+version = "1.0"
+default-features = false
+
+[dev-dependencies.criterion]
+version = "0.4.0"
+
+[dev-dependencies.paste]
+version = "1.0.0"
+
+[dev-dependencies.permutohedron]
+version = "0.2"
+
+[dev-dependencies.quickcheck]
+version = "0.9"
+default_features = false
+
+[dev-dependencies.rand]
+version = "0.7"
+
+[features]
+default = ["use_std"]
+use_alloc = []
+use_std = [
+ "use_alloc",
+ "either/use_std",
+]
diff --git a/rust/hw/char/pl011/vendor/itertools/LICENSE-APACHE b/rust/hw/char/pl011/vendor/itertools/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ 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
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/rust/hw/char/pl011/vendor/itertools/LICENSE-MIT b/rust/hw/char/pl011/vendor/itertools/LICENSE-MIT
new file mode 100644
index 0000000000..9203baa055
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2015
+
+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/rust/hw/char/pl011/vendor/itertools/README.md b/rust/hw/char/pl011/vendor/itertools/README.md
new file mode 100644
index 0000000000..626d10d0d0
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/README.md
@@ -0,0 +1,44 @@
+# Itertools
+
+Extra iterator adaptors, functions and macros.
+
+Please read the [API documentation here](https://docs.rs/itertools/).
+
+[](https://github.com/rust-itertools/itertools/actions)
+[](https://crates.io/crates/itertools)
+
+How to use with Cargo:
+
+```toml
+[dependencies]
+itertools = "0.11.0"
+```
+
+How to use in your crate:
+
+```rust
+use itertools::Itertools;
+```
+
+## How to contribute
+
+- Fix a bug or implement a new thing
+- Include tests for your new feature, preferably a QuickCheck test
+- Make a Pull Request
+
+For new features, please first consider filing a PR to [rust-lang/rust](https://github.com/rust-lang/rust),
+adding your new feature to the `Iterator` trait of the standard library, if you believe it is reasonable.
+If it isn't accepted there, proposing it for inclusion in ``itertools`` is a good idea.
+The reason for doing is this is so that we avoid future breakage as with ``.flatten()``.
+However, if your feature involves heap allocation, such as storing elements in a ``Vec<T>``,
+then it can't be accepted into ``libcore``, and you should propose it for ``itertools`` directly instead.
+
+## License
+
+Dual-licensed to be compatible with the Rust project.
+
+Licensed under the Apache License, Version 2.0
+https://www.apache.org/licenses/LICENSE-2.0 or the MIT license
+https://opensource.org/licenses/MIT, at your
+option. This file may not be copied, modified, or distributed
+except according to those terms.
diff --git a/rust/hw/char/pl011/vendor/itertools/benches/bench1.rs b/rust/hw/char/pl011/vendor/itertools/benches/bench1.rs
new file mode 100644
index 0000000000..71278d17b6
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/benches/bench1.rs
@@ -0,0 +1,877 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use itertools::Itertools;
+use itertools::free::cloned;
+use itertools::iproduct;
+
+use std::iter::repeat;
+use std::cmp;
+use std::ops::{Add, Range};
+
+mod extra;
+
+use crate::extra::ZipSlices;
+
+fn slice_iter(c: &mut Criterion) {
+ let xs: Vec<_> = repeat(1i32).take(20).collect();
+
+ c.bench_function("slice iter", move |b| {
+ b.iter(|| for elt in xs.iter() {
+ black_box(elt);
+ })
+ });
+}
+
+fn slice_iter_rev(c: &mut Criterion) {
+ let xs: Vec<_> = repeat(1i32).take(20).collect();
+
+ c.bench_function("slice iter rev", move |b| {
+ b.iter(|| for elt in xs.iter().rev() {
+ black_box(elt);
+ })
+ });
+}
+
+fn zip_default_zip(c: &mut Criterion) {
+ let xs = vec![0; 1024];
+ let ys = vec![0; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zip default zip", move |b| {
+ b.iter(|| {
+ for (&x, &y) in xs.iter().zip(&ys) {
+ black_box(x);
+ black_box(y);
+ }
+ })
+ });
+}
+
+fn zipdot_i32_default_zip(c: &mut Criterion) {
+ let xs = vec![2; 1024];
+ let ys = vec![2; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zipdot i32 default zip", move |b| {
+ b.iter(|| {
+ let mut s = 0;
+ for (&x, &y) in xs.iter().zip(&ys) {
+ s += x * y;
+ }
+ s
+ })
+ });
+}
+
+fn zipdot_f32_default_zip(c: &mut Criterion) {
+ let xs = vec![2f32; 1024];
+ let ys = vec![2f32; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zipdot f32 default zip", move |b| {
+ b.iter(|| {
+ let mut s = 0.;
+ for (&x, &y) in xs.iter().zip(&ys) {
+ s += x * y;
+ }
+ s
+ })
+ });
+}
+
+fn zip_default_zip3(c: &mut Criterion) {
+ let xs = vec![0; 1024];
+ let ys = vec![0; 768];
+ let zs = vec![0; 766];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+ let zs = black_box(zs);
+
+ c.bench_function("zip default zip3", move |b| {
+ b.iter(|| {
+ for ((&x, &y), &z) in xs.iter().zip(&ys).zip(&zs) {
+ black_box(x);
+ black_box(y);
+ black_box(z);
+ }
+ })
+ });
+}
+
+fn zip_slices_ziptuple(c: &mut Criterion) {
+ let xs = vec![0; 1024];
+ let ys = vec![0; 768];
+
+ c.bench_function("zip slices ziptuple", move |b| {
+ b.iter(|| {
+ let xs = black_box(&xs);
+ let ys = black_box(&ys);
+ for (&x, &y) in itertools::multizip((xs, ys)) {
+ black_box(x);
+ black_box(y);
+ }
+ })
+ });
+}
+
+fn zipslices(c: &mut Criterion) {
+ let xs = vec![0; 1024];
+ let ys = vec![0; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zipslices", move |b| {
+ b.iter(|| {
+ for (&x, &y) in ZipSlices::new(&xs, &ys) {
+ black_box(x);
+ black_box(y);
+ }
+ })
+ });
+}
+
+fn zipslices_mut(c: &mut Criterion) {
+ let xs = vec![0; 1024];
+ let ys = vec![0; 768];
+ let xs = black_box(xs);
+ let mut ys = black_box(ys);
+
+ c.bench_function("zipslices mut", move |b| {
+ b.iter(|| {
+ for (&x, &mut y) in ZipSlices::from_slices(&xs[..], &mut ys[..]) {
+ black_box(x);
+ black_box(y);
+ }
+ })
+ });
+}
+
+fn zipdot_i32_zipslices(c: &mut Criterion) {
+ let xs = vec![2; 1024];
+ let ys = vec![2; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zipdot i32 zipslices", move |b| {
+ b.iter(|| {
+ let mut s = 0i32;
+ for (&x, &y) in ZipSlices::new(&xs, &ys) {
+ s += x * y;
+ }
+ s
+ })
+ });
+}
+
+fn zipdot_f32_zipslices(c: &mut Criterion) {
+ let xs = vec![2f32; 1024];
+ let ys = vec![2f32; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zipdot f32 zipslices", move |b| {
+ b.iter(|| {
+ let mut s = 0.;
+ for (&x, &y) in ZipSlices::new(&xs, &ys) {
+ s += x * y;
+ }
+ s
+ })
+ });
+}
+
+fn zip_checked_counted_loop(c: &mut Criterion) {
+ let xs = vec![0; 1024];
+ let ys = vec![0; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zip checked counted loop", move |b| {
+ b.iter(|| {
+ // Must slice to equal lengths, and then bounds checks are eliminated!
+ let len = cmp::min(xs.len(), ys.len());
+ let xs = &xs[..len];
+ let ys = &ys[..len];
+
+ for i in 0..len {
+ let x = xs[i];
+ let y = ys[i];
+ black_box(x);
+ black_box(y);
+ }
+ })
+ });
+}
+
+fn zipdot_i32_checked_counted_loop(c: &mut Criterion) {
+ let xs = vec![2; 1024];
+ let ys = vec![2; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zipdot i32 checked counted loop", move |b| {
+ b.iter(|| {
+ // Must slice to equal lengths, and then bounds checks are eliminated!
+ let len = cmp::min(xs.len(), ys.len());
+ let xs = &xs[..len];
+ let ys = &ys[..len];
+
+ let mut s = 0i32;
+
+ for i in 0..len {
+ s += xs[i] * ys[i];
+ }
+ s
+ })
+ });
+}
+
+fn zipdot_f32_checked_counted_loop(c: &mut Criterion) {
+ let xs = vec![2f32; 1024];
+ let ys = vec![2f32; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zipdot f32 checked counted loop", move |b| {
+ b.iter(|| {
+ // Must slice to equal lengths, and then bounds checks are eliminated!
+ let len = cmp::min(xs.len(), ys.len());
+ let xs = &xs[..len];
+ let ys = &ys[..len];
+
+ let mut s = 0.;
+
+ for i in 0..len {
+ s += xs[i] * ys[i];
+ }
+ s
+ })
+ });
+}
+
+fn zipdot_f32_checked_counted_unrolled_loop(c: &mut Criterion) {
+ let xs = vec![2f32; 1024];
+ let ys = vec![2f32; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zipdot f32 checked counted unrolled loop", move |b| {
+ b.iter(|| {
+ // Must slice to equal lengths, and then bounds checks are eliminated!
+ let len = cmp::min(xs.len(), ys.len());
+ let mut xs = &xs[..len];
+ let mut ys = &ys[..len];
+
+ let mut s = 0.;
+ let (mut p0, mut p1, mut p2, mut p3, mut p4, mut p5, mut p6, mut p7) =
+ (0., 0., 0., 0., 0., 0., 0., 0.);
+
+ // how to unroll and have bounds checks eliminated (by cristicbz)
+ // split sum into eight parts to enable vectorization (by bluss)
+ while xs.len() >= 8 {
+ p0 += xs[0] * ys[0];
+ p1 += xs[1] * ys[1];
+ p2 += xs[2] * ys[2];
+ p3 += xs[3] * ys[3];
+ p4 += xs[4] * ys[4];
+ p5 += xs[5] * ys[5];
+ p6 += xs[6] * ys[6];
+ p7 += xs[7] * ys[7];
+
+ xs = &xs[8..];
+ ys = &ys[8..];
+ }
+ s += p0 + p4;
+ s += p1 + p5;
+ s += p2 + p6;
+ s += p3 + p7;
+
+ for i in 0..xs.len() {
+ s += xs[i] * ys[i];
+ }
+ s
+ })
+ });
+}
+
+fn zip_unchecked_counted_loop(c: &mut Criterion) {
+ let xs = vec![0; 1024];
+ let ys = vec![0; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zip unchecked counted loop", move |b| {
+ b.iter(|| {
+ let len = cmp::min(xs.len(), ys.len());
+ for i in 0..len {
+ unsafe {
+ let x = *xs.get_unchecked(i);
+ let y = *ys.get_unchecked(i);
+ black_box(x);
+ black_box(y);
+ }
+ }
+ })
+ });
+}
+
+fn zipdot_i32_unchecked_counted_loop(c: &mut Criterion) {
+ let xs = vec![2; 1024];
+ let ys = vec![2; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zipdot i32 unchecked counted loop", move |b| {
+ b.iter(|| {
+ let len = cmp::min(xs.len(), ys.len());
+ let mut s = 0i32;
+ for i in 0..len {
+ unsafe {
+ let x = *xs.get_unchecked(i);
+ let y = *ys.get_unchecked(i);
+ s += x * y;
+ }
+ }
+ s
+ })
+ });
+}
+
+fn zipdot_f32_unchecked_counted_loop(c: &mut Criterion) {
+ let xs = vec![2.; 1024];
+ let ys = vec![2.; 768];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+
+ c.bench_function("zipdot f32 unchecked counted loop", move |b| {
+ b.iter(|| {
+ let len = cmp::min(xs.len(), ys.len());
+ let mut s = 0f32;
+ for i in 0..len {
+ unsafe {
+ let x = *xs.get_unchecked(i);
+ let y = *ys.get_unchecked(i);
+ s += x * y;
+ }
+ }
+ s
+ })
+ });
+}
+
+fn zip_unchecked_counted_loop3(c: &mut Criterion) {
+ let xs = vec![0; 1024];
+ let ys = vec![0; 768];
+ let zs = vec![0; 766];
+ let xs = black_box(xs);
+ let ys = black_box(ys);
+ let zs = black_box(zs);
+
+ c.bench_function("zip unchecked counted loop3", move |b| {
+ b.iter(|| {
+ let len = cmp::min(xs.len(), cmp::min(ys.len(), zs.len()));
+ for i in 0..len {
+ unsafe {
+ let x = *xs.get_unchecked(i);
+ let y = *ys.get_unchecked(i);
+ let z = *zs.get_unchecked(i);
+ black_box(x);
+ black_box(y);
+ black_box(z);
+ }
+ }
+ })
+ });
+}
+
+fn group_by_lazy_1(c: &mut Criterion) {
+ let mut data = vec![0; 1024];
+ for (index, elt) in data.iter_mut().enumerate() {
+ *elt = index / 10;
+ }
+
+ let data = black_box(data);
+
+ c.bench_function("group by lazy 1", move |b| {
+ b.iter(|| {
+ for (_key, group) in &data.iter().group_by(|elt| **elt) {
+ for elt in group {
+ black_box(elt);
+ }
+ }
+ })
+ });
+}
+
+fn group_by_lazy_2(c: &mut Criterion) {
+ let mut data = vec![0; 1024];
+ for (index, elt) in data.iter_mut().enumerate() {
+ *elt = index / 2;
+ }
+
+ let data = black_box(data);
+
+ c.bench_function("group by lazy 2", move |b| {
+ b.iter(|| {
+ for (_key, group) in &data.iter().group_by(|elt| **elt) {
+ for elt in group {
+ black_box(elt);
+ }
+ }
+ })
+ });
+}
+
+fn slice_chunks(c: &mut Criterion) {
+ let data = vec![0; 1024];
+
+ let data = black_box(data);
+ let sz = black_box(10);
+
+ c.bench_function("slice chunks", move |b| {
+ b.iter(|| {
+ for group in data.chunks(sz) {
+ for elt in group {
+ black_box(elt);
+ }
+ }
+ })
+ });
+}
+
+fn chunks_lazy_1(c: &mut Criterion) {
+ let data = vec![0; 1024];
+
+ let data = black_box(data);
+ let sz = black_box(10);
+
+ c.bench_function("chunks lazy 1", move |b| {
+ b.iter(|| {
+ for group in &data.iter().chunks(sz) {
+ for elt in group {
+ black_box(elt);
+ }
+ }
+ })
+ });
+}
+
+fn equal(c: &mut Criterion) {
+ let data = vec![7; 1024];
+ let l = data.len();
+ let alpha = black_box(&data[1..]);
+ let beta = black_box(&data[..l - 1]);
+
+ c.bench_function("equal", move |b| {
+ b.iter(|| {
+ itertools::equal(alpha, beta)
+ })
+ });
+}
+
+fn merge_default(c: &mut Criterion) {
+ let mut data1 = vec![0; 1024];
+ let mut data2 = vec![0; 800];
+ let mut x = 0;
+ for (_, elt) in data1.iter_mut().enumerate() {
+ *elt = x;
+ x += 1;
+ }
+
+ let mut y = 0;
+ for (i, elt) in data2.iter_mut().enumerate() {
+ *elt += y;
+ if i % 3 == 0 {
+ y += 3;
+ } else {
+ y += 0;
+ }
+ }
+ let data1 = black_box(data1);
+ let data2 = black_box(data2);
+
+ c.bench_function("merge default", move |b| {
+ b.iter(|| {
+ data1.iter().merge(&data2).count()
+ })
+ });
+}
+
+fn merge_by_cmp(c: &mut Criterion) {
+ let mut data1 = vec![0; 1024];
+ let mut data2 = vec![0; 800];
+ let mut x = 0;
+ for (_, elt) in data1.iter_mut().enumerate() {
+ *elt = x;
+ x += 1;
+ }
+
+ let mut y = 0;
+ for (i, elt) in data2.iter_mut().enumerate() {
+ *elt += y;
+ if i % 3 == 0 {
+ y += 3;
+ } else {
+ y += 0;
+ }
+ }
+ let data1 = black_box(data1);
+ let data2 = black_box(data2);
+
+ c.bench_function("merge by cmp", move |b| {
+ b.iter(|| {
+ data1.iter().merge_by(&data2, PartialOrd::le).count()
+ })
+ });
+}
+
+fn merge_by_lt(c: &mut Criterion) {
+ let mut data1 = vec![0; 1024];
+ let mut data2 = vec![0; 800];
+ let mut x = 0;
+ for (_, elt) in data1.iter_mut().enumerate() {
+ *elt = x;
+ x += 1;
+ }
+
+ let mut y = 0;
+ for (i, elt) in data2.iter_mut().enumerate() {
+ *elt += y;
+ if i % 3 == 0 {
+ y += 3;
+ } else {
+ y += 0;
+ }
+ }
+ let data1 = black_box(data1);
+ let data2 = black_box(data2);
+
+ c.bench_function("merge by lt", move |b| {
+ b.iter(|| {
+ data1.iter().merge_by(&data2, |a, b| a <= b).count()
+ })
+ });
+}
+
+fn kmerge_default(c: &mut Criterion) {
+ let mut data1 = vec![0; 1024];
+ let mut data2 = vec![0; 800];
+ let mut x = 0;
+ for (_, elt) in data1.iter_mut().enumerate() {
+ *elt = x;
+ x += 1;
+ }
+
+ let mut y = 0;
+ for (i, elt) in data2.iter_mut().enumerate() {
+ *elt += y;
+ if i % 3 == 0 {
+ y += 3;
+ } else {
+ y += 0;
+ }
+ }
+ let data1 = black_box(data1);
+ let data2 = black_box(data2);
+ let its = &[data1.iter(), data2.iter()];
+
+ c.bench_function("kmerge default", move |b| {
+ b.iter(|| {
+ its.iter().cloned().kmerge().count()
+ })
+ });
+}
+
+fn kmerge_tenway(c: &mut Criterion) {
+ let mut data = vec![0; 10240];
+
+ let mut state = 1729u16;
+ fn rng(state: &mut u16) -> u16 {
+ let new = state.wrapping_mul(31421) + 6927;
+ *state = new;
+ new
+ }
+
+ for elt in &mut data {
+ *elt = rng(&mut state);
+ }
+
+ let mut chunks = Vec::new();
+ let mut rest = &mut data[..];
+ while rest.len() > 0 {
+ let chunk_len = 1 + rng(&mut state) % 512;
+ let chunk_len = cmp::min(rest.len(), chunk_len as usize);
+ let (fst, tail) = {rest}.split_at_mut(chunk_len);
+ fst.sort();
+ chunks.push(fst.iter().cloned());
+ rest = tail;
+ }
+
+ // println!("Chunk lengths: {}", chunks.iter().format_with(", ", |elt, f| f(&elt.len())));
+
+ c.bench_function("kmerge tenway", move |b| {
+ b.iter(|| {
+ chunks.iter().cloned().kmerge().count()
+ })
+ });
+}
+
+fn fast_integer_sum<I>(iter: I) -> I::Item
+ where I: IntoIterator,
+ I::Item: Default + Add<Output=I::Item>
+{
+ iter.into_iter().fold(<_>::default(), |x, y| x + y)
+}
+
+fn step_vec_2(c: &mut Criterion) {
+ let v = vec![0; 1024];
+
+ c.bench_function("step vec 2", move |b| {
+ b.iter(|| {
+ fast_integer_sum(cloned(v.iter().step_by(2)))
+ })
+ });
+}
+
+fn step_vec_10(c: &mut Criterion) {
+ let v = vec![0; 1024];
+
+ c.bench_function("step vec 10", move |b| {
+ b.iter(|| {
+ fast_integer_sum(cloned(v.iter().step_by(10)))
+ })
+ });
+}
+
+fn step_range_2(c: &mut Criterion) {
+ let v = black_box(0..1024);
+
+ c.bench_function("step range 2", move |b| {
+ b.iter(|| {
+ fast_integer_sum(v.clone().step_by(2))
+ })
+ });
+}
+
+fn step_range_10(c: &mut Criterion) {
+ let v = black_box(0..1024);
+
+ c.bench_function("step range 10", move |b| {
+ b.iter(|| {
+ fast_integer_sum(v.clone().step_by(10))
+ })
+ });
+}
+
+fn cartesian_product_iterator(c: &mut Criterion) {
+ let xs = vec![0; 16];
+
+ c.bench_function("cartesian product iterator", move |b| {
+ b.iter(|| {
+ let mut sum = 0;
+ for (&x, &y, &z) in iproduct!(&xs, &xs, &xs) {
+ sum += x;
+ sum += y;
+ sum += z;
+ }
+ sum
+ })
+ });
+}
+
+fn cartesian_product_fold(c: &mut Criterion) {
+ let xs = vec![0; 16];
+
+ c.bench_function("cartesian product fold", move |b| {
+ b.iter(|| {
+ let mut sum = 0;
+ iproduct!(&xs, &xs, &xs).fold((), |(), (&x, &y, &z)| {
+ sum += x;
+ sum += y;
+ sum += z;
+ });
+ sum
+ })
+ });
+}
+
+fn multi_cartesian_product_iterator(c: &mut Criterion) {
+ let xs = [vec![0; 16], vec![0; 16], vec![0; 16]];
+
+ c.bench_function("multi cartesian product iterator", move |b| {
+ b.iter(|| {
+ let mut sum = 0;
+ for x in xs.iter().multi_cartesian_product() {
+ sum += x[0];
+ sum += x[1];
+ sum += x[2];
+ }
+ sum
+ })
+ });
+}
+
+fn multi_cartesian_product_fold(c: &mut Criterion) {
+ let xs = [vec![0; 16], vec![0; 16], vec![0; 16]];
+
+ c.bench_function("multi cartesian product fold", move |b| {
+ b.iter(|| {
+ let mut sum = 0;
+ xs.iter().multi_cartesian_product().fold((), |(), x| {
+ sum += x[0];
+ sum += x[1];
+ sum += x[2];
+ });
+ sum
+ })
+ });
+}
+
+fn cartesian_product_nested_for(c: &mut Criterion) {
+ let xs = vec![0; 16];
+
+ c.bench_function("cartesian product nested for", move |b| {
+ b.iter(|| {
+ let mut sum = 0;
+ for &x in &xs {
+ for &y in &xs {
+ for &z in &xs {
+ sum += x;
+ sum += y;
+ sum += z;
+ }
+ }
+ }
+ sum
+ })
+ });
+}
+
+fn all_equal(c: &mut Criterion) {
+ let mut xs = vec![0; 5_000_000];
+ xs.extend(vec![1; 5_000_000]);
+
+ c.bench_function("all equal", move |b| {
+ b.iter(|| xs.iter().all_equal())
+ });
+}
+
+fn all_equal_for(c: &mut Criterion) {
+ let mut xs = vec![0; 5_000_000];
+ xs.extend(vec![1; 5_000_000]);
+
+ c.bench_function("all equal for", move |b| {
+ b.iter(|| {
+ for &x in &xs {
+ if x != xs[0] {
+ return false;
+ }
+ }
+ true
+ })
+ });
+}
+
+fn all_equal_default(c: &mut Criterion) {
+ let mut xs = vec![0; 5_000_000];
+ xs.extend(vec![1; 5_000_000]);
+
+ c.bench_function("all equal default", move |b| {
+ b.iter(|| xs.iter().dedup().nth(1).is_none())
+ });
+}
+
+const PERM_COUNT: usize = 6;
+
+fn permutations_iter(c: &mut Criterion) {
+ struct NewIterator(Range<usize>);
+
+ impl Iterator for NewIterator {
+ type Item = usize;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next()
+ }
+ }
+
+ c.bench_function("permutations iter", move |b| {
+ b.iter(|| {
+ for _ in NewIterator(0..PERM_COUNT).permutations(PERM_COUNT) {
+
+ }
+ })
+ });
+}
+
+fn permutations_range(c: &mut Criterion) {
+ c.bench_function("permutations range", move |b| {
+ b.iter(|| {
+ for _ in (0..PERM_COUNT).permutations(PERM_COUNT) {
+
+ }
+ })
+ });
+}
+
+fn permutations_slice(c: &mut Criterion) {
+ let v = (0..PERM_COUNT).collect_vec();
+
+ c.bench_function("permutations slice", move |b| {
+ b.iter(|| {
+ for _ in v.as_slice().iter().permutations(PERM_COUNT) {
+
+ }
+ })
+ });
+}
+
+criterion_group!(
+ benches,
+ slice_iter,
+ slice_iter_rev,
+ zip_default_zip,
+ zipdot_i32_default_zip,
+ zipdot_f32_default_zip,
+ zip_default_zip3,
+ zip_slices_ziptuple,
+ zipslices,
+ zipslices_mut,
+ zipdot_i32_zipslices,
+ zipdot_f32_zipslices,
+ zip_checked_counted_loop,
+ zipdot_i32_checked_counted_loop,
+ zipdot_f32_checked_counted_loop,
+ zipdot_f32_checked_counted_unrolled_loop,
+ zip_unchecked_counted_loop,
+ zipdot_i32_unchecked_counted_loop,
+ zipdot_f32_unchecked_counted_loop,
+ zip_unchecked_counted_loop3,
+ group_by_lazy_1,
+ group_by_lazy_2,
+ slice_chunks,
+ chunks_lazy_1,
+ equal,
+ merge_default,
+ merge_by_cmp,
+ merge_by_lt,
+ kmerge_default,
+ kmerge_tenway,
+ step_vec_2,
+ step_vec_10,
+ step_range_2,
+ step_range_10,
+ cartesian_product_iterator,
+ cartesian_product_fold,
+ multi_cartesian_product_iterator,
+ multi_cartesian_product_fold,
+ cartesian_product_nested_for,
+ all_equal,
+ all_equal_for,
+ all_equal_default,
+ permutations_iter,
+ permutations_range,
+ permutations_slice,
+);
+criterion_main!(benches);
diff --git a/rust/hw/char/pl011/vendor/itertools/benches/combinations.rs b/rust/hw/char/pl011/vendor/itertools/benches/combinations.rs
new file mode 100644
index 0000000000..e7433a4cb0
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/benches/combinations.rs
@@ -0,0 +1,125 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use itertools::Itertools;
+
+// approximate 100_000 iterations for each combination
+const N1: usize = 100_000;
+const N2: usize = 448;
+const N3: usize = 86;
+const N4: usize = 41;
+const N14: usize = 21;
+
+fn comb_for1(c: &mut Criterion) {
+ c.bench_function("comb for1", move |b| {
+ b.iter(|| {
+ for i in 0..N1 {
+ black_box(vec![i]);
+ }
+ })
+ });
+}
+
+fn comb_for2(c: &mut Criterion) {
+ c.bench_function("comb for2", move |b| {
+ b.iter(|| {
+ for i in 0..N2 {
+ for j in (i + 1)..N2 {
+ black_box(vec![i, j]);
+ }
+ }
+ })
+ });
+}
+
+fn comb_for3(c: &mut Criterion) {
+ c.bench_function("comb for3", move |b| {
+ b.iter(|| {
+ for i in 0..N3 {
+ for j in (i + 1)..N3 {
+ for k in (j + 1)..N3 {
+ black_box(vec![i, j, k]);
+ }
+ }
+ }
+ })
+ });
+}
+
+fn comb_for4(c: &mut Criterion) {
+ c.bench_function("comb for4", move |b| {
+ b.iter(|| {
+ for i in 0..N4 {
+ for j in (i + 1)..N4 {
+ for k in (j + 1)..N4 {
+ for l in (k + 1)..N4 {
+ black_box(vec![i, j, k, l]);
+ }
+ }
+ }
+ }
+ })
+ });
+}
+
+fn comb_c1(c: &mut Criterion) {
+ c.bench_function("comb c1", move |b| {
+ b.iter(|| {
+ for combo in (0..N1).combinations(1) {
+ black_box(combo);
+ }
+ })
+ });
+}
+
+fn comb_c2(c: &mut Criterion) {
+ c.bench_function("comb c2", move |b| {
+ b.iter(|| {
+ for combo in (0..N2).combinations(2) {
+ black_box(combo);
+ }
+ })
+ });
+}
+
+fn comb_c3(c: &mut Criterion) {
+ c.bench_function("comb c3", move |b| {
+ b.iter(|| {
+ for combo in (0..N3).combinations(3) {
+ black_box(combo);
+ }
+ })
+ });
+}
+
+fn comb_c4(c: &mut Criterion) {
+ c.bench_function("comb c4", move |b| {
+ b.iter(|| {
+ for combo in (0..N4).combinations(4) {
+ black_box(combo);
+ }
+ })
+ });
+}
+
+fn comb_c14(c: &mut Criterion) {
+ c.bench_function("comb c14", move |b| {
+ b.iter(|| {
+ for combo in (0..N14).combinations(14) {
+ black_box(combo);
+ }
+ })
+ });
+}
+
+criterion_group!(
+ benches,
+ comb_for1,
+ comb_for2,
+ comb_for3,
+ comb_for4,
+ comb_c1,
+ comb_c2,
+ comb_c3,
+ comb_c4,
+ comb_c14,
+);
+criterion_main!(benches);
diff --git a/rust/hw/char/pl011/vendor/itertools/benches/combinations_with_replacement.rs b/rust/hw/char/pl011/vendor/itertools/benches/combinations_with_replacement.rs
new file mode 100644
index 0000000000..8e4fa3dc3b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/benches/combinations_with_replacement.rs
@@ -0,0 +1,40 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use itertools::Itertools;
+
+fn comb_replacement_n10_k5(c: &mut Criterion) {
+ c.bench_function("comb replacement n10k5", move |b| {
+ b.iter(|| {
+ for i in (0..10).combinations_with_replacement(5) {
+ black_box(i);
+ }
+ })
+ });
+}
+
+fn comb_replacement_n5_k10(c: &mut Criterion) {
+ c.bench_function("comb replacement n5 k10", move |b| {
+ b.iter(|| {
+ for i in (0..5).combinations_with_replacement(10) {
+ black_box(i);
+ }
+ })
+ });
+}
+
+fn comb_replacement_n10_k10(c: &mut Criterion) {
+ c.bench_function("comb replacement n10 k10", move |b| {
+ b.iter(|| {
+ for i in (0..10).combinations_with_replacement(10) {
+ black_box(i);
+ }
+ })
+ });
+}
+
+criterion_group!(
+ benches,
+ comb_replacement_n10_k5,
+ comb_replacement_n5_k10,
+ comb_replacement_n10_k10,
+);
+criterion_main!(benches);
--git a/rust/hw/char/pl011/vendor/itertools/benches/extra/mod.rs b/rust/hw/char/pl011/vendor/itertools/benches/extra/mod.rs
new file mode 100644
index 0000000000..52fe5cc3fe
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/benches/extra/mod.rs
@@ -0,0 +1,2 @@
+pub use self::zipslices::ZipSlices;
+mod zipslices;
--git a/rust/hw/char/pl011/vendor/itertools/benches/extra/zipslices.rs b/rust/hw/char/pl011/vendor/itertools/benches/extra/zipslices.rs
new file mode 100644
index 0000000000..633be59068
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/benches/extra/zipslices.rs
@@ -0,0 +1,188 @@
+use std::cmp;
+
+// Note: There are different ways to implement ZipSlices.
+// This version performed the best in benchmarks.
+//
+// I also implemented a version with three pointers (tptr, tend, uptr),
+// that mimiced slice::Iter and only checked bounds by using tptr == tend,
+// but that was inferior to this solution.
+
+/// An iterator which iterates two slices simultaneously.
+///
+/// `ZipSlices` acts like a double-ended `.zip()` iterator.
+///
+/// It was intended to be more efficient than `.zip()`, and it was, then
+/// rustc changed how it optimizes so it can not promise improved performance
+/// at this time.
+///
+/// Note that elements past the end of the shortest of the two slices are ignored.
+///
+/// Iterator element type for `ZipSlices<T, U>` is `(T::Item, U::Item)`. For example,
+/// for a `ZipSlices<&'a [A], &'b mut [B]>`, the element type is `(&'a A, &'b mut B)`.
+#[derive(Clone)]
+pub struct ZipSlices<T, U> {
+ t: T,
+ u: U,
+ len: usize,
+ index: usize,
+}
+
+impl<'a, 'b, A, B> ZipSlices<&'a [A], &'b [B]> {
+ /// Create a new `ZipSlices` from slices `a` and `b`.
+ ///
+ /// Act like a double-ended `.zip()` iterator, but more efficiently.
+ ///
+ /// Note that elements past the end of the shortest of the two slices are ignored.
+ #[inline(always)]
+ pub fn new(a: &'a [A], b: &'b [B]) -> Self {
+ let minl = cmp::min(a.len(), b.len());
+ ZipSlices {
+ t: a,
+ u: b,
+ len: minl,
+ index: 0,
+ }
+ }
+}
+
+impl<T, U> ZipSlices<T, U>
+ where T: Slice,
+ U: Slice
+{
+ /// Create a new `ZipSlices` from slices `a` and `b`.
+ ///
+ /// Act like a double-ended `.zip()` iterator, but more efficiently.
+ ///
+ /// Note that elements past the end of the shortest of the two slices are ignored.
+ #[inline(always)]
+ pub fn from_slices(a: T, b: U) -> Self {
+ let minl = cmp::min(a.len(), b.len());
+ ZipSlices {
+ t: a,
+ u: b,
+ len: minl,
+ index: 0,
+ }
+ }
+}
+
+impl<T, U> Iterator for ZipSlices<T, U>
+ where T: Slice,
+ U: Slice
+{
+ type Item = (T::Item, U::Item);
+
+ #[inline(always)]
+ fn next(&mut self) -> Option<Self::Item> {
+ unsafe {
+ if self.index >= self.len {
+ None
+ } else {
+ let i = self.index;
+ self.index += 1;
+ Some((
+ self.t.get_unchecked(i),
+ self.u.get_unchecked(i)))
+ }
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let len = self.len - self.index;
+ (len, Some(len))
+ }
+}
+
+impl<T, U> DoubleEndedIterator for ZipSlices<T, U>
+ where T: Slice,
+ U: Slice
+{
+ #[inline(always)]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ unsafe {
+ if self.index >= self.len {
+ None
+ } else {
+ self.len -= 1;
+ let i = self.len;
+ Some((
+ self.t.get_unchecked(i),
+ self.u.get_unchecked(i)))
+ }
+ }
+ }
+}
+
+impl<T, U> ExactSizeIterator for ZipSlices<T, U>
+ where T: Slice,
+ U: Slice
+{}
+
+unsafe impl<T, U> Slice for ZipSlices<T, U>
+ where T: Slice,
+ U: Slice
+{
+ type Item = (T::Item, U::Item);
+
+ fn len(&self) -> usize {
+ self.len - self.index
+ }
+
+ unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
+ (self.t.get_unchecked(i),
+ self.u.get_unchecked(i))
+ }
+}
+
+/// A helper trait to let `ZipSlices` accept both `&[T]` and `&mut [T]`.
+///
+/// Unsafe trait because:
+///
+/// - Implementors must guarantee that `get_unchecked` is valid for all indices `0..len()`.
+pub unsafe trait Slice {
+ /// The type of a reference to the slice's elements
+ type Item;
+ #[doc(hidden)]
+ fn len(&self) -> usize;
+ #[doc(hidden)]
+ unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item;
+}
+
+unsafe impl<'a, T> Slice for &'a [T] {
+ type Item = &'a T;
+ #[inline(always)]
+ fn len(&self) -> usize { (**self).len() }
+ #[inline(always)]
+ unsafe fn get_unchecked(&mut self, i: usize) -> &'a T {
+ debug_assert!(i < self.len());
+ (**self).get_unchecked(i)
+ }
+}
+
+unsafe impl<'a, T> Slice for &'a mut [T] {
+ type Item = &'a mut T;
+ #[inline(always)]
+ fn len(&self) -> usize { (**self).len() }
+ #[inline(always)]
+ unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut T {
+ debug_assert!(i < self.len());
+ // override the lifetime constraints of &mut &'a mut [T]
+ (*(*self as *mut [T])).get_unchecked_mut(i)
+ }
+}
+
+#[test]
+fn zipslices() {
+
+ let xs = [1, 2, 3, 4, 5, 6];
+ let ys = [1, 2, 3, 7];
+ ::itertools::assert_equal(ZipSlices::new(&xs, &ys), xs.iter().zip(&ys));
+
+ let xs = [1, 2, 3, 4, 5, 6];
+ let mut ys = [0; 6];
+ for (x, y) in ZipSlices::from_slices(&xs[..], &mut ys[..]) {
+ *y = *x;
+ }
+ ::itertools::assert_equal(&xs, &ys);
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/benches/fold_specialization.rs b/rust/hw/char/pl011/vendor/itertools/benches/fold_specialization.rs
new file mode 100644
index 0000000000..5de4671e98
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/benches/fold_specialization.rs
@@ -0,0 +1,73 @@
+use criterion::{criterion_group, criterion_main, Criterion};
+use itertools::Itertools;
+
+struct Unspecialized<I>(I);
+
+impl<I> Iterator for Unspecialized<I>
+where I: Iterator
+{
+ type Item = I::Item;
+
+ #[inline(always)]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next()
+ }
+
+ #[inline(always)]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.0.size_hint()
+ }
+}
+
+mod specialization {
+ use super::*;
+
+ pub mod intersperse {
+ use super::*;
+
+ pub fn external(c: &mut Criterion)
+ {
+ let arr = [1; 1024];
+
+ c.bench_function("external", move |b| {
+ b.iter(|| {
+ let mut sum = 0;
+ for &x in arr.iter().intersperse(&0) {
+ sum += x;
+ }
+ sum
+ })
+ });
+ }
+
+ pub fn internal_specialized(c: &mut Criterion)
+ {
+ let arr = [1; 1024];
+
+ c.bench_function("internal specialized", move |b| {
+ b.iter(|| {
+ arr.iter().intersperse(&0).fold(0, |acc, x| acc + x)
+ })
+ });
+ }
+
+ pub fn internal_unspecialized(c: &mut Criterion)
+ {
+ let arr = [1; 1024];
+
+ c.bench_function("internal unspecialized", move |b| {
+ b.iter(|| {
+ Unspecialized(arr.iter().intersperse(&0)).fold(0, |acc, x| acc + x)
+ })
+ });
+ }
+ }
+}
+
+criterion_group!(
+ benches,
+ specialization::intersperse::external,
+ specialization::intersperse::internal_specialized,
+ specialization::intersperse::internal_unspecialized,
+);
+criterion_main!(benches);
diff --git a/rust/hw/char/pl011/vendor/itertools/benches/powerset.rs b/rust/hw/char/pl011/vendor/itertools/benches/powerset.rs
new file mode 100644
index 0000000000..074550bc44
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/benches/powerset.rs
@@ -0,0 +1,44 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use itertools::Itertools;
+
+// Keep aggregate generated elements the same, regardless of powerset length.
+const TOTAL_ELEMENTS: usize = 1 << 12;
+const fn calc_iters(n: usize) -> usize {
+ TOTAL_ELEMENTS / (1 << n)
+}
+
+fn powerset_n(c: &mut Criterion, n: usize) {
+ let id = format!("powerset {}", n);
+ c.bench_function(id.as_str(), move |b| {
+ b.iter(|| {
+ for _ in 0..calc_iters(n) {
+ for elt in (0..n).powerset() {
+ black_box(elt);
+ }
+ }
+ })
+ });
+}
+
+fn powerset_0(c: &mut Criterion) { powerset_n(c, 0); }
+
+fn powerset_1(c: &mut Criterion) { powerset_n(c, 1); }
+
+fn powerset_2(c: &mut Criterion) { powerset_n(c, 2); }
+
+fn powerset_4(c: &mut Criterion) { powerset_n(c, 4); }
+
+fn powerset_8(c: &mut Criterion) { powerset_n(c, 8); }
+
+fn powerset_12(c: &mut Criterion) { powerset_n(c, 12); }
+
+criterion_group!(
+ benches,
+ powerset_0,
+ powerset_1,
+ powerset_2,
+ powerset_4,
+ powerset_8,
+ powerset_12,
+);
+criterion_main!(benches);
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/itertools/benches/tree_fold1.rs b/rust/hw/char/pl011/vendor/itertools/benches/tree_fold1.rs
new file mode 100644
index 0000000000..f12995db8e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/benches/tree_fold1.rs
@@ -0,0 +1,144 @@
+use criterion::{criterion_group, criterion_main, Criterion};
+use itertools::{Itertools, cloned};
+
+trait IterEx : Iterator {
+ // Another efficient implementation against which to compare,
+ // but needs `std` so is less desirable.
+ fn tree_fold1_vec<F>(self, mut f: F) -> Option<Self::Item>
+ where F: FnMut(Self::Item, Self::Item) -> Self::Item,
+ Self: Sized,
+ {
+ let hint = self.size_hint().0;
+ let cap = std::mem::size_of::<usize>() * 8 - hint.leading_zeros() as usize;
+ let mut stack = Vec::with_capacity(cap);
+ self.enumerate().for_each(|(mut i, mut x)| {
+ while (i & 1) != 0 {
+ x = f(stack.pop().unwrap(), x);
+ i >>= 1;
+ }
+ stack.push(x);
+ });
+ stack.into_iter().fold1(f)
+ }
+}
+impl<T:Iterator> IterEx for T {}
+
+macro_rules! def_benchs {
+ ($N:expr,
+ $FUN:ident,
+ $BENCH_NAME:ident,
+ ) => (
+ mod $BENCH_NAME {
+ use super::*;
+
+ pub fn sum(c: &mut Criterion) {
+ let v: Vec<u32> = (0.. $N).collect();
+
+ c.bench_function(&(stringify!($BENCH_NAME).replace('_', " ") + " sum"), move |b| {
+ b.iter(|| {
+ cloned(&v).$FUN(|x, y| x + y)
+ })
+ });
+ }
+
+ pub fn complex_iter(c: &mut Criterion) {
+ let u = (3..).take($N / 2);
+ let v = (5..).take($N / 2);
+ let it = u.chain(v);
+
+ c.bench_function(&(stringify!($BENCH_NAME).replace('_', " ") + " complex iter"), move |b| {
+ b.iter(|| {
+ it.clone().map(|x| x as f32).$FUN(f32::atan2)
+ })
+ });
+ }
+
+ pub fn string_format(c: &mut Criterion) {
+ // This goes quadratic with linear `fold1`, so use a smaller
+ // size to not waste too much time in travis. The allocations
+ // in here are so expensive anyway that it'll still take
+ // way longer per iteration than the other two benchmarks.
+ let v: Vec<u32> = (0.. ($N/4)).collect();
+
+ c.bench_function(&(stringify!($BENCH_NAME).replace('_', " ") + " string format"), move |b| {
+ b.iter(|| {
+ cloned(&v).map(|x| x.to_string()).$FUN(|x, y| format!("{} + {}", x, y))
+ })
+ });
+ }
+ }
+
+ criterion_group!(
+ $BENCH_NAME,
+ $BENCH_NAME::sum,
+ $BENCH_NAME::complex_iter,
+ $BENCH_NAME::string_format,
+ );
+ )
+}
+
+def_benchs!{
+ 10_000,
+ fold1,
+ fold1_10k,
+}
+
+def_benchs!{
+ 10_000,
+ tree_fold1,
+ tree_fold1_stack_10k,
+}
+
+def_benchs!{
+ 10_000,
+ tree_fold1_vec,
+ tree_fold1_vec_10k,
+}
+
+def_benchs!{
+ 100,
+ fold1,
+ fold1_100,
+}
+
+def_benchs!{
+ 100,
+ tree_fold1,
+ tree_fold1_stack_100,
+}
+
+def_benchs!{
+ 100,
+ tree_fold1_vec,
+ tree_fold1_vec_100,
+}
+
+def_benchs!{
+ 8,
+ fold1,
+ fold1_08,
+}
+
+def_benchs!{
+ 8,
+ tree_fold1,
+ tree_fold1_stack_08,
+}
+
+def_benchs!{
+ 8,
+ tree_fold1_vec,
+ tree_fold1_vec_08,
+}
+
+criterion_main!(
+ fold1_10k,
+ tree_fold1_stack_10k,
+ tree_fold1_vec_10k,
+ fold1_100,
+ tree_fold1_stack_100,
+ tree_fold1_vec_100,
+ fold1_08,
+ tree_fold1_stack_08,
+ tree_fold1_vec_08,
+);
diff --git a/rust/hw/char/pl011/vendor/itertools/benches/tuple_combinations.rs b/rust/hw/char/pl011/vendor/itertools/benches/tuple_combinations.rs
new file mode 100644
index 0000000000..4e26b282e8
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/benches/tuple_combinations.rs
@@ -0,0 +1,113 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use itertools::Itertools;
+
+// approximate 100_000 iterations for each combination
+const N1: usize = 100_000;
+const N2: usize = 448;
+const N3: usize = 86;
+const N4: usize = 41;
+
+fn tuple_comb_for1(c: &mut Criterion) {
+ c.bench_function("tuple comb for1", move |b| {
+ b.iter(|| {
+ for i in 0..N1 {
+ black_box(i);
+ }
+ })
+ });
+}
+
+fn tuple_comb_for2(c: &mut Criterion) {
+ c.bench_function("tuple comb for2", move |b| {
+ b.iter(|| {
+ for i in 0..N2 {
+ for j in (i + 1)..N2 {
+ black_box(i + j);
+ }
+ }
+ })
+ });
+}
+
+fn tuple_comb_for3(c: &mut Criterion) {
+ c.bench_function("tuple comb for3", move |b| {
+ b.iter(|| {
+ for i in 0..N3 {
+ for j in (i + 1)..N3 {
+ for k in (j + 1)..N3 {
+ black_box(i + j + k);
+ }
+ }
+ }
+ })
+ });
+}
+
+fn tuple_comb_for4(c: &mut Criterion) {
+ c.bench_function("tuple comb for4", move |b| {
+ b.iter(|| {
+ for i in 0..N4 {
+ for j in (i + 1)..N4 {
+ for k in (j + 1)..N4 {
+ for l in (k + 1)..N4 {
+ black_box(i + j + k + l);
+ }
+ }
+ }
+ }
+ })
+ });
+}
+
+fn tuple_comb_c1(c: &mut Criterion) {
+ c.bench_function("tuple comb c1", move |b| {
+ b.iter(|| {
+ for (i,) in (0..N1).tuple_combinations() {
+ black_box(i);
+ }
+ })
+ });
+}
+
+fn tuple_comb_c2(c: &mut Criterion) {
+ c.bench_function("tuple comb c2", move |b| {
+ b.iter(|| {
+ for (i, j) in (0..N2).tuple_combinations() {
+ black_box(i + j);
+ }
+ })
+ });
+}
+
+fn tuple_comb_c3(c: &mut Criterion) {
+ c.bench_function("tuple comb c3", move |b| {
+ b.iter(|| {
+ for (i, j, k) in (0..N3).tuple_combinations() {
+ black_box(i + j + k);
+ }
+ })
+ });
+}
+
+fn tuple_comb_c4(c: &mut Criterion) {
+ c.bench_function("tuple comb c4", move |b| {
+ b.iter(|| {
+ for (i, j, k, l) in (0..N4).tuple_combinations() {
+ black_box(i + j + k + l);
+ }
+ })
+ });
+}
+
+criterion_group!(
+ benches,
+ tuple_comb_for1,
+ tuple_comb_for2,
+ tuple_comb_for3,
+ tuple_comb_for4,
+ tuple_comb_c1,
+ tuple_comb_c2,
+ tuple_comb_c3,
+ tuple_comb_c4,
+);
+criterion_main!(benches);
diff --git a/rust/hw/char/pl011/vendor/itertools/benches/tuples.rs b/rust/hw/char/pl011/vendor/itertools/benches/tuples.rs
new file mode 100644
index 0000000000..ea50aaaee1
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/benches/tuples.rs
@@ -0,0 +1,213 @@
+use criterion::{criterion_group, criterion_main, Criterion};
+use itertools::Itertools;
+
+fn s1(a: u32) -> u32 {
+ a
+}
+
+fn s2(a: u32, b: u32) -> u32 {
+ a + b
+}
+
+fn s3(a: u32, b: u32, c: u32) -> u32 {
+ a + b + c
+}
+
+fn s4(a: u32, b: u32, c: u32, d: u32) -> u32 {
+ a + b + c + d
+}
+
+fn sum_s1(s: &[u32]) -> u32 {
+ s1(s[0])
+}
+
+fn sum_s2(s: &[u32]) -> u32 {
+ s2(s[0], s[1])
+}
+
+fn sum_s3(s: &[u32]) -> u32 {
+ s3(s[0], s[1], s[2])
+}
+
+fn sum_s4(s: &[u32]) -> u32 {
+ s4(s[0], s[1], s[2], s[3])
+}
+
+fn sum_t1(s: &(&u32, )) -> u32 {
+ s1(*s.0)
+}
+
+fn sum_t2(s: &(&u32, &u32)) -> u32 {
+ s2(*s.0, *s.1)
+}
+
+fn sum_t3(s: &(&u32, &u32, &u32)) -> u32 {
+ s3(*s.0, *s.1, *s.2)
+}
+
+fn sum_t4(s: &(&u32, &u32, &u32, &u32)) -> u32 {
+ s4(*s.0, *s.1, *s.2, *s.3)
+}
+
+macro_rules! def_benchs {
+ ($N:expr;
+ $BENCH_GROUP:ident,
+ $TUPLE_FUN:ident,
+ $TUPLES:ident,
+ $TUPLE_WINDOWS:ident;
+ $SLICE_FUN:ident,
+ $CHUNKS:ident,
+ $WINDOWS:ident;
+ $FOR_CHUNKS:ident,
+ $FOR_WINDOWS:ident
+ ) => (
+ fn $FOR_CHUNKS(c: &mut Criterion) {
+ let v: Vec<u32> = (0.. $N * 1_000).collect();
+ let mut s = 0;
+ c.bench_function(&stringify!($FOR_CHUNKS).replace('_', " "), move |b| {
+ b.iter(|| {
+ let mut j = 0;
+ for _ in 0..1_000 {
+ s += $SLICE_FUN(&v[j..(j + $N)]);
+ j += $N;
+ }
+ s
+ })
+ });
+ }
+
+ fn $FOR_WINDOWS(c: &mut Criterion) {
+ let v: Vec<u32> = (0..1_000).collect();
+ let mut s = 0;
+ c.bench_function(&stringify!($FOR_WINDOWS).replace('_', " "), move |b| {
+ b.iter(|| {
+ for i in 0..(1_000 - $N) {
+ s += $SLICE_FUN(&v[i..(i + $N)]);
+ }
+ s
+ })
+ });
+ }
+
+ fn $TUPLES(c: &mut Criterion) {
+ let v: Vec<u32> = (0.. $N * 1_000).collect();
+ let mut s = 0;
+ c.bench_function(&stringify!($TUPLES).replace('_', " "), move |b| {
+ b.iter(|| {
+ for x in v.iter().tuples() {
+ s += $TUPLE_FUN(&x);
+ }
+ s
+ })
+ });
+ }
+
+ fn $CHUNKS(c: &mut Criterion) {
+ let v: Vec<u32> = (0.. $N * 1_000).collect();
+ let mut s = 0;
+ c.bench_function(&stringify!($CHUNKS).replace('_', " "), move |b| {
+ b.iter(|| {
+ for x in v.chunks($N) {
+ s += $SLICE_FUN(x);
+ }
+ s
+ })
+ });
+ }
+
+ fn $TUPLE_WINDOWS(c: &mut Criterion) {
+ let v: Vec<u32> = (0..1_000).collect();
+ let mut s = 0;
+ c.bench_function(&stringify!($TUPLE_WINDOWS).replace('_', " "), move |b| {
+ b.iter(|| {
+ for x in v.iter().tuple_windows() {
+ s += $TUPLE_FUN(&x);
+ }
+ s
+ })
+ });
+ }
+
+ fn $WINDOWS(c: &mut Criterion) {
+ let v: Vec<u32> = (0..1_000).collect();
+ let mut s = 0;
+ c.bench_function(&stringify!($WINDOWS).replace('_', " "), move |b| {
+ b.iter(|| {
+ for x in v.windows($N) {
+ s += $SLICE_FUN(x);
+ }
+ s
+ })
+ });
+ }
+
+ criterion_group!(
+ $BENCH_GROUP,
+ $FOR_CHUNKS,
+ $FOR_WINDOWS,
+ $TUPLES,
+ $CHUNKS,
+ $TUPLE_WINDOWS,
+ $WINDOWS,
+ );
+ )
+}
+
+def_benchs!{
+ 1;
+ benches_1,
+ sum_t1,
+ tuple_chunks_1,
+ tuple_windows_1;
+ sum_s1,
+ slice_chunks_1,
+ slice_windows_1;
+ for_chunks_1,
+ for_windows_1
+}
+
+def_benchs!{
+ 2;
+ benches_2,
+ sum_t2,
+ tuple_chunks_2,
+ tuple_windows_2;
+ sum_s2,
+ slice_chunks_2,
+ slice_windows_2;
+ for_chunks_2,
+ for_windows_2
+}
+
+def_benchs!{
+ 3;
+ benches_3,
+ sum_t3,
+ tuple_chunks_3,
+ tuple_windows_3;
+ sum_s3,
+ slice_chunks_3,
+ slice_windows_3;
+ for_chunks_3,
+ for_windows_3
+}
+
+def_benchs!{
+ 4;
+ benches_4,
+ sum_t4,
+ tuple_chunks_4,
+ tuple_windows_4;
+ sum_s4,
+ slice_chunks_4,
+ slice_windows_4;
+ for_chunks_4,
+ for_windows_4
+}
+
+criterion_main!(
+ benches_1,
+ benches_2,
+ benches_3,
+ benches_4,
+);
diff --git a/rust/hw/char/pl011/vendor/itertools/examples/iris.data b/rust/hw/char/pl011/vendor/itertools/examples/iris.data
new file mode 100644
index 0000000000..a3490e0e07
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/examples/iris.data
@@ -0,0 +1,150 @@
+5.1,3.5,1.4,0.2,Iris-setosa
+4.9,3.0,1.4,0.2,Iris-setosa
+4.7,3.2,1.3,0.2,Iris-setosa
+4.6,3.1,1.5,0.2,Iris-setosa
+5.0,3.6,1.4,0.2,Iris-setosa
+5.4,3.9,1.7,0.4,Iris-setosa
+4.6,3.4,1.4,0.3,Iris-setosa
+5.0,3.4,1.5,0.2,Iris-setosa
+4.4,2.9,1.4,0.2,Iris-setosa
+4.9,3.1,1.5,0.1,Iris-setosa
+5.4,3.7,1.5,0.2,Iris-setosa
+4.8,3.4,1.6,0.2,Iris-setosa
+4.8,3.0,1.4,0.1,Iris-setosa
+4.3,3.0,1.1,0.1,Iris-setosa
+5.8,4.0,1.2,0.2,Iris-setosa
+5.7,4.4,1.5,0.4,Iris-setosa
+5.4,3.9,1.3,0.4,Iris-setosa
+5.1,3.5,1.4,0.3,Iris-setosa
+5.7,3.8,1.7,0.3,Iris-setosa
+5.1,3.8,1.5,0.3,Iris-setosa
+5.4,3.4,1.7,0.2,Iris-setosa
+5.1,3.7,1.5,0.4,Iris-setosa
+4.6,3.6,1.0,0.2,Iris-setosa
+5.1,3.3,1.7,0.5,Iris-setosa
+4.8,3.4,1.9,0.2,Iris-setosa
+5.0,3.0,1.6,0.2,Iris-setosa
+5.0,3.4,1.6,0.4,Iris-setosa
+5.2,3.5,1.5,0.2,Iris-setosa
+5.2,3.4,1.4,0.2,Iris-setosa
+4.7,3.2,1.6,0.2,Iris-setosa
+4.8,3.1,1.6,0.2,Iris-setosa
+5.4,3.4,1.5,0.4,Iris-setosa
+5.2,4.1,1.5,0.1,Iris-setosa
+5.5,4.2,1.4,0.2,Iris-setosa
+4.9,3.1,1.5,0.1,Iris-setosa
+5.0,3.2,1.2,0.2,Iris-setosa
+5.5,3.5,1.3,0.2,Iris-setosa
+4.9,3.1,1.5,0.1,Iris-setosa
+4.4,3.0,1.3,0.2,Iris-setosa
+5.1,3.4,1.5,0.2,Iris-setosa
+5.0,3.5,1.3,0.3,Iris-setosa
+4.5,2.3,1.3,0.3,Iris-setosa
+4.4,3.2,1.3,0.2,Iris-setosa
+5.0,3.5,1.6,0.6,Iris-setosa
+5.1,3.8,1.9,0.4,Iris-setosa
+4.8,3.0,1.4,0.3,Iris-setosa
+5.1,3.8,1.6,0.2,Iris-setosa
+4.6,3.2,1.4,0.2,Iris-setosa
+5.3,3.7,1.5,0.2,Iris-setosa
+5.0,3.3,1.4,0.2,Iris-setosa
+7.0,3.2,4.7,1.4,Iris-versicolor
+6.4,3.2,4.5,1.5,Iris-versicolor
+6.9,3.1,4.9,1.5,Iris-versicolor
+5.5,2.3,4.0,1.3,Iris-versicolor
+6.5,2.8,4.6,1.5,Iris-versicolor
+5.7,2.8,4.5,1.3,Iris-versicolor
+6.3,3.3,4.7,1.6,Iris-versicolor
+4.9,2.4,3.3,1.0,Iris-versicolor
+6.6,2.9,4.6,1.3,Iris-versicolor
+5.2,2.7,3.9,1.4,Iris-versicolor
+5.0,2.0,3.5,1.0,Iris-versicolor
+5.9,3.0,4.2,1.5,Iris-versicolor
+6.0,2.2,4.0,1.0,Iris-versicolor
+6.1,2.9,4.7,1.4,Iris-versicolor
+5.6,2.9,3.6,1.3,Iris-versicolor
+6.7,3.1,4.4,1.4,Iris-versicolor
+5.6,3.0,4.5,1.5,Iris-versicolor
+5.8,2.7,4.1,1.0,Iris-versicolor
+6.2,2.2,4.5,1.5,Iris-versicolor
+5.6,2.5,3.9,1.1,Iris-versicolor
+5.9,3.2,4.8,1.8,Iris-versicolor
+6.1,2.8,4.0,1.3,Iris-versicolor
+6.3,2.5,4.9,1.5,Iris-versicolor
+6.1,2.8,4.7,1.2,Iris-versicolor
+6.4,2.9,4.3,1.3,Iris-versicolor
+6.6,3.0,4.4,1.4,Iris-versicolor
+6.8,2.8,4.8,1.4,Iris-versicolor
+6.7,3.0,5.0,1.7,Iris-versicolor
+6.0,2.9,4.5,1.5,Iris-versicolor
+5.7,2.6,3.5,1.0,Iris-versicolor
+5.5,2.4,3.8,1.1,Iris-versicolor
+5.5,2.4,3.7,1.0,Iris-versicolor
+5.8,2.7,3.9,1.2,Iris-versicolor
+6.0,2.7,5.1,1.6,Iris-versicolor
+5.4,3.0,4.5,1.5,Iris-versicolor
+6.0,3.4,4.5,1.6,Iris-versicolor
+6.7,3.1,4.7,1.5,Iris-versicolor
+6.3,2.3,4.4,1.3,Iris-versicolor
+5.6,3.0,4.1,1.3,Iris-versicolor
+5.5,2.5,4.0,1.3,Iris-versicolor
+5.5,2.6,4.4,1.2,Iris-versicolor
+6.1,3.0,4.6,1.4,Iris-versicolor
+5.8,2.6,4.0,1.2,Iris-versicolor
+5.0,2.3,3.3,1.0,Iris-versicolor
+5.6,2.7,4.2,1.3,Iris-versicolor
+5.7,3.0,4.2,1.2,Iris-versicolor
+5.7,2.9,4.2,1.3,Iris-versicolor
+6.2,2.9,4.3,1.3,Iris-versicolor
+5.1,2.5,3.0,1.1,Iris-versicolor
+5.7,2.8,4.1,1.3,Iris-versicolor
+6.3,3.3,6.0,2.5,Iris-virginica
+5.8,2.7,5.1,1.9,Iris-virginica
+7.1,3.0,5.9,2.1,Iris-virginica
+6.3,2.9,5.6,1.8,Iris-virginica
+6.5,3.0,5.8,2.2,Iris-virginica
+7.6,3.0,6.6,2.1,Iris-virginica
+4.9,2.5,4.5,1.7,Iris-virginica
+7.3,2.9,6.3,1.8,Iris-virginica
+6.7,2.5,5.8,1.8,Iris-virginica
+7.2,3.6,6.1,2.5,Iris-virginica
+6.5,3.2,5.1,2.0,Iris-virginica
+6.4,2.7,5.3,1.9,Iris-virginica
+6.8,3.0,5.5,2.1,Iris-virginica
+5.7,2.5,5.0,2.0,Iris-virginica
+5.8,2.8,5.1,2.4,Iris-virginica
+6.4,3.2,5.3,2.3,Iris-virginica
+6.5,3.0,5.5,1.8,Iris-virginica
+7.7,3.8,6.7,2.2,Iris-virginica
+7.7,2.6,6.9,2.3,Iris-virginica
+6.0,2.2,5.0,1.5,Iris-virginica
+6.9,3.2,5.7,2.3,Iris-virginica
+5.6,2.8,4.9,2.0,Iris-virginica
+7.7,2.8,6.7,2.0,Iris-virginica
+6.3,2.7,4.9,1.8,Iris-virginica
+6.7,3.3,5.7,2.1,Iris-virginica
+7.2,3.2,6.0,1.8,Iris-virginica
+6.2,2.8,4.8,1.8,Iris-virginica
+6.1,3.0,4.9,1.8,Iris-virginica
+6.4,2.8,5.6,2.1,Iris-virginica
+7.2,3.0,5.8,1.6,Iris-virginica
+7.4,2.8,6.1,1.9,Iris-virginica
+7.9,3.8,6.4,2.0,Iris-virginica
+6.4,2.8,5.6,2.2,Iris-virginica
+6.3,2.8,5.1,1.5,Iris-virginica
+6.1,2.6,5.6,1.4,Iris-virginica
+7.7,3.0,6.1,2.3,Iris-virginica
+6.3,3.4,5.6,2.4,Iris-virginica
+6.4,3.1,5.5,1.8,Iris-virginica
+6.0,3.0,4.8,1.8,Iris-virginica
+6.9,3.1,5.4,2.1,Iris-virginica
+6.7,3.1,5.6,2.4,Iris-virginica
+6.9,3.1,5.1,2.3,Iris-virginica
+5.8,2.7,5.1,1.9,Iris-virginica
+6.8,3.2,5.9,2.3,Iris-virginica
+6.7,3.3,5.7,2.5,Iris-virginica
+6.7,3.0,5.2,2.3,Iris-virginica
+6.3,2.5,5.0,1.9,Iris-virginica
+6.5,3.0,5.2,2.0,Iris-virginica
+6.2,3.4,5.4,2.3,Iris-virginica
+5.9,3.0,5.1,1.8,Iris-virginica
diff --git a/rust/hw/char/pl011/vendor/itertools/examples/iris.rs b/rust/hw/char/pl011/vendor/itertools/examples/iris.rs
new file mode 100644
index 0000000000..987d9e9cba
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/examples/iris.rs
@@ -0,0 +1,137 @@
+///
+/// This example parses, sorts and groups the iris dataset
+/// and does some simple manipulations.
+///
+/// Iterators and itertools functionality are used throughout.
+
+use itertools::Itertools;
+use std::collections::HashMap;
+use std::iter::repeat;
+use std::num::ParseFloatError;
+use std::str::FromStr;
+
+static DATA: &'static str = include_str!("iris.data");
+
+#[derive(Clone, Debug)]
+struct Iris {
+ name: String,
+ data: [f32; 4],
+}
+
+#[derive(Clone, Debug)]
+enum ParseError {
+ Numeric(ParseFloatError),
+ Other(&'static str),
+}
+
+impl From<ParseFloatError> for ParseError {
+ fn from(err: ParseFloatError) -> Self {
+ ParseError::Numeric(err)
+ }
+}
+
+/// Parse an Iris from a comma-separated line
+impl FromStr for Iris {
+ type Err = ParseError;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ let mut iris = Iris { name: "".into(), data: [0.; 4] };
+ let mut parts = s.split(",").map(str::trim);
+
+ // using Iterator::by_ref()
+ for (index, part) in parts.by_ref().take(4).enumerate() {
+ iris.data[index] = part.parse::<f32>()?;
+ }
+ if let Some(name) = parts.next() {
+ iris.name = name.into();
+ } else {
+ return Err(ParseError::Other("Missing name"))
+ }
+ Ok(iris)
+ }
+}
+
+fn main() {
+ // using Itertools::fold_results to create the result of parsing
+ let irises = DATA.lines()
+ .map(str::parse)
+ .fold_ok(Vec::new(), |mut v, iris: Iris| {
+ v.push(iris);
+ v
+ });
+ let mut irises = match irises {
+ Err(e) => {
+ println!("Error parsing: {:?}", e);
+ std::process::exit(1);
+ }
+ Ok(data) => data,
+ };
+
+ // Sort them and group them
+ irises.sort_by(|a, b| Ord::cmp(&a.name, &b.name));
+
+ // using Iterator::cycle()
+ let mut plot_symbols = "+ox".chars().cycle();
+ let mut symbolmap = HashMap::new();
+
+ // using Itertools::group_by
+ for (species, species_group) in &irises.iter().group_by(|iris| &iris.name) {
+ // assign a plot symbol
+ symbolmap.entry(species).or_insert_with(|| {
+ plot_symbols.next().unwrap()
+ });
+ println!("{} (symbol={})", species, symbolmap[species]);
+
+ for iris in species_group {
+ // using Itertools::format for lazy formatting
+ println!("{:>3.1}", iris.data.iter().format(", "));
+ }
+
+ }
+
+ // Look at all combinations of the four columns
+ //
+ // See https://en.wikipedia.org/wiki/Iris_flower_data_set
+ //
+ let n = 30; // plot size
+ let mut plot = vec![' '; n * n];
+
+ // using Itertools::tuple_combinations
+ for (a, b) in (0..4).tuple_combinations() {
+ println!("Column {} vs {}:", a, b);
+
+ // Clear plot
+ //
+ // using std::iter::repeat;
+ // using Itertools::set_from
+ plot.iter_mut().set_from(repeat(' '));
+
+ // using Itertools::minmax
+ let min_max = |data: &[Iris], col| {
+ data.iter()
+ .map(|iris| iris.data[col])
+ .minmax()
+ .into_option()
+ .expect("Can't find min/max of empty iterator")
+ };
+ let (min_x, max_x) = min_max(&irises, a);
+ let (min_y, max_y) = min_max(&irises, b);
+
+ // Plot the data points
+ let round_to_grid = |x, min, max| ((x - min) / (max - min) * ((n - 1) as f32)) as usize;
+ let flip = |ix| n - 1 - ix; // reverse axis direction
+
+ for iris in &irises {
+ let ix = round_to_grid(iris.data[a], min_x, max_x);
+ let iy = flip(round_to_grid(iris.data[b], min_y, max_y));
+ plot[n * iy + ix] = symbolmap[&iris.name];
+ }
+
+ // render plot
+ //
+ // using Itertools::join
+ for line in plot.chunks(n) {
+ println!("{}", line.iter().join(" "))
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/meson.build b/rust/hw/char/pl011/vendor/itertools/meson.build
new file mode 100644
index 0000000000..3fb976c06d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/meson.build
@@ -0,0 +1,18 @@
+_itertools_rs = static_library(
+ 'itertools',
+ files('src/lib.rs'),
+ gnu_symbol_visibility: 'hidden',
+ rust_abi: 'rust',
+ rust_args: rust_args + [
+ '--edition', '2018',
+ '--cfg', 'feature="use_std"',
+ '--cfg', 'feature="use_alloc"',
+ ],
+ dependencies: [
+ dep_either,
+ ],
+)
+
+dep_itertools = declare_dependency(
+ link_with: _itertools_rs,
+)
diff --git a/rust/hw/char/pl011/vendor/itertools/src/adaptors/coalesce.rs b/rust/hw/char/pl011/vendor/itertools/src/adaptors/coalesce.rs
new file mode 100644
index 0000000000..3df7cc5823
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/adaptors/coalesce.rs
@@ -0,0 +1,235 @@
+use std::fmt;
+use std::iter::FusedIterator;
+
+use crate::size_hint;
+
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct CoalesceBy<I, F, T>
+where
+ I: Iterator,
+{
+ iter: I,
+ last: Option<T>,
+ f: F,
+}
+
+impl<I: Clone, F: Clone, T: Clone> Clone for CoalesceBy<I, F, T>
+where
+ I: Iterator,
+{
+ clone_fields!(last, iter, f);
+}
+
+impl<I, F, T> fmt::Debug for CoalesceBy<I, F, T>
+where
+ I: Iterator + fmt::Debug,
+ T: fmt::Debug,
+{
+ debug_fmt_fields!(CoalesceBy, iter);
+}
+
+pub trait CoalescePredicate<Item, T> {
+ fn coalesce_pair(&mut self, t: T, item: Item) -> Result<T, (T, T)>;
+}
+
+impl<I, F, T> Iterator for CoalesceBy<I, F, T>
+where
+ I: Iterator,
+ F: CoalescePredicate<I::Item, T>,
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ // this fuses the iterator
+ let last = self.last.take()?;
+
+ let self_last = &mut self.last;
+ let self_f = &mut self.f;
+ Some(
+ self.iter
+ .try_fold(last, |last, next| match self_f.coalesce_pair(last, next) {
+ Ok(joined) => Ok(joined),
+ Err((last_, next_)) => {
+ *self_last = Some(next_);
+ Err(last_)
+ }
+ })
+ .unwrap_or_else(|x| x),
+ )
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (low, hi) = size_hint::add_scalar(self.iter.size_hint(), self.last.is_some() as usize);
+ ((low > 0) as usize, hi)
+ }
+
+ fn fold<Acc, FnAcc>(self, acc: Acc, mut fn_acc: FnAcc) -> Acc
+ where
+ FnAcc: FnMut(Acc, Self::Item) -> Acc,
+ {
+ if let Some(last) = self.last {
+ let mut f = self.f;
+ let (last, acc) = self.iter.fold((last, acc), |(last, acc), elt| {
+ match f.coalesce_pair(last, elt) {
+ Ok(joined) => (joined, acc),
+ Err((last_, next_)) => (next_, fn_acc(acc, last_)),
+ }
+ });
+ fn_acc(acc, last)
+ } else {
+ acc
+ }
+ }
+}
+
+impl<I: Iterator, F: CoalescePredicate<I::Item, T>, T> FusedIterator for CoalesceBy<I, F, T> {}
+
+/// An iterator adaptor that may join together adjacent elements.
+///
+/// See [`.coalesce()`](crate::Itertools::coalesce) for more information.
+pub type Coalesce<I, F> = CoalesceBy<I, F, <I as Iterator>::Item>;
+
+impl<F, Item, T> CoalescePredicate<Item, T> for F
+where
+ F: FnMut(T, Item) -> Result<T, (T, T)>,
+{
+ fn coalesce_pair(&mut self, t: T, item: Item) -> Result<T, (T, T)> {
+ self(t, item)
+ }
+}
+
+/// Create a new `Coalesce`.
+pub fn coalesce<I, F>(mut iter: I, f: F) -> Coalesce<I, F>
+where
+ I: Iterator,
+{
+ Coalesce {
+ last: iter.next(),
+ iter,
+ f,
+ }
+}
+
+/// An iterator adaptor that removes repeated duplicates, determining equality using a comparison function.
+///
+/// See [`.dedup_by()`](crate::Itertools::dedup_by) or [`.dedup()`](crate::Itertools::dedup) for more information.
+pub type DedupBy<I, Pred> = CoalesceBy<I, DedupPred2CoalescePred<Pred>, <I as Iterator>::Item>;
+
+#[derive(Clone)]
+pub struct DedupPred2CoalescePred<DP>(DP);
+
+impl<DP> fmt::Debug for DedupPred2CoalescePred<DP> {
+ debug_fmt_fields!(DedupPred2CoalescePred,);
+}
+
+pub trait DedupPredicate<T> {
+ // TODO replace by Fn(&T, &T)->bool once Rust supports it
+ fn dedup_pair(&mut self, a: &T, b: &T) -> bool;
+}
+
+impl<DP, T> CoalescePredicate<T, T> for DedupPred2CoalescePred<DP>
+where
+ DP: DedupPredicate<T>,
+{
+ fn coalesce_pair(&mut self, t: T, item: T) -> Result<T, (T, T)> {
+ if self.0.dedup_pair(&t, &item) {
+ Ok(t)
+ } else {
+ Err((t, item))
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+pub struct DedupEq;
+
+impl<T: PartialEq> DedupPredicate<T> for DedupEq {
+ fn dedup_pair(&mut self, a: &T, b: &T) -> bool {
+ a == b
+ }
+}
+
+impl<T, F: FnMut(&T, &T) -> bool> DedupPredicate<T> for F {
+ fn dedup_pair(&mut self, a: &T, b: &T) -> bool {
+ self(a, b)
+ }
+}
+
+/// Create a new `DedupBy`.
+pub fn dedup_by<I, Pred>(mut iter: I, dedup_pred: Pred) -> DedupBy<I, Pred>
+where
+ I: Iterator,
+{
+ DedupBy {
+ last: iter.next(),
+ iter,
+ f: DedupPred2CoalescePred(dedup_pred),
+ }
+}
+
+/// An iterator adaptor that removes repeated duplicates.
+///
+/// See [`.dedup()`](crate::Itertools::dedup) for more information.
+pub type Dedup<I> = DedupBy<I, DedupEq>;
+
+/// Create a new `Dedup`.
+pub fn dedup<I>(iter: I) -> Dedup<I>
+where
+ I: Iterator,
+{
+ dedup_by(iter, DedupEq)
+}
+
+/// An iterator adaptor that removes repeated duplicates, while keeping a count of how many
+/// repeated elements were present. This will determine equality using a comparison function.
+///
+/// See [`.dedup_by_with_count()`](crate::Itertools::dedup_by_with_count) or
+/// [`.dedup_with_count()`](crate::Itertools::dedup_with_count) for more information.
+pub type DedupByWithCount<I, Pred> =
+ CoalesceBy<I, DedupPredWithCount2CoalescePred<Pred>, (usize, <I as Iterator>::Item)>;
+
+#[derive(Clone, Debug)]
+pub struct DedupPredWithCount2CoalescePred<DP>(DP);
+
+impl<DP, T> CoalescePredicate<T, (usize, T)> for DedupPredWithCount2CoalescePred<DP>
+where
+ DP: DedupPredicate<T>,
+{
+ fn coalesce_pair(
+ &mut self,
+ (c, t): (usize, T),
+ item: T,
+ ) -> Result<(usize, T), ((usize, T), (usize, T))> {
+ if self.0.dedup_pair(&t, &item) {
+ Ok((c + 1, t))
+ } else {
+ Err(((c, t), (1, item)))
+ }
+ }
+}
+
+/// An iterator adaptor that removes repeated duplicates, while keeping a count of how many
+/// repeated elements were present.
+///
+/// See [`.dedup_with_count()`](crate::Itertools::dedup_with_count) for more information.
+pub type DedupWithCount<I> = DedupByWithCount<I, DedupEq>;
+
+/// Create a new `DedupByWithCount`.
+pub fn dedup_by_with_count<I, Pred>(mut iter: I, dedup_pred: Pred) -> DedupByWithCount<I, Pred>
+where
+ I: Iterator,
+{
+ DedupByWithCount {
+ last: iter.next().map(|v| (1, v)),
+ iter,
+ f: DedupPredWithCount2CoalescePred(dedup_pred),
+ }
+}
+
+/// Create a new `DedupWithCount`.
+pub fn dedup_with_count<I>(iter: I) -> DedupWithCount<I>
+where
+ I: Iterator,
+{
+ dedup_by_with_count(iter, DedupEq)
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/adaptors/map.rs b/rust/hw/char/pl011/vendor/itertools/src/adaptors/map.rs
new file mode 100644
index 0000000000..cf5e5a00d5
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/adaptors/map.rs
@@ -0,0 +1,124 @@
+use std::iter::FromIterator;
+use std::marker::PhantomData;
+
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct MapSpecialCase<I, F> {
+ iter: I,
+ f: F,
+}
+
+pub trait MapSpecialCaseFn<T> {
+ type Out;
+ fn call(&mut self, t: T) -> Self::Out;
+}
+
+impl<I, R> Iterator for MapSpecialCase<I, R>
+where
+ I: Iterator,
+ R: MapSpecialCaseFn<I::Item>,
+{
+ type Item = R::Out;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next().map(|i| self.f.call(i))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+
+ fn fold<Acc, Fold>(self, init: Acc, mut fold_f: Fold) -> Acc
+ where
+ Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ let mut f = self.f;
+ self.iter.fold(init, move |acc, v| fold_f(acc, f.call(v)))
+ }
+
+ fn collect<C>(self) -> C
+ where
+ C: FromIterator<Self::Item>,
+ {
+ let mut f = self.f;
+ self.iter.map(move |v| f.call(v)).collect()
+ }
+}
+
+impl<I, R> DoubleEndedIterator for MapSpecialCase<I, R>
+where
+ I: DoubleEndedIterator,
+ R: MapSpecialCaseFn<I::Item>,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter.next_back().map(|i| self.f.call(i))
+ }
+}
+
+impl<I, R> ExactSizeIterator for MapSpecialCase<I, R>
+where
+ I: ExactSizeIterator,
+ R: MapSpecialCaseFn<I::Item>,
+{
+}
+
+/// An iterator adapter to apply a transformation within a nested `Result::Ok`.
+///
+/// See [`.map_ok()`](crate::Itertools::map_ok) for more information.
+pub type MapOk<I, F> = MapSpecialCase<I, MapSpecialCaseFnOk<F>>;
+
+/// See [`MapOk`].
+#[deprecated(note = "Use MapOk instead", since = "0.10.0")]
+pub type MapResults<I, F> = MapOk<I, F>;
+
+impl<F, T, U, E> MapSpecialCaseFn<Result<T, E>> for MapSpecialCaseFnOk<F>
+where
+ F: FnMut(T) -> U,
+{
+ type Out = Result<U, E>;
+ fn call(&mut self, t: Result<T, E>) -> Self::Out {
+ t.map(|v| self.0(v))
+ }
+}
+
+#[derive(Clone)]
+pub struct MapSpecialCaseFnOk<F>(F);
+
+impl<F> std::fmt::Debug for MapSpecialCaseFnOk<F> {
+ debug_fmt_fields!(MapSpecialCaseFnOk,);
+}
+
+/// Create a new `MapOk` iterator.
+pub fn map_ok<I, F, T, U, E>(iter: I, f: F) -> MapOk<I, F>
+where
+ I: Iterator<Item = Result<T, E>>,
+ F: FnMut(T) -> U,
+{
+ MapSpecialCase {
+ iter,
+ f: MapSpecialCaseFnOk(f),
+ }
+}
+
+/// An iterator adapter to apply `Into` conversion to each element.
+///
+/// See [`.map_into()`](crate::Itertools::map_into) for more information.
+pub type MapInto<I, R> = MapSpecialCase<I, MapSpecialCaseFnInto<R>>;
+
+impl<T: Into<U>, U> MapSpecialCaseFn<T> for MapSpecialCaseFnInto<U> {
+ type Out = U;
+ fn call(&mut self, t: T) -> Self::Out {
+ t.into()
+ }
+}
+
+#[derive(Clone, Debug)]
+pub struct MapSpecialCaseFnInto<U>(PhantomData<U>);
+
+/// Create a new [`MapInto`] iterator.
+pub fn map_into<I, R>(iter: I) -> MapInto<I, R> {
+ MapSpecialCase {
+ iter,
+ f: MapSpecialCaseFnInto(PhantomData),
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/adaptors/mod.rs b/rust/hw/char/pl011/vendor/itertools/src/adaptors/mod.rs
new file mode 100644
index 0000000000..1695bbd655
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/adaptors/mod.rs
@@ -0,0 +1,1151 @@
+//! Licensed under the Apache License, Version 2.0
+//! <https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+//! <https://opensource.org/licenses/MIT>, at your
+//! option. This file may not be copied, modified, or distributed
+//! except according to those terms.
+
+mod coalesce;
+mod map;
+mod multi_product;
+pub use self::coalesce::*;
+pub use self::map::{map_into, map_ok, MapInto, MapOk};
+#[allow(deprecated)]
+pub use self::map::MapResults;
+#[cfg(feature = "use_alloc")]
+pub use self::multi_product::*;
+
+use std::fmt;
+use std::iter::{Fuse, Peekable, FromIterator, FusedIterator};
+use std::marker::PhantomData;
+use crate::size_hint;
+
+/// An iterator adaptor that alternates elements from two iterators until both
+/// run out.
+///
+/// This iterator is *fused*.
+///
+/// See [`.interleave()`](crate::Itertools::interleave) for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Interleave<I, J> {
+ a: Fuse<I>,
+ b: Fuse<J>,
+ flag: bool,
+}
+
+/// Create an iterator that interleaves elements in `i` and `j`.
+///
+/// [`IntoIterator`] enabled version of `[Itertools::interleave]`.
+pub fn interleave<I, J>(i: I, j: J) -> Interleave<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
+ where I: IntoIterator,
+ J: IntoIterator<Item = I::Item>
+{
+ Interleave {
+ a: i.into_iter().fuse(),
+ b: j.into_iter().fuse(),
+ flag: false,
+ }
+}
+
+impl<I, J> Iterator for Interleave<I, J>
+ where I: Iterator,
+ J: Iterator<Item = I::Item>
+{
+ type Item = I::Item;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.flag = !self.flag;
+ if self.flag {
+ match self.a.next() {
+ None => self.b.next(),
+ r => r,
+ }
+ } else {
+ match self.b.next() {
+ None => self.a.next(),
+ r => r,
+ }
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ size_hint::add(self.a.size_hint(), self.b.size_hint())
+ }
+}
+
+impl<I, J> FusedIterator for Interleave<I, J>
+ where I: Iterator,
+ J: Iterator<Item = I::Item>
+{}
+
+/// An iterator adaptor that alternates elements from the two iterators until
+/// one of them runs out.
+///
+/// This iterator is *fused*.
+///
+/// See [`.interleave_shortest()`](crate::Itertools::interleave_shortest)
+/// for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct InterleaveShortest<I, J>
+ where I: Iterator,
+ J: Iterator<Item = I::Item>
+{
+ it0: I,
+ it1: J,
+ phase: bool, // false ==> it0, true ==> it1
+}
+
+/// Create a new `InterleaveShortest` iterator.
+pub fn interleave_shortest<I, J>(a: I, b: J) -> InterleaveShortest<I, J>
+ where I: Iterator,
+ J: Iterator<Item = I::Item>
+{
+ InterleaveShortest {
+ it0: a,
+ it1: b,
+ phase: false,
+ }
+}
+
+impl<I, J> Iterator for InterleaveShortest<I, J>
+ where I: Iterator,
+ J: Iterator<Item = I::Item>
+{
+ type Item = I::Item;
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ let e = if self.phase { self.it1.next() } else { self.it0.next() };
+ if e.is_some() {
+ self.phase = !self.phase;
+ }
+ e
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (curr_hint, next_hint) = {
+ let it0_hint = self.it0.size_hint();
+ let it1_hint = self.it1.size_hint();
+ if self.phase {
+ (it1_hint, it0_hint)
+ } else {
+ (it0_hint, it1_hint)
+ }
+ };
+ let (curr_lower, curr_upper) = curr_hint;
+ let (next_lower, next_upper) = next_hint;
+ let (combined_lower, combined_upper) =
+ size_hint::mul_scalar(size_hint::min(curr_hint, next_hint), 2);
+ let lower =
+ if curr_lower > next_lower {
+ combined_lower + 1
+ } else {
+ combined_lower
+ };
+ let upper = {
+ let extra_elem = match (curr_upper, next_upper) {
+ (_, None) => false,
+ (None, Some(_)) => true,
+ (Some(curr_max), Some(next_max)) => curr_max > next_max,
+ };
+ if extra_elem {
+ combined_upper.and_then(|x| x.checked_add(1))
+ } else {
+ combined_upper
+ }
+ };
+ (lower, upper)
+ }
+}
+
+impl<I, J> FusedIterator for InterleaveShortest<I, J>
+ where I: FusedIterator,
+ J: FusedIterator<Item = I::Item>
+{}
+
+#[derive(Clone, Debug)]
+/// An iterator adaptor that allows putting back a single
+/// item to the front of the iterator.
+///
+/// Iterator element type is `I::Item`.
+pub struct PutBack<I>
+ where I: Iterator
+{
+ top: Option<I::Item>,
+ iter: I,
+}
+
+/// Create an iterator where you can put back a single item
+pub fn put_back<I>(iterable: I) -> PutBack<I::IntoIter>
+ where I: IntoIterator
+{
+ PutBack {
+ top: None,
+ iter: iterable.into_iter(),
+ }
+}
+
+impl<I> PutBack<I>
+ where I: Iterator
+{
+ /// put back value `value` (builder method)
+ pub fn with_value(mut self, value: I::Item) -> Self {
+ self.put_back(value);
+ self
+ }
+
+ /// Split the `PutBack` into its parts.
+ #[inline]
+ pub fn into_parts(self) -> (Option<I::Item>, I) {
+ let PutBack{top, iter} = self;
+ (top, iter)
+ }
+
+ /// Put back a single value to the front of the iterator.
+ ///
+ /// If a value is already in the put back slot, it is overwritten.
+ #[inline]
+ pub fn put_back(&mut self, x: I::Item) {
+ self.top = Some(x);
+ }
+}
+
+impl<I> Iterator for PutBack<I>
+ where I: Iterator
+{
+ type Item = I::Item;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.top {
+ None => self.iter.next(),
+ ref mut some => some.take(),
+ }
+ }
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ // Not ExactSizeIterator because size may be larger than usize
+ size_hint::add_scalar(self.iter.size_hint(), self.top.is_some() as usize)
+ }
+
+ fn count(self) -> usize {
+ self.iter.count() + (self.top.is_some() as usize)
+ }
+
+ fn last(self) -> Option<Self::Item> {
+ self.iter.last().or(self.top)
+ }
+
+ fn nth(&mut self, n: usize) -> Option<Self::Item> {
+ match self.top {
+ None => self.iter.nth(n),
+ ref mut some => {
+ if n == 0 {
+ some.take()
+ } else {
+ *some = None;
+ self.iter.nth(n - 1)
+ }
+ }
+ }
+ }
+
+ fn all<G>(&mut self, mut f: G) -> bool
+ where G: FnMut(Self::Item) -> bool
+ {
+ if let Some(elt) = self.top.take() {
+ if !f(elt) {
+ return false;
+ }
+ }
+ self.iter.all(f)
+ }
+
+ fn fold<Acc, G>(mut self, init: Acc, mut f: G) -> Acc
+ where G: FnMut(Acc, Self::Item) -> Acc,
+ {
+ let mut accum = init;
+ if let Some(elt) = self.top.take() {
+ accum = f(accum, elt);
+ }
+ self.iter.fold(accum, f)
+ }
+}
+
+#[derive(Debug, Clone)]
+/// An iterator adaptor that iterates over the cartesian product of
+/// the element sets of two iterators `I` and `J`.
+///
+/// Iterator element type is `(I::Item, J::Item)`.
+///
+/// See [`.cartesian_product()`](crate::Itertools::cartesian_product) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Product<I, J>
+ where I: Iterator
+{
+ a: I,
+ a_cur: Option<I::Item>,
+ b: J,
+ b_orig: J,
+}
+
+/// Create a new cartesian product iterator
+///
+/// Iterator element type is `(I::Item, J::Item)`.
+pub fn cartesian_product<I, J>(mut i: I, j: J) -> Product<I, J>
+ where I: Iterator,
+ J: Clone + Iterator,
+ I::Item: Clone
+{
+ Product {
+ a_cur: i.next(),
+ a: i,
+ b: j.clone(),
+ b_orig: j,
+ }
+}
+
+impl<I, J> Iterator for Product<I, J>
+ where I: Iterator,
+ J: Clone + Iterator,
+ I::Item: Clone
+{
+ type Item = (I::Item, J::Item);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let elt_b = match self.b.next() {
+ None => {
+ self.b = self.b_orig.clone();
+ match self.b.next() {
+ None => return None,
+ Some(x) => {
+ self.a_cur = self.a.next();
+ x
+ }
+ }
+ }
+ Some(x) => x
+ };
+ self.a_cur.as_ref().map(|a| (a.clone(), elt_b))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let has_cur = self.a_cur.is_some() as usize;
+ // Not ExactSizeIterator because size may be larger than usize
+ let (b_min, b_max) = self.b.size_hint();
+
+ // Compute a * b_orig + b for both lower and upper bound
+ size_hint::add(
+ size_hint::mul(self.a.size_hint(), self.b_orig.size_hint()),
+ (b_min * has_cur, b_max.map(move |x| x * has_cur)))
+ }
+
+ fn fold<Acc, G>(mut self, mut accum: Acc, mut f: G) -> Acc
+ where G: FnMut(Acc, Self::Item) -> Acc,
+ {
+ // use a split loop to handle the loose a_cur as well as avoiding to
+ // clone b_orig at the end.
+ if let Some(mut a) = self.a_cur.take() {
+ let mut b = self.b;
+ loop {
+ accum = b.fold(accum, |acc, elt| f(acc, (a.clone(), elt)));
+
+ // we can only continue iterating a if we had a first element;
+ if let Some(next_a) = self.a.next() {
+ b = self.b_orig.clone();
+ a = next_a;
+ } else {
+ break;
+ }
+ }
+ }
+ accum
+ }
+}
+
+impl<I, J> FusedIterator for Product<I, J>
+ where I: FusedIterator,
+ J: Clone + FusedIterator,
+ I::Item: Clone
+{}
+
+/// A “meta iterator adaptor”. Its closure receives a reference to the iterator
+/// and may pick off as many elements as it likes, to produce the next iterator element.
+///
+/// Iterator element type is *X*, if the return type of `F` is *Option\<X\>*.
+///
+/// See [`.batching()`](crate::Itertools::batching) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Batching<I, F> {
+ f: F,
+ iter: I,
+}
+
+impl<I, F> fmt::Debug for Batching<I, F> where I: fmt::Debug {
+ debug_fmt_fields!(Batching, iter);
+}
+
+/// Create a new Batching iterator.
+pub fn batching<I, F>(iter: I, f: F) -> Batching<I, F> {
+ Batching { f, iter }
+}
+
+impl<B, F, I> Iterator for Batching<I, F>
+ where I: Iterator,
+ F: FnMut(&mut I) -> Option<B>
+{
+ type Item = B;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ (self.f)(&mut self.iter)
+ }
+}
+
+/// An iterator adaptor that steps a number elements in the base iterator
+/// for each iteration.
+///
+/// The iterator steps by yielding the next element from the base iterator,
+/// then skipping forward *n-1* elements.
+///
+/// See [`.step()`](crate::Itertools::step) for more information.
+#[deprecated(note="Use std .step_by() instead", since="0.8.0")]
+#[allow(deprecated)]
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Step<I> {
+ iter: Fuse<I>,
+ skip: usize,
+}
+
+/// Create a `Step` iterator.
+///
+/// **Panics** if the step is 0.
+#[allow(deprecated)]
+pub fn step<I>(iter: I, step: usize) -> Step<I>
+ where I: Iterator
+{
+ assert!(step != 0);
+ Step {
+ iter: iter.fuse(),
+ skip: step - 1,
+ }
+}
+
+#[allow(deprecated)]
+impl<I> Iterator for Step<I>
+ where I: Iterator
+{
+ type Item = I::Item;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ let elt = self.iter.next();
+ if self.skip > 0 {
+ self.iter.nth(self.skip - 1);
+ }
+ elt
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (low, high) = self.iter.size_hint();
+ let div = |x: usize| {
+ if x == 0 {
+ 0
+ } else {
+ 1 + (x - 1) / (self.skip + 1)
+ }
+ };
+ (div(low), high.map(div))
+ }
+}
+
+// known size
+#[allow(deprecated)]
+impl<I> ExactSizeIterator for Step<I>
+ where I: ExactSizeIterator
+{}
+
+pub trait MergePredicate<T> {
+ fn merge_pred(&mut self, a: &T, b: &T) -> bool;
+}
+
+#[derive(Clone, Debug)]
+pub struct MergeLte;
+
+impl<T: PartialOrd> MergePredicate<T> for MergeLte {
+ fn merge_pred(&mut self, a: &T, b: &T) -> bool {
+ a <= b
+ }
+}
+
+/// An iterator adaptor that merges the two base iterators in ascending order.
+/// If both base iterators are sorted (ascending), the result is sorted.
+///
+/// Iterator element type is `I::Item`.
+///
+/// See [`.merge()`](crate::Itertools::merge_by) for more information.
+pub type Merge<I, J> = MergeBy<I, J, MergeLte>;
+
+/// Create an iterator that merges elements in `i` and `j`.
+///
+/// [`IntoIterator`] enabled version of [`Itertools::merge`](crate::Itertools::merge).
+///
+/// ```
+/// use itertools::merge;
+///
+/// for elt in merge(&[1, 2, 3], &[2, 3, 4]) {
+/// /* loop body */
+/// }
+/// ```
+pub fn merge<I, J>(i: I, j: J) -> Merge<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
+ where I: IntoIterator,
+ J: IntoIterator<Item = I::Item>,
+ I::Item: PartialOrd
+{
+ merge_by_new(i, j, MergeLte)
+}
+
+/// An iterator adaptor that merges the two base iterators in ascending order.
+/// If both base iterators are sorted (ascending), the result is sorted.
+///
+/// Iterator element type is `I::Item`.
+///
+/// See [`.merge_by()`](crate::Itertools::merge_by) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct MergeBy<I, J, F>
+ where I: Iterator,
+ J: Iterator<Item = I::Item>
+{
+ a: Peekable<I>,
+ b: Peekable<J>,
+ fused: Option<bool>,
+ cmp: F,
+}
+
+impl<I, J, F> fmt::Debug for MergeBy<I, J, F>
+ where I: Iterator + fmt::Debug, J: Iterator<Item = I::Item> + fmt::Debug,
+ I::Item: fmt::Debug,
+{
+ debug_fmt_fields!(MergeBy, a, b);
+}
+
+impl<T, F: FnMut(&T, &T)->bool> MergePredicate<T> for F {
+ fn merge_pred(&mut self, a: &T, b: &T) -> bool {
+ self(a, b)
+ }
+}
+
+/// Create a `MergeBy` iterator.
+pub fn merge_by_new<I, J, F>(a: I, b: J, cmp: F) -> MergeBy<I::IntoIter, J::IntoIter, F>
+ where I: IntoIterator,
+ J: IntoIterator<Item = I::Item>,
+ F: MergePredicate<I::Item>,
+{
+ MergeBy {
+ a: a.into_iter().peekable(),
+ b: b.into_iter().peekable(),
+ fused: None,
+ cmp,
+ }
+}
+
+impl<I, J, F> Clone for MergeBy<I, J, F>
+ where I: Iterator,
+ J: Iterator<Item = I::Item>,
+ Peekable<I>: Clone,
+ Peekable<J>: Clone,
+ F: Clone
+{
+ clone_fields!(a, b, fused, cmp);
+}
+
+impl<I, J, F> Iterator for MergeBy<I, J, F>
+ where I: Iterator,
+ J: Iterator<Item = I::Item>,
+ F: MergePredicate<I::Item>
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let less_than = match self.fused {
+ Some(lt) => lt,
+ None => match (self.a.peek(), self.b.peek()) {
+ (Some(a), Some(b)) => self.cmp.merge_pred(a, b),
+ (Some(_), None) => {
+ self.fused = Some(true);
+ true
+ }
+ (None, Some(_)) => {
+ self.fused = Some(false);
+ false
+ }
+ (None, None) => return None,
+ }
+ };
+ if less_than {
+ self.a.next()
+ } else {
+ self.b.next()
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ // Not ExactSizeIterator because size may be larger than usize
+ size_hint::add(self.a.size_hint(), self.b.size_hint())
+ }
+}
+
+impl<I, J, F> FusedIterator for MergeBy<I, J, F>
+ where I: FusedIterator,
+ J: FusedIterator<Item = I::Item>,
+ F: MergePredicate<I::Item>
+{}
+
+/// An iterator adaptor that borrows from a `Clone`-able iterator
+/// to only pick off elements while the predicate returns `true`.
+///
+/// See [`.take_while_ref()`](crate::Itertools::take_while_ref) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct TakeWhileRef<'a, I: 'a, F> {
+ iter: &'a mut I,
+ f: F,
+}
+
+impl<'a, I, F> fmt::Debug for TakeWhileRef<'a, I, F>
+ where I: Iterator + fmt::Debug,
+{
+ debug_fmt_fields!(TakeWhileRef, iter);
+}
+
+/// Create a new `TakeWhileRef` from a reference to clonable iterator.
+pub fn take_while_ref<I, F>(iter: &mut I, f: F) -> TakeWhileRef<I, F>
+ where I: Iterator + Clone
+{
+ TakeWhileRef { iter, f }
+}
+
+impl<'a, I, F> Iterator for TakeWhileRef<'a, I, F>
+ where I: Iterator + Clone,
+ F: FnMut(&I::Item) -> bool
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let old = self.iter.clone();
+ match self.iter.next() {
+ None => None,
+ Some(elt) => {
+ if (self.f)(&elt) {
+ Some(elt)
+ } else {
+ *self.iter = old;
+ None
+ }
+ }
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (0, self.iter.size_hint().1)
+ }
+}
+
+/// An iterator adaptor that filters `Option<A>` iterator elements
+/// and produces `A`. Stops on the first `None` encountered.
+///
+/// See [`.while_some()`](crate::Itertools::while_some) for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct WhileSome<I> {
+ iter: I,
+}
+
+/// Create a new `WhileSome<I>`.
+pub fn while_some<I>(iter: I) -> WhileSome<I> {
+ WhileSome { iter }
+}
+
+impl<I, A> Iterator for WhileSome<I>
+ where I: Iterator<Item = Option<A>>
+{
+ type Item = A;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.iter.next() {
+ None | Some(None) => None,
+ Some(elt) => elt,
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (0, self.iter.size_hint().1)
+ }
+}
+
+/// An iterator to iterate through all combinations in a `Clone`-able iterator that produces tuples
+/// of a specific size.
+///
+/// See [`.tuple_combinations()`](crate::Itertools::tuple_combinations) for more
+/// information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct TupleCombinations<I, T>
+ where I: Iterator,
+ T: HasCombination<I>
+{
+ iter: T::Combination,
+ _mi: PhantomData<I>,
+}
+
+pub trait HasCombination<I>: Sized {
+ type Combination: From<I> + Iterator<Item = Self>;
+}
+
+/// Create a new `TupleCombinations` from a clonable iterator.
+pub fn tuple_combinations<T, I>(iter: I) -> TupleCombinations<I, T>
+ where I: Iterator + Clone,
+ I::Item: Clone,
+ T: HasCombination<I>,
+{
+ TupleCombinations {
+ iter: T::Combination::from(iter),
+ _mi: PhantomData,
+ }
+}
+
+impl<I, T> Iterator for TupleCombinations<I, T>
+ where I: Iterator,
+ T: HasCombination<I>,
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next()
+ }
+}
+
+impl<I, T> FusedIterator for TupleCombinations<I, T>
+ where I: FusedIterator,
+ T: HasCombination<I>,
+{}
+
+#[derive(Clone, Debug)]
+pub struct Tuple1Combination<I> {
+ iter: I,
+}
+
+impl<I> From<I> for Tuple1Combination<I> {
+ fn from(iter: I) -> Self {
+ Tuple1Combination { iter }
+ }
+}
+
+impl<I: Iterator> Iterator for Tuple1Combination<I> {
+ type Item = (I::Item,);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next().map(|x| (x,))
+ }
+}
+
+impl<I: Iterator> HasCombination<I> for (I::Item,) {
+ type Combination = Tuple1Combination<I>;
+}
+
+macro_rules! impl_tuple_combination {
+ ($C:ident $P:ident ; $($X:ident)*) => (
+ #[derive(Clone, Debug)]
+ pub struct $C<I: Iterator> {
+ item: Option<I::Item>,
+ iter: I,
+ c: $P<I>,
+ }
+
+ impl<I: Iterator + Clone> From<I> for $C<I> {
+ fn from(mut iter: I) -> Self {
+ Self {
+ item: iter.next(),
+ iter: iter.clone(),
+ c: iter.into(),
+ }
+ }
+ }
+
+ impl<I: Iterator + Clone> From<I> for $C<Fuse<I>> {
+ fn from(iter: I) -> Self {
+ Self::from(iter.fuse())
+ }
+ }
+
+ impl<I, A> Iterator for $C<I>
+ where I: Iterator<Item = A> + Clone,
+ I::Item: Clone
+ {
+ type Item = (A, $(ignore_ident!($X, A)),*);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if let Some(($($X),*,)) = self.c.next() {
+ let z = self.item.clone().unwrap();
+ Some((z, $($X),*))
+ } else {
+ self.item = self.iter.next();
+ self.item.clone().and_then(|z| {
+ self.c = self.iter.clone().into();
+ self.c.next().map(|($($X),*,)| (z, $($X),*))
+ })
+ }
+ }
+ }
+
+ impl<I, A> HasCombination<I> for (A, $(ignore_ident!($X, A)),*)
+ where I: Iterator<Item = A> + Clone,
+ I::Item: Clone
+ {
+ type Combination = $C<Fuse<I>>;
+ }
+ )
+}
+
+// This snippet generates the twelve `impl_tuple_combination!` invocations:
+// use core::iter;
+// use itertools::Itertools;
+//
+// for i in 2..=12 {
+// println!("impl_tuple_combination!(Tuple{arity}Combination Tuple{prev}Combination; {idents});",
+// arity = i,
+// prev = i - 1,
+// idents = ('a'..'z').take(i - 1).join(" "),
+// );
+// }
+// It could probably be replaced by a bit more macro cleverness.
+impl_tuple_combination!(Tuple2Combination Tuple1Combination; a);
+impl_tuple_combination!(Tuple3Combination Tuple2Combination; a b);
+impl_tuple_combination!(Tuple4Combination Tuple3Combination; a b c);
+impl_tuple_combination!(Tuple5Combination Tuple4Combination; a b c d);
+impl_tuple_combination!(Tuple6Combination Tuple5Combination; a b c d e);
+impl_tuple_combination!(Tuple7Combination Tuple6Combination; a b c d e f);
+impl_tuple_combination!(Tuple8Combination Tuple7Combination; a b c d e f g);
+impl_tuple_combination!(Tuple9Combination Tuple8Combination; a b c d e f g h);
+impl_tuple_combination!(Tuple10Combination Tuple9Combination; a b c d e f g h i);
+impl_tuple_combination!(Tuple11Combination Tuple10Combination; a b c d e f g h i j);
+impl_tuple_combination!(Tuple12Combination Tuple11Combination; a b c d e f g h i j k);
+
+/// An iterator adapter to filter values within a nested `Result::Ok`.
+///
+/// See [`.filter_ok()`](crate::Itertools::filter_ok) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct FilterOk<I, F> {
+ iter: I,
+ f: F
+}
+
+impl<I, F> fmt::Debug for FilterOk<I, F>
+where
+ I: fmt::Debug,
+{
+ debug_fmt_fields!(FilterOk, iter);
+}
+
+/// Create a new `FilterOk` iterator.
+pub fn filter_ok<I, F, T, E>(iter: I, f: F) -> FilterOk<I, F>
+ where I: Iterator<Item = Result<T, E>>,
+ F: FnMut(&T) -> bool,
+{
+ FilterOk {
+ iter,
+ f,
+ }
+}
+
+impl<I, F, T, E> Iterator for FilterOk<I, F>
+ where I: Iterator<Item = Result<T, E>>,
+ F: FnMut(&T) -> bool,
+{
+ type Item = Result<T, E>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ loop {
+ match self.iter.next() {
+ Some(Ok(v)) => {
+ if (self.f)(&v) {
+ return Some(Ok(v));
+ }
+ },
+ Some(Err(e)) => return Some(Err(e)),
+ None => return None,
+ }
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (0, self.iter.size_hint().1)
+ }
+
+ fn fold<Acc, Fold>(self, init: Acc, fold_f: Fold) -> Acc
+ where Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ let mut f = self.f;
+ self.iter.filter(|v| {
+ v.as_ref().map(&mut f).unwrap_or(true)
+ }).fold(init, fold_f)
+ }
+
+ fn collect<C>(self) -> C
+ where C: FromIterator<Self::Item>
+ {
+ let mut f = self.f;
+ self.iter.filter(|v| {
+ v.as_ref().map(&mut f).unwrap_or(true)
+ }).collect()
+ }
+}
+
+impl<I, F, T, E> FusedIterator for FilterOk<I, F>
+ where I: FusedIterator<Item = Result<T, E>>,
+ F: FnMut(&T) -> bool,
+{}
+
+/// An iterator adapter to filter and apply a transformation on values within a nested `Result::Ok`.
+///
+/// See [`.filter_map_ok()`](crate::Itertools::filter_map_ok) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct FilterMapOk<I, F> {
+ iter: I,
+ f: F
+}
+
+impl<I, F> fmt::Debug for FilterMapOk<I, F>
+where
+ I: fmt::Debug,
+{
+ debug_fmt_fields!(FilterMapOk, iter);
+}
+
+fn transpose_result<T, E>(result: Result<Option<T>, E>) -> Option<Result<T, E>> {
+ match result {
+ Ok(Some(v)) => Some(Ok(v)),
+ Ok(None) => None,
+ Err(e) => Some(Err(e)),
+ }
+}
+
+/// Create a new `FilterOk` iterator.
+pub fn filter_map_ok<I, F, T, U, E>(iter: I, f: F) -> FilterMapOk<I, F>
+ where I: Iterator<Item = Result<T, E>>,
+ F: FnMut(T) -> Option<U>,
+{
+ FilterMapOk {
+ iter,
+ f,
+ }
+}
+
+impl<I, F, T, U, E> Iterator for FilterMapOk<I, F>
+ where I: Iterator<Item = Result<T, E>>,
+ F: FnMut(T) -> Option<U>,
+{
+ type Item = Result<U, E>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ loop {
+ match self.iter.next() {
+ Some(Ok(v)) => {
+ if let Some(v) = (self.f)(v) {
+ return Some(Ok(v));
+ }
+ },
+ Some(Err(e)) => return Some(Err(e)),
+ None => return None,
+ }
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (0, self.iter.size_hint().1)
+ }
+
+ fn fold<Acc, Fold>(self, init: Acc, fold_f: Fold) -> Acc
+ where Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ let mut f = self.f;
+ self.iter.filter_map(|v| {
+ transpose_result(v.map(&mut f))
+ }).fold(init, fold_f)
+ }
+
+ fn collect<C>(self) -> C
+ where C: FromIterator<Self::Item>
+ {
+ let mut f = self.f;
+ self.iter.filter_map(|v| {
+ transpose_result(v.map(&mut f))
+ }).collect()
+ }
+}
+
+impl<I, F, T, U, E> FusedIterator for FilterMapOk<I, F>
+ where I: FusedIterator<Item = Result<T, E>>,
+ F: FnMut(T) -> Option<U>,
+{}
+
+/// An iterator adapter to get the positions of each element that matches a predicate.
+///
+/// See [`.positions()`](crate::Itertools::positions) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Positions<I, F> {
+ iter: I,
+ f: F,
+ count: usize,
+}
+
+impl<I, F> fmt::Debug for Positions<I, F>
+where
+ I: fmt::Debug,
+{
+ debug_fmt_fields!(Positions, iter, count);
+}
+
+/// Create a new `Positions` iterator.
+pub fn positions<I, F>(iter: I, f: F) -> Positions<I, F>
+ where I: Iterator,
+ F: FnMut(I::Item) -> bool,
+{
+ Positions {
+ iter,
+ f,
+ count: 0
+ }
+}
+
+impl<I, F> Iterator for Positions<I, F>
+ where I: Iterator,
+ F: FnMut(I::Item) -> bool,
+{
+ type Item = usize;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ while let Some(v) = self.iter.next() {
+ let i = self.count;
+ self.count = i + 1;
+ if (self.f)(v) {
+ return Some(i);
+ }
+ }
+ None
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (0, self.iter.size_hint().1)
+ }
+}
+
+impl<I, F> DoubleEndedIterator for Positions<I, F>
+ where I: DoubleEndedIterator + ExactSizeIterator,
+ F: FnMut(I::Item) -> bool,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ while let Some(v) = self.iter.next_back() {
+ if (self.f)(v) {
+ return Some(self.count + self.iter.len())
+ }
+ }
+ None
+ }
+}
+
+impl<I, F> FusedIterator for Positions<I, F>
+ where I: FusedIterator,
+ F: FnMut(I::Item) -> bool,
+{}
+
+/// An iterator adapter to apply a mutating function to each element before yielding it.
+///
+/// See [`.update()`](crate::Itertools::update) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Update<I, F> {
+ iter: I,
+ f: F,
+}
+
+impl<I, F> fmt::Debug for Update<I, F>
+where
+ I: fmt::Debug,
+{
+ debug_fmt_fields!(Update, iter);
+}
+
+/// Create a new `Update` iterator.
+pub fn update<I, F>(iter: I, f: F) -> Update<I, F>
+where
+ I: Iterator,
+ F: FnMut(&mut I::Item),
+{
+ Update { iter, f }
+}
+
+impl<I, F> Iterator for Update<I, F>
+where
+ I: Iterator,
+ F: FnMut(&mut I::Item),
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if let Some(mut v) = self.iter.next() {
+ (self.f)(&mut v);
+ Some(v)
+ } else {
+ None
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+
+ fn fold<Acc, G>(self, init: Acc, mut g: G) -> Acc
+ where G: FnMut(Acc, Self::Item) -> Acc,
+ {
+ let mut f = self.f;
+ self.iter.fold(init, move |acc, mut v| { f(&mut v); g(acc, v) })
+ }
+
+ // if possible, re-use inner iterator specializations in collect
+ fn collect<C>(self) -> C
+ where C: FromIterator<Self::Item>
+ {
+ let mut f = self.f;
+ self.iter.map(move |mut v| { f(&mut v); v }).collect()
+ }
+}
+
+impl<I, F> ExactSizeIterator for Update<I, F>
+where
+ I: ExactSizeIterator,
+ F: FnMut(&mut I::Item),
+{}
+
+impl<I, F> DoubleEndedIterator for Update<I, F>
+where
+ I: DoubleEndedIterator,
+ F: FnMut(&mut I::Item),
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ if let Some(mut v) = self.iter.next_back() {
+ (self.f)(&mut v);
+ Some(v)
+ } else {
+ None
+ }
+ }
+}
+
+impl<I, F> FusedIterator for Update<I, F>
+where
+ I: FusedIterator,
+ F: FnMut(&mut I::Item),
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/adaptors/multi_product.rs b/rust/hw/char/pl011/vendor/itertools/src/adaptors/multi_product.rs
new file mode 100644
index 0000000000..0b38406987
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/adaptors/multi_product.rs
@@ -0,0 +1,230 @@
+#![cfg(feature = "use_alloc")]
+
+use crate::size_hint;
+use crate::Itertools;
+
+use alloc::vec::Vec;
+
+#[derive(Clone)]
+/// An iterator adaptor that iterates over the cartesian product of
+/// multiple iterators of type `I`.
+///
+/// An iterator element type is `Vec<I>`.
+///
+/// See [`.multi_cartesian_product()`](crate::Itertools::multi_cartesian_product)
+/// for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct MultiProduct<I>(Vec<MultiProductIter<I>>)
+ where I: Iterator + Clone,
+ I::Item: Clone;
+
+impl<I> std::fmt::Debug for MultiProduct<I>
+where
+ I: Iterator + Clone + std::fmt::Debug,
+ I::Item: Clone + std::fmt::Debug,
+{
+ debug_fmt_fields!(CoalesceBy, 0);
+}
+
+/// Create a new cartesian product iterator over an arbitrary number
+/// of iterators of the same type.
+///
+/// Iterator element is of type `Vec<H::Item::Item>`.
+pub fn multi_cartesian_product<H>(iters: H) -> MultiProduct<<H::Item as IntoIterator>::IntoIter>
+ where H: Iterator,
+ H::Item: IntoIterator,
+ <H::Item as IntoIterator>::IntoIter: Clone,
+ <H::Item as IntoIterator>::Item: Clone
+{
+ MultiProduct(iters.map(|i| MultiProductIter::new(i.into_iter())).collect())
+}
+
+#[derive(Clone, Debug)]
+/// Holds the state of a single iterator within a `MultiProduct`.
+struct MultiProductIter<I>
+ where I: Iterator + Clone,
+ I::Item: Clone
+{
+ cur: Option<I::Item>,
+ iter: I,
+ iter_orig: I,
+}
+
+/// Holds the current state during an iteration of a `MultiProduct`.
+#[derive(Debug)]
+enum MultiProductIterState {
+ StartOfIter,
+ MidIter { on_first_iter: bool },
+}
+
+impl<I> MultiProduct<I>
+ where I: Iterator + Clone,
+ I::Item: Clone
+{
+ /// Iterates the rightmost iterator, then recursively iterates iterators
+ /// to the left if necessary.
+ ///
+ /// Returns true if the iteration succeeded, else false.
+ fn iterate_last(
+ multi_iters: &mut [MultiProductIter<I>],
+ mut state: MultiProductIterState
+ ) -> bool {
+ use self::MultiProductIterState::*;
+
+ if let Some((last, rest)) = multi_iters.split_last_mut() {
+ let on_first_iter = match state {
+ StartOfIter => {
+ let on_first_iter = !last.in_progress();
+ state = MidIter { on_first_iter };
+ on_first_iter
+ },
+ MidIter { on_first_iter } => on_first_iter
+ };
+
+ if !on_first_iter {
+ last.iterate();
+ }
+
+ if last.in_progress() {
+ true
+ } else if MultiProduct::iterate_last(rest, state) {
+ last.reset();
+ last.iterate();
+ // If iterator is None twice consecutively, then iterator is
+ // empty; whole product is empty.
+ last.in_progress()
+ } else {
+ false
+ }
+ } else {
+ // Reached end of iterator list. On initialisation, return true.
+ // At end of iteration (final iterator finishes), finish.
+ match state {
+ StartOfIter => false,
+ MidIter { on_first_iter } => on_first_iter
+ }
+ }
+ }
+
+ /// Returns the unwrapped value of the next iteration.
+ fn curr_iterator(&self) -> Vec<I::Item> {
+ self.0.iter().map(|multi_iter| {
+ multi_iter.cur.clone().unwrap()
+ }).collect()
+ }
+
+ /// Returns true if iteration has started and has not yet finished; false
+ /// otherwise.
+ fn in_progress(&self) -> bool {
+ if let Some(last) = self.0.last() {
+ last.in_progress()
+ } else {
+ false
+ }
+ }
+}
+
+impl<I> MultiProductIter<I>
+ where I: Iterator + Clone,
+ I::Item: Clone
+{
+ fn new(iter: I) -> Self {
+ MultiProductIter {
+ cur: None,
+ iter: iter.clone(),
+ iter_orig: iter
+ }
+ }
+
+ /// Iterate the managed iterator.
+ fn iterate(&mut self) {
+ self.cur = self.iter.next();
+ }
+
+ /// Reset the managed iterator.
+ fn reset(&mut self) {
+ self.iter = self.iter_orig.clone();
+ }
+
+ /// Returns true if the current iterator has been started and has not yet
+ /// finished; false otherwise.
+ fn in_progress(&self) -> bool {
+ self.cur.is_some()
+ }
+}
+
+impl<I> Iterator for MultiProduct<I>
+ where I: Iterator + Clone,
+ I::Item: Clone
+{
+ type Item = Vec<I::Item>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if MultiProduct::iterate_last(
+ &mut self.0,
+ MultiProductIterState::StartOfIter
+ ) {
+ Some(self.curr_iterator())
+ } else {
+ None
+ }
+ }
+
+ fn count(self) -> usize {
+ if self.0.is_empty() {
+ return 0;
+ }
+
+ if !self.in_progress() {
+ return self.0.into_iter().fold(1, |acc, multi_iter| {
+ acc * multi_iter.iter.count()
+ });
+ }
+
+ self.0.into_iter().fold(
+ 0,
+ |acc, MultiProductIter { iter, iter_orig, cur: _ }| {
+ let total_count = iter_orig.count();
+ let cur_count = iter.count();
+ acc * total_count + cur_count
+ }
+ )
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ // Not ExactSizeIterator because size may be larger than usize
+ if self.0.is_empty() {
+ return (0, Some(0));
+ }
+
+ if !self.in_progress() {
+ return self.0.iter().fold((1, Some(1)), |acc, multi_iter| {
+ size_hint::mul(acc, multi_iter.iter.size_hint())
+ });
+ }
+
+ self.0.iter().fold(
+ (0, Some(0)),
+ |acc, &MultiProductIter { ref iter, ref iter_orig, cur: _ }| {
+ let cur_size = iter.size_hint();
+ let total_size = iter_orig.size_hint();
+ size_hint::add(size_hint::mul(acc, total_size), cur_size)
+ }
+ )
+ }
+
+ fn last(self) -> Option<Self::Item> {
+ let iter_count = self.0.len();
+
+ let lasts: Self::Item = self.0.into_iter()
+ .map(|multi_iter| multi_iter.iter.last())
+ .while_some()
+ .collect();
+
+ if lasts.len() == iter_count {
+ Some(lasts)
+ } else {
+ None
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/combinations.rs b/rust/hw/char/pl011/vendor/itertools/src/combinations.rs
new file mode 100644
index 0000000000..68a59c5e4d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/combinations.rs
@@ -0,0 +1,128 @@
+use std::fmt;
+use std::iter::FusedIterator;
+
+use super::lazy_buffer::LazyBuffer;
+use alloc::vec::Vec;
+
+/// An iterator to iterate through all the `k`-length combinations in an iterator.
+///
+/// See [`.combinations()`](crate::Itertools::combinations) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Combinations<I: Iterator> {
+ indices: Vec<usize>,
+ pool: LazyBuffer<I>,
+ first: bool,
+}
+
+impl<I> Clone for Combinations<I>
+ where I: Clone + Iterator,
+ I::Item: Clone,
+{
+ clone_fields!(indices, pool, first);
+}
+
+impl<I> fmt::Debug for Combinations<I>
+ where I: Iterator + fmt::Debug,
+ I::Item: fmt::Debug,
+{
+ debug_fmt_fields!(Combinations, indices, pool, first);
+}
+
+/// Create a new `Combinations` from a clonable iterator.
+pub fn combinations<I>(iter: I, k: usize) -> Combinations<I>
+ where I: Iterator
+{
+ let mut pool = LazyBuffer::new(iter);
+ pool.prefill(k);
+
+ Combinations {
+ indices: (0..k).collect(),
+ pool,
+ first: true,
+ }
+}
+
+impl<I: Iterator> Combinations<I> {
+ /// Returns the length of a combination produced by this iterator.
+ #[inline]
+ pub fn k(&self) -> usize { self.indices.len() }
+
+ /// Returns the (current) length of the pool from which combination elements are
+ /// selected. This value can change between invocations of [`next`](Combinations::next).
+ #[inline]
+ pub fn n(&self) -> usize { self.pool.len() }
+
+ /// Returns a reference to the source iterator.
+ #[inline]
+ pub(crate) fn src(&self) -> &I { &self.pool.it }
+
+ /// Resets this `Combinations` back to an initial state for combinations of length
+ /// `k` over the same pool data source. If `k` is larger than the current length
+ /// of the data pool an attempt is made to prefill the pool so that it holds `k`
+ /// elements.
+ pub(crate) fn reset(&mut self, k: usize) {
+ self.first = true;
+
+ if k < self.indices.len() {
+ self.indices.truncate(k);
+ for i in 0..k {
+ self.indices[i] = i;
+ }
+
+ } else {
+ for i in 0..self.indices.len() {
+ self.indices[i] = i;
+ }
+ self.indices.extend(self.indices.len()..k);
+ self.pool.prefill(k);
+ }
+ }
+}
+
+impl<I> Iterator for Combinations<I>
+ where I: Iterator,
+ I::Item: Clone
+{
+ type Item = Vec<I::Item>;
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.first {
+ if self.k() > self.n() {
+ return None;
+ }
+ self.first = false;
+ } else if self.indices.is_empty() {
+ return None;
+ } else {
+ // Scan from the end, looking for an index to increment
+ let mut i: usize = self.indices.len() - 1;
+
+ // Check if we need to consume more from the iterator
+ if self.indices[i] == self.pool.len() - 1 {
+ self.pool.get_next(); // may change pool size
+ }
+
+ while self.indices[i] == i + self.pool.len() - self.indices.len() {
+ if i > 0 {
+ i -= 1;
+ } else {
+ // Reached the last combination
+ return None;
+ }
+ }
+
+ // Increment index, and reset the ones to its right
+ self.indices[i] += 1;
+ for j in i+1..self.indices.len() {
+ self.indices[j] = self.indices[j - 1] + 1;
+ }
+ }
+
+ // Create result vector based on the indices
+ Some(self.indices.iter().map(|i| self.pool[*i].clone()).collect())
+ }
+}
+
+impl<I> FusedIterator for Combinations<I>
+ where I: Iterator,
+ I::Item: Clone
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/combinations_with_replacement.rs b/rust/hw/char/pl011/vendor/itertools/src/combinations_with_replacement.rs
new file mode 100644
index 0000000000..0fec9671ac
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/combinations_with_replacement.rs
@@ -0,0 +1,109 @@
+use alloc::vec::Vec;
+use std::fmt;
+use std::iter::FusedIterator;
+
+use super::lazy_buffer::LazyBuffer;
+
+/// An iterator to iterate through all the `n`-length combinations in an iterator, with replacement.
+///
+/// See [`.combinations_with_replacement()`](crate::Itertools::combinations_with_replacement)
+/// for more information.
+#[derive(Clone)]
+pub struct CombinationsWithReplacement<I>
+where
+ I: Iterator,
+ I::Item: Clone,
+{
+ indices: Vec<usize>,
+ pool: LazyBuffer<I>,
+ first: bool,
+}
+
+impl<I> fmt::Debug for CombinationsWithReplacement<I>
+where
+ I: Iterator + fmt::Debug,
+ I::Item: fmt::Debug + Clone,
+{
+ debug_fmt_fields!(Combinations, indices, pool, first);
+}
+
+impl<I> CombinationsWithReplacement<I>
+where
+ I: Iterator,
+ I::Item: Clone,
+{
+ /// Map the current mask over the pool to get an output combination
+ fn current(&self) -> Vec<I::Item> {
+ self.indices.iter().map(|i| self.pool[*i].clone()).collect()
+ }
+}
+
+/// Create a new `CombinationsWithReplacement` from a clonable iterator.
+pub fn combinations_with_replacement<I>(iter: I, k: usize) -> CombinationsWithReplacement<I>
+where
+ I: Iterator,
+ I::Item: Clone,
+{
+ let indices: Vec<usize> = alloc::vec![0; k];
+ let pool: LazyBuffer<I> = LazyBuffer::new(iter);
+
+ CombinationsWithReplacement {
+ indices,
+ pool,
+ first: true,
+ }
+}
+
+impl<I> Iterator for CombinationsWithReplacement<I>
+where
+ I: Iterator,
+ I::Item: Clone,
+{
+ type Item = Vec<I::Item>;
+ fn next(&mut self) -> Option<Self::Item> {
+ // If this is the first iteration, return early
+ if self.first {
+ // In empty edge cases, stop iterating immediately
+ return if !(self.indices.is_empty() || self.pool.get_next()) {
+ None
+ // Otherwise, yield the initial state
+ } else {
+ self.first = false;
+ Some(self.current())
+ };
+ }
+
+ // Check if we need to consume more from the iterator
+ // This will run while we increment our first index digit
+ self.pool.get_next();
+
+ // Work out where we need to update our indices
+ let mut increment: Option<(usize, usize)> = None;
+ for (i, indices_int) in self.indices.iter().enumerate().rev() {
+ if *indices_int < self.pool.len()-1 {
+ increment = Some((i, indices_int + 1));
+ break;
+ }
+ }
+
+ match increment {
+ // If we can update the indices further
+ Some((increment_from, increment_value)) => {
+ // We need to update the rightmost non-max value
+ // and all those to the right
+ for indices_index in increment_from..self.indices.len() {
+ self.indices[indices_index] = increment_value;
+ }
+ Some(self.current())
+ }
+ // Otherwise, we're done
+ None => None,
+ }
+ }
+}
+
+impl<I> FusedIterator for CombinationsWithReplacement<I>
+where
+ I: Iterator,
+ I::Item: Clone,
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/concat_impl.rs b/rust/hw/char/pl011/vendor/itertools/src/concat_impl.rs
new file mode 100644
index 0000000000..f022ec90af
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/concat_impl.rs
@@ -0,0 +1,23 @@
+use crate::Itertools;
+
+/// Combine all an iterator's elements into one element by using [`Extend`].
+///
+/// [`IntoIterator`]-enabled version of [`Itertools::concat`].
+///
+/// This combinator will extend the first item with each of the rest of the
+/// items of the iterator. If the iterator is empty, the default value of
+/// `I::Item` is returned.
+///
+/// ```rust
+/// use itertools::concat;
+///
+/// let input = vec![vec![1], vec![2, 3], vec![4, 5, 6]];
+/// assert_eq!(concat(input), vec![1, 2, 3, 4, 5, 6]);
+/// ```
+pub fn concat<I>(iterable: I) -> I::Item
+ where I: IntoIterator,
+ I::Item: Extend<<<I as IntoIterator>::Item as IntoIterator>::Item> + IntoIterator + Default
+{
+ #[allow(deprecated)] //TODO: once msrv hits 1.51. replace `fold1` with `reduce`
+ iterable.into_iter().fold1(|mut a, b| { a.extend(b); a }).unwrap_or_default()
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/cons_tuples_impl.rs b/rust/hw/char/pl011/vendor/itertools/src/cons_tuples_impl.rs
new file mode 100644
index 0000000000..ae0f48f349
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/cons_tuples_impl.rs
@@ -0,0 +1,64 @@
+
+macro_rules! impl_cons_iter(
+ ($_A:ident, $_B:ident, ) => (); // stop
+
+ ($A:ident, $($B:ident,)*) => (
+ impl_cons_iter!($($B,)*);
+ #[allow(non_snake_case)]
+ impl<X, Iter, $($B),*> Iterator for ConsTuples<Iter, (($($B,)*), X)>
+ where Iter: Iterator<Item = (($($B,)*), X)>,
+ {
+ type Item = ($($B,)* X, );
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next().map(|(($($B,)*), x)| ($($B,)* x, ))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+ fn fold<Acc, Fold>(self, accum: Acc, mut f: Fold) -> Acc
+ where Fold: FnMut(Acc, Self::Item) -> Acc,
+ {
+ self.iter.fold(accum, move |acc, (($($B,)*), x)| f(acc, ($($B,)* x, )))
+ }
+ }
+
+ #[allow(non_snake_case)]
+ impl<X, Iter, $($B),*> DoubleEndedIterator for ConsTuples<Iter, (($($B,)*), X)>
+ where Iter: DoubleEndedIterator<Item = (($($B,)*), X)>,
+ {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter.next().map(|(($($B,)*), x)| ($($B,)* x, ))
+ }
+ }
+
+ );
+);
+
+impl_cons_iter!(A, B, C, D, E, F, G, H, I, J, K, L,);
+
+/// An iterator that maps an iterator of tuples like
+/// `((A, B), C)` to an iterator of `(A, B, C)`.
+///
+/// Used by the `iproduct!()` macro.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Debug)]
+pub struct ConsTuples<I, J>
+ where I: Iterator<Item=J>,
+{
+ iter: I,
+}
+
+impl<I, J> Clone for ConsTuples<I, J>
+ where I: Clone + Iterator<Item=J>,
+{
+ clone_fields!(iter);
+}
+
+/// Create an iterator that maps for example iterators of
+/// `((A, B), C)` to `(A, B, C)`.
+pub fn cons_tuples<I, J>(iterable: I) -> ConsTuples<I::IntoIter, J>
+ where I: IntoIterator<Item=J>
+{
+ ConsTuples { iter: iterable.into_iter() }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/diff.rs b/rust/hw/char/pl011/vendor/itertools/src/diff.rs
new file mode 100644
index 0000000000..1731f0639f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/diff.rs
@@ -0,0 +1,61 @@
+//! "Diff"ing iterators for caching elements to sequential collections without requiring the new
+//! elements' iterator to be `Clone`.
+//!
+//! - [`Diff`] (produced by the [`diff_with`] function)
+//! describes the difference between two non-`Clone` iterators `I` and `J` after breaking ASAP from
+//! a lock-step comparison.
+
+use crate::free::put_back;
+use crate::structs::PutBack;
+
+/// A type returned by the [`diff_with`] function.
+///
+/// `Diff` represents the way in which the elements yielded by the iterator `I` differ to some
+/// iterator `J`.
+pub enum Diff<I, J>
+ where I: Iterator,
+ J: Iterator
+{
+ /// The index of the first non-matching element along with both iterator's remaining elements
+ /// starting with the first mis-match.
+ FirstMismatch(usize, PutBack<I>, PutBack<J>),
+ /// The total number of elements that were in `J` along with the remaining elements of `I`.
+ Shorter(usize, PutBack<I>),
+ /// The total number of elements that were in `I` along with the remaining elements of `J`.
+ Longer(usize, PutBack<J>),
+}
+
+/// Compares every element yielded by both `i` and `j` with the given function in lock-step and
+/// returns a [`Diff`] which describes how `j` differs from `i`.
+///
+/// If the number of elements yielded by `j` is less than the number of elements yielded by `i`,
+/// the number of `j` elements yielded will be returned along with `i`'s remaining elements as
+/// `Diff::Shorter`.
+///
+/// If the two elements of a step differ, the index of those elements along with the remaining
+/// elements of both `i` and `j` are returned as `Diff::FirstMismatch`.
+///
+/// If `i` becomes exhausted before `j` becomes exhausted, the number of elements in `i` along with
+/// the remaining `j` elements will be returned as `Diff::Longer`.
+pub fn diff_with<I, J, F>(i: I, j: J, is_equal: F)
+ -> Option<Diff<I::IntoIter, J::IntoIter>>
+ where I: IntoIterator,
+ J: IntoIterator,
+ F: Fn(&I::Item, &J::Item) -> bool
+{
+ let mut i = i.into_iter();
+ let mut j = j.into_iter();
+ let mut idx = 0;
+ while let Some(i_elem) = i.next() {
+ match j.next() {
+ None => return Some(Diff::Shorter(idx, put_back(i).with_value(i_elem))),
+ Some(j_elem) => if !is_equal(&i_elem, &j_elem) {
+ let remaining_i = put_back(i).with_value(i_elem);
+ let remaining_j = put_back(j).with_value(j_elem);
+ return Some(Diff::FirstMismatch(idx, remaining_i, remaining_j));
+ },
+ }
+ idx += 1;
+ }
+ j.next().map(|j_elem| Diff::Longer(idx, put_back(j).with_value(j_elem)))
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/duplicates_impl.rs b/rust/hw/char/pl011/vendor/itertools/src/duplicates_impl.rs
new file mode 100644
index 0000000000..28eda44a97
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/duplicates_impl.rs
@@ -0,0 +1,216 @@
+use std::hash::Hash;
+
+mod private {
+ use std::collections::HashMap;
+ use std::hash::Hash;
+ use std::fmt;
+
+ #[derive(Clone)]
+ #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+ pub struct DuplicatesBy<I: Iterator, Key, F> {
+ pub(crate) iter: I,
+ pub(crate) meta: Meta<Key, F>,
+ }
+
+ impl<I, V, F> fmt::Debug for DuplicatesBy<I, V, F>
+ where
+ I: Iterator + fmt::Debug,
+ V: fmt::Debug + Hash + Eq,
+ {
+ debug_fmt_fields!(DuplicatesBy, iter, meta.used);
+ }
+
+ impl<I: Iterator, Key: Eq + Hash, F> DuplicatesBy<I, Key, F> {
+ pub(crate) fn new(iter: I, key_method: F) -> Self {
+ DuplicatesBy {
+ iter,
+ meta: Meta {
+ used: HashMap::new(),
+ pending: 0,
+ key_method,
+ },
+ }
+ }
+ }
+
+ #[derive(Clone)]
+ pub struct Meta<Key, F> {
+ used: HashMap<Key, bool>,
+ pending: usize,
+ key_method: F,
+ }
+
+ impl<Key, F> Meta<Key, F>
+ where
+ Key: Eq + Hash,
+ {
+ /// Takes an item and returns it back to the caller if it's the second time we see it.
+ /// Otherwise the item is consumed and None is returned
+ #[inline(always)]
+ fn filter<I>(&mut self, item: I) -> Option<I>
+ where
+ F: KeyMethod<Key, I>,
+ {
+ let kv = self.key_method.make(item);
+ match self.used.get_mut(kv.key_ref()) {
+ None => {
+ self.used.insert(kv.key(), false);
+ self.pending += 1;
+ None
+ }
+ Some(true) => None,
+ Some(produced) => {
+ *produced = true;
+ self.pending -= 1;
+ Some(kv.value())
+ }
+ }
+ }
+ }
+
+ impl<I, Key, F> Iterator for DuplicatesBy<I, Key, F>
+ where
+ I: Iterator,
+ Key: Eq + Hash,
+ F: KeyMethod<Key, I::Item>,
+ {
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let DuplicatesBy { iter, meta } = self;
+ iter.find_map(|v| meta.filter(v))
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (_, hi) = self.iter.size_hint();
+ let hi = hi.map(|hi| {
+ if hi <= self.meta.pending {
+ // fewer or equally many iter-remaining elements than pending elements
+ // => at most, each iter-remaining element is matched
+ hi
+ } else {
+ // fewer pending elements than iter-remaining elements
+ // => at most:
+ // * each pending element is matched
+ // * the other iter-remaining elements come in pairs
+ self.meta.pending + (hi - self.meta.pending) / 2
+ }
+ });
+ // The lower bound is always 0 since we might only get unique items from now on
+ (0, hi)
+ }
+ }
+
+ impl<I, Key, F> DoubleEndedIterator for DuplicatesBy<I, Key, F>
+ where
+ I: DoubleEndedIterator,
+ Key: Eq + Hash,
+ F: KeyMethod<Key, I::Item>,
+ {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ let DuplicatesBy { iter, meta } = self;
+ iter.rev().find_map(|v| meta.filter(v))
+ }
+ }
+
+ /// A keying method for use with `DuplicatesBy`
+ pub trait KeyMethod<K, V> {
+ type Container: KeyXorValue<K, V>;
+
+ fn make(&mut self, value: V) -> Self::Container;
+ }
+
+ /// Apply the identity function to elements before checking them for equality.
+ #[derive(Debug)]
+ pub struct ById;
+ impl<V> KeyMethod<V, V> for ById {
+ type Container = JustValue<V>;
+
+ fn make(&mut self, v: V) -> Self::Container {
+ JustValue(v)
+ }
+ }
+
+ /// Apply a user-supplied function to elements before checking them for equality.
+ pub struct ByFn<F>(pub(crate) F);
+ impl<F> fmt::Debug for ByFn<F> {
+ debug_fmt_fields!(ByFn,);
+ }
+ impl<K, V, F> KeyMethod<K, V> for ByFn<F>
+ where
+ F: FnMut(&V) -> K,
+ {
+ type Container = KeyValue<K, V>;
+
+ fn make(&mut self, v: V) -> Self::Container {
+ KeyValue((self.0)(&v), v)
+ }
+ }
+
+ // Implementors of this trait can hold onto a key and a value but only give access to one of them
+ // at a time. This allows the key and the value to be the same value internally
+ pub trait KeyXorValue<K, V> {
+ fn key_ref(&self) -> &K;
+ fn key(self) -> K;
+ fn value(self) -> V;
+ }
+
+ #[derive(Debug)]
+ pub struct KeyValue<K, V>(K, V);
+ impl<K, V> KeyXorValue<K, V> for KeyValue<K, V> {
+ fn key_ref(&self) -> &K {
+ &self.0
+ }
+ fn key(self) -> K {
+ self.0
+ }
+ fn value(self) -> V {
+ self.1
+ }
+ }
+
+ #[derive(Debug)]
+ pub struct JustValue<V>(V);
+ impl<V> KeyXorValue<V, V> for JustValue<V> {
+ fn key_ref(&self) -> &V {
+ &self.0
+ }
+ fn key(self) -> V {
+ self.0
+ }
+ fn value(self) -> V {
+ self.0
+ }
+ }
+}
+
+/// An iterator adapter to filter for duplicate elements.
+///
+/// See [`.duplicates_by()`](crate::Itertools::duplicates_by) for more information.
+pub type DuplicatesBy<I, V, F> = private::DuplicatesBy<I, V, private::ByFn<F>>;
+
+/// Create a new `DuplicatesBy` iterator.
+pub fn duplicates_by<I, Key, F>(iter: I, f: F) -> DuplicatesBy<I, Key, F>
+where
+ Key: Eq + Hash,
+ F: FnMut(&I::Item) -> Key,
+ I: Iterator,
+{
+ DuplicatesBy::new(iter, private::ByFn(f))
+}
+
+/// An iterator adapter to filter out duplicate elements.
+///
+/// See [`.duplicates()`](crate::Itertools::duplicates) for more information.
+pub type Duplicates<I> = private::DuplicatesBy<I, <I as Iterator>::Item, private::ById>;
+
+/// Create a new `Duplicates` iterator.
+pub fn duplicates<I>(iter: I) -> Duplicates<I>
+where
+ I: Iterator,
+ I::Item: Eq + Hash,
+{
+ Duplicates::new(iter, private::ById)
+}
+
diff --git a/rust/hw/char/pl011/vendor/itertools/src/either_or_both.rs b/rust/hw/char/pl011/vendor/itertools/src/either_or_both.rs
new file mode 100644
index 0000000000..cf65fe7885
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/either_or_both.rs
@@ -0,0 +1,495 @@
+use core::ops::{Deref, DerefMut};
+
+use crate::EitherOrBoth::*;
+
+use either::Either;
+
+/// Value that either holds a single A or B, or both.
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+pub enum EitherOrBoth<A, B> {
+ /// Both values are present.
+ Both(A, B),
+ /// Only the left value of type `A` is present.
+ Left(A),
+ /// Only the right value of type `B` is present.
+ Right(B),
+}
+
+impl<A, B> EitherOrBoth<A, B> {
+ /// If `Left`, or `Both`, return true. Otherwise, return false.
+ pub fn has_left(&self) -> bool {
+ self.as_ref().left().is_some()
+ }
+
+ /// If `Right`, or `Both`, return true, otherwise, return false.
+ pub fn has_right(&self) -> bool {
+ self.as_ref().right().is_some()
+ }
+
+ /// If `Left`, return true. Otherwise, return false.
+ /// Exclusive version of [`has_left`](EitherOrBoth::has_left).
+ pub fn is_left(&self) -> bool {
+ match *self {
+ Left(_) => true,
+ _ => false,
+ }
+ }
+
+ /// If `Right`, return true. Otherwise, return false.
+ /// Exclusive version of [`has_right`](EitherOrBoth::has_right).
+ pub fn is_right(&self) -> bool {
+ match *self {
+ Right(_) => true,
+ _ => false,
+ }
+ }
+
+ /// If `Both`, return true. Otherwise, return false.
+ pub fn is_both(&self) -> bool {
+ self.as_ref().both().is_some()
+ }
+
+ /// If `Left`, or `Both`, return `Some` with the left value. Otherwise, return `None`.
+ pub fn left(self) -> Option<A> {
+ match self {
+ Left(left) | Both(left, _) => Some(left),
+ _ => None,
+ }
+ }
+
+ /// If `Right`, or `Both`, return `Some` with the right value. Otherwise, return `None`.
+ pub fn right(self) -> Option<B> {
+ match self {
+ Right(right) | Both(_, right) => Some(right),
+ _ => None,
+ }
+ }
+
+ /// If `Left`, return `Some` with the left value. If `Right` or `Both`, return `None`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// // On the `Left` variant.
+ /// # use itertools::{EitherOrBoth, EitherOrBoth::{Left, Right, Both}};
+ /// let x: EitherOrBoth<_, ()> = Left("bonjour");
+ /// assert_eq!(x.just_left(), Some("bonjour"));
+ ///
+ /// // On the `Right` variant.
+ /// let x: EitherOrBoth<(), _> = Right("hola");
+ /// assert_eq!(x.just_left(), None);
+ ///
+ /// // On the `Both` variant.
+ /// let x = Both("bonjour", "hola");
+ /// assert_eq!(x.just_left(), None);
+ /// ```
+ pub fn just_left(self) -> Option<A> {
+ match self {
+ Left(left) => Some(left),
+ _ => None,
+ }
+ }
+
+ /// If `Right`, return `Some` with the right value. If `Left` or `Both`, return `None`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// // On the `Left` variant.
+ /// # use itertools::{EitherOrBoth::{Left, Right, Both}, EitherOrBoth};
+ /// let x: EitherOrBoth<_, ()> = Left("auf wiedersehen");
+ /// assert_eq!(x.just_left(), Some("auf wiedersehen"));
+ ///
+ /// // On the `Right` variant.
+ /// let x: EitherOrBoth<(), _> = Right("adios");
+ /// assert_eq!(x.just_left(), None);
+ ///
+ /// // On the `Both` variant.
+ /// let x = Both("auf wiedersehen", "adios");
+ /// assert_eq!(x.just_left(), None);
+ /// ```
+ pub fn just_right(self) -> Option<B> {
+ match self {
+ Right(right) => Some(right),
+ _ => None,
+ }
+ }
+
+ /// If `Both`, return `Some` containing the left and right values. Otherwise, return `None`.
+ pub fn both(self) -> Option<(A, B)> {
+ match self {
+ Both(a, b) => Some((a, b)),
+ _ => None,
+ }
+ }
+
+ /// If `Left` or `Both`, return the left value. Otherwise, convert the right value and return it.
+ pub fn into_left(self) -> A
+ where
+ B: Into<A>,
+ {
+ match self {
+ Left(a) | Both(a, _) => a,
+ Right(b) => b.into(),
+ }
+ }
+
+ /// If `Right` or `Both`, return the right value. Otherwise, convert the left value and return it.
+ pub fn into_right(self) -> B
+ where
+ A: Into<B>,
+ {
+ match self {
+ Right(b) | Both(_, b) => b,
+ Left(a) => a.into(),
+ }
+ }
+
+ /// Converts from `&EitherOrBoth<A, B>` to `EitherOrBoth<&A, &B>`.
+ pub fn as_ref(&self) -> EitherOrBoth<&A, &B> {
+ match *self {
+ Left(ref left) => Left(left),
+ Right(ref right) => Right(right),
+ Both(ref left, ref right) => Both(left, right),
+ }
+ }
+
+ /// Converts from `&mut EitherOrBoth<A, B>` to `EitherOrBoth<&mut A, &mut B>`.
+ pub fn as_mut(&mut self) -> EitherOrBoth<&mut A, &mut B> {
+ match *self {
+ Left(ref mut left) => Left(left),
+ Right(ref mut right) => Right(right),
+ Both(ref mut left, ref mut right) => Both(left, right),
+ }
+ }
+
+ /// Converts from `&EitherOrBoth<A, B>` to `EitherOrBoth<&_, &_>` using the [`Deref`] trait.
+ pub fn as_deref(&self) -> EitherOrBoth<&A::Target, &B::Target>
+ where
+ A: Deref,
+ B: Deref,
+ {
+ match *self {
+ Left(ref left) => Left(left),
+ Right(ref right) => Right(right),
+ Both(ref left, ref right) => Both(left, right),
+ }
+ }
+
+ /// Converts from `&mut EitherOrBoth<A, B>` to `EitherOrBoth<&mut _, &mut _>` using the [`DerefMut`] trait.
+ pub fn as_deref_mut(&mut self) -> EitherOrBoth<&mut A::Target, &mut B::Target>
+ where
+ A: DerefMut,
+ B: DerefMut,
+ {
+ match *self {
+ Left(ref mut left) => Left(left),
+ Right(ref mut right) => Right(right),
+ Both(ref mut left, ref mut right) => Both(left, right),
+ }
+ }
+
+ /// Convert `EitherOrBoth<A, B>` to `EitherOrBoth<B, A>`.
+ pub fn flip(self) -> EitherOrBoth<B, A> {
+ match self {
+ Left(a) => Right(a),
+ Right(b) => Left(b),
+ Both(a, b) => Both(b, a),
+ }
+ }
+
+ /// Apply the function `f` on the value `a` in `Left(a)` or `Both(a, b)` variants. If it is
+ /// present rewrapping the result in `self`'s original variant.
+ pub fn map_left<F, M>(self, f: F) -> EitherOrBoth<M, B>
+ where
+ F: FnOnce(A) -> M,
+ {
+ match self {
+ Both(a, b) => Both(f(a), b),
+ Left(a) => Left(f(a)),
+ Right(b) => Right(b),
+ }
+ }
+
+ /// Apply the function `f` on the value `b` in `Right(b)` or `Both(a, b)` variants.
+ /// If it is present rewrapping the result in `self`'s original variant.
+ pub fn map_right<F, M>(self, f: F) -> EitherOrBoth<A, M>
+ where
+ F: FnOnce(B) -> M,
+ {
+ match self {
+ Left(a) => Left(a),
+ Right(b) => Right(f(b)),
+ Both(a, b) => Both(a, f(b)),
+ }
+ }
+
+ /// Apply the functions `f` and `g` on the value `a` and `b` respectively;
+ /// found in `Left(a)`, `Right(b)`, or `Both(a, b)` variants.
+ /// The Result is rewrapped `self`'s original variant.
+ pub fn map_any<F, L, G, R>(self, f: F, g: G) -> EitherOrBoth<L, R>
+ where
+ F: FnOnce(A) -> L,
+ G: FnOnce(B) -> R,
+ {
+ match self {
+ Left(a) => Left(f(a)),
+ Right(b) => Right(g(b)),
+ Both(a, b) => Both(f(a), g(b)),
+ }
+ }
+
+ /// Apply the function `f` on the value `a` in `Left(a)` or `Both(a, _)` variants if it is
+ /// present.
+ pub fn left_and_then<F, L>(self, f: F) -> EitherOrBoth<L, B>
+ where
+ F: FnOnce(A) -> EitherOrBoth<L, B>,
+ {
+ match self {
+ Left(a) | Both(a, _) => f(a),
+ Right(b) => Right(b),
+ }
+ }
+
+ /// Apply the function `f` on the value `b`
+ /// in `Right(b)` or `Both(_, b)` variants if it is present.
+ pub fn right_and_then<F, R>(self, f: F) -> EitherOrBoth<A, R>
+ where
+ F: FnOnce(B) -> EitherOrBoth<A, R>,
+ {
+ match self {
+ Left(a) => Left(a),
+ Right(b) | Both(_, b) => f(b),
+ }
+ }
+
+ /// Returns a tuple consisting of the `l` and `r` in `Both(l, r)`, if present.
+ /// Otherwise, returns the wrapped value for the present element, and the supplied
+ /// value for the other. The first (`l`) argument is used for a missing `Left`
+ /// value. The second (`r`) argument is used for a missing `Right` value.
+ ///
+ /// Arguments passed to `or` are eagerly evaluated; if you are passing
+ /// the result of a function call, it is recommended to use [`or_else`],
+ /// which is lazily evaluated.
+ ///
+ /// [`or_else`]: EitherOrBoth::or_else
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use itertools::EitherOrBoth;
+ /// assert_eq!(EitherOrBoth::Both("tree", 1).or("stone", 5), ("tree", 1));
+ /// assert_eq!(EitherOrBoth::Left("tree").or("stone", 5), ("tree", 5));
+ /// assert_eq!(EitherOrBoth::Right(1).or("stone", 5), ("stone", 1));
+ /// ```
+ pub fn or(self, l: A, r: B) -> (A, B) {
+ match self {
+ Left(inner_l) => (inner_l, r),
+ Right(inner_r) => (l, inner_r),
+ Both(inner_l, inner_r) => (inner_l, inner_r),
+ }
+ }
+
+ /// Returns a tuple consisting of the `l` and `r` in `Both(l, r)`, if present.
+ /// Otherwise, returns the wrapped value for the present element, and the [`default`](Default::default)
+ /// for the other.
+ pub fn or_default(self) -> (A, B)
+ where
+ A: Default,
+ B: Default,
+ {
+ match self {
+ EitherOrBoth::Left(l) => (l, B::default()),
+ EitherOrBoth::Right(r) => (A::default(), r),
+ EitherOrBoth::Both(l, r) => (l, r),
+ }
+ }
+
+ /// Returns a tuple consisting of the `l` and `r` in `Both(l, r)`, if present.
+ /// Otherwise, returns the wrapped value for the present element, and computes the
+ /// missing value with the supplied closure. The first argument (`l`) is used for a
+ /// missing `Left` value. The second argument (`r`) is used for a missing `Right` value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use itertools::EitherOrBoth;
+ /// let k = 10;
+ /// assert_eq!(EitherOrBoth::Both("tree", 1).or_else(|| "stone", || 2 * k), ("tree", 1));
+ /// assert_eq!(EitherOrBoth::Left("tree").or_else(|| "stone", || 2 * k), ("tree", 20));
+ /// assert_eq!(EitherOrBoth::Right(1).or_else(|| "stone", || 2 * k), ("stone", 1));
+ /// ```
+ pub fn or_else<L: FnOnce() -> A, R: FnOnce() -> B>(self, l: L, r: R) -> (A, B) {
+ match self {
+ Left(inner_l) => (inner_l, r()),
+ Right(inner_r) => (l(), inner_r),
+ Both(inner_l, inner_r) => (inner_l, inner_r),
+ }
+ }
+
+ /// Returns a mutable reference to the left value. If the left value is not present,
+ /// it is replaced with `val`.
+ pub fn left_or_insert(&mut self, val: A) -> &mut A {
+ self.left_or_insert_with(|| val)
+ }
+
+ /// Returns a mutable reference to the right value. If the right value is not present,
+ /// it is replaced with `val`.
+ pub fn right_or_insert(&mut self, val: B) -> &mut B {
+ self.right_or_insert_with(|| val)
+ }
+
+ /// If the left value is not present, replace it the value computed by the closure `f`.
+ /// Returns a mutable reference to the now-present left value.
+ pub fn left_or_insert_with<F>(&mut self, f: F) -> &mut A
+ where
+ F: FnOnce() -> A,
+ {
+ match self {
+ Left(left) | Both(left, _) => left,
+ Right(_) => self.insert_left(f()),
+ }
+ }
+
+ /// If the right value is not present, replace it the value computed by the closure `f`.
+ /// Returns a mutable reference to the now-present right value.
+ pub fn right_or_insert_with<F>(&mut self, f: F) -> &mut B
+ where
+ F: FnOnce() -> B,
+ {
+ match self {
+ Right(right) | Both(_, right) => right,
+ Left(_) => self.insert_right(f()),
+ }
+ }
+
+ /// Sets the `left` value of this instance, and returns a mutable reference to it.
+ /// Does not affect the `right` value.
+ ///
+ /// # Examples
+ /// ```
+ /// # use itertools::{EitherOrBoth, EitherOrBoth::{Left, Right, Both}};
+ ///
+ /// // Overwriting a pre-existing value.
+ /// let mut either: EitherOrBoth<_, ()> = Left(0_u32);
+ /// assert_eq!(*either.insert_left(69), 69);
+ ///
+ /// // Inserting a second value.
+ /// let mut either = Right("no");
+ /// assert_eq!(*either.insert_left("yes"), "yes");
+ /// assert_eq!(either, Both("yes", "no"));
+ /// ```
+ pub fn insert_left(&mut self, val: A) -> &mut A {
+ match self {
+ Left(left) | Both(left, _) => {
+ *left = val;
+ left
+ }
+ Right(right) => {
+ // This is like a map in place operation. We move out of the reference,
+ // change the value, and then move back into the reference.
+ unsafe {
+ // SAFETY: We know this pointer is valid for reading since we got it from a reference.
+ let right = std::ptr::read(right as *mut _);
+ // SAFETY: Again, we know the pointer is valid since we got it from a reference.
+ std::ptr::write(self as *mut _, Both(val, right));
+ }
+
+ if let Both(left, _) = self {
+ left
+ } else {
+ // SAFETY: The above pattern will always match, since we just
+ // set `self` equal to `Both`.
+ unsafe { std::hint::unreachable_unchecked() }
+ }
+ }
+ }
+ }
+
+ /// Sets the `right` value of this instance, and returns a mutable reference to it.
+ /// Does not affect the `left` value.
+ ///
+ /// # Examples
+ /// ```
+ /// # use itertools::{EitherOrBoth, EitherOrBoth::{Left, Both}};
+ /// // Overwriting a pre-existing value.
+ /// let mut either: EitherOrBoth<_, ()> = Left(0_u32);
+ /// assert_eq!(*either.insert_left(69), 69);
+ ///
+ /// // Inserting a second value.
+ /// let mut either = Left("what's");
+ /// assert_eq!(*either.insert_right(9 + 10), 21 - 2);
+ /// assert_eq!(either, Both("what's", 9+10));
+ /// ```
+ pub fn insert_right(&mut self, val: B) -> &mut B {
+ match self {
+ Right(right) | Both(_, right) => {
+ *right = val;
+ right
+ }
+ Left(left) => {
+ // This is like a map in place operation. We move out of the reference,
+ // change the value, and then move back into the reference.
+ unsafe {
+ // SAFETY: We know this pointer is valid for reading since we got it from a reference.
+ let left = std::ptr::read(left as *mut _);
+ // SAFETY: Again, we know the pointer is valid since we got it from a reference.
+ std::ptr::write(self as *mut _, Both(left, val));
+ }
+ if let Both(_, right) = self {
+ right
+ } else {
+ // SAFETY: The above pattern will always match, since we just
+ // set `self` equal to `Both`.
+ unsafe { std::hint::unreachable_unchecked() }
+ }
+ }
+ }
+ }
+
+ /// Set `self` to `Both(..)`, containing the specified left and right values,
+ /// and returns a mutable reference to those values.
+ pub fn insert_both(&mut self, left: A, right: B) -> (&mut A, &mut B) {
+ *self = Both(left, right);
+ if let Both(left, right) = self {
+ (left, right)
+ } else {
+ // SAFETY: The above pattern will always match, since we just
+ // set `self` equal to `Both`.
+ unsafe { std::hint::unreachable_unchecked() }
+ }
+ }
+}
+
+impl<T> EitherOrBoth<T, T> {
+ /// Return either value of left, right, or apply a function `f` to both values if both are present.
+ /// The input function has to return the same type as both Right and Left carry.
+ ///
+ /// # Examples
+ /// ```
+ /// # use itertools::EitherOrBoth;
+ /// assert_eq!(EitherOrBoth::Both(3, 7).reduce(u32::max), 7);
+ /// assert_eq!(EitherOrBoth::Left(3).reduce(u32::max), 3);
+ /// assert_eq!(EitherOrBoth::Right(7).reduce(u32::max), 7);
+ /// ```
+ pub fn reduce<F>(self, f: F) -> T
+ where
+ F: FnOnce(T, T) -> T,
+ {
+ match self {
+ Left(a) => a,
+ Right(b) => b,
+ Both(a, b) => f(a, b),
+ }
+ }
+}
+
+impl<A, B> Into<Option<Either<A, B>>> for EitherOrBoth<A, B> {
+ fn into(self) -> Option<Either<A, B>> {
+ match self {
+ EitherOrBoth::Left(l) => Some(Either::Left(l)),
+ EitherOrBoth::Right(r) => Some(Either::Right(r)),
+ _ => None,
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/exactly_one_err.rs b/rust/hw/char/pl011/vendor/itertools/src/exactly_one_err.rs
new file mode 100644
index 0000000000..c54ae77ca9
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/exactly_one_err.rs
@@ -0,0 +1,110 @@
+#[cfg(feature = "use_std")]
+use std::error::Error;
+use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
+
+use std::iter::ExactSizeIterator;
+
+use either::Either;
+
+use crate::size_hint;
+
+/// Iterator returned for the error case of `IterTools::exactly_one()`
+/// This iterator yields exactly the same elements as the input iterator.
+///
+/// During the execution of `exactly_one` the iterator must be mutated. This wrapper
+/// effectively "restores" the state of the input iterator when it's handed back.
+///
+/// This is very similar to `PutBackN` except this iterator only supports 0-2 elements and does not
+/// use a `Vec`.
+#[derive(Clone)]
+pub struct ExactlyOneError<I>
+where
+ I: Iterator,
+{
+ first_two: Option<Either<[I::Item; 2], I::Item>>,
+ inner: I,
+}
+
+impl<I> ExactlyOneError<I>
+where
+ I: Iterator,
+{
+ /// Creates a new `ExactlyOneErr` iterator.
+ pub(crate) fn new(first_two: Option<Either<[I::Item; 2], I::Item>>, inner: I) -> Self {
+ Self { first_two, inner }
+ }
+
+ fn additional_len(&self) -> usize {
+ match self.first_two {
+ Some(Either::Left(_)) => 2,
+ Some(Either::Right(_)) => 1,
+ None => 0,
+ }
+ }
+}
+
+impl<I> Iterator for ExactlyOneError<I>
+where
+ I: Iterator,
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.first_two.take() {
+ Some(Either::Left([first, second])) => {
+ self.first_two = Some(Either::Right(second));
+ Some(first)
+ },
+ Some(Either::Right(second)) => {
+ Some(second)
+ }
+ None => {
+ self.inner.next()
+ }
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ size_hint::add_scalar(self.inner.size_hint(), self.additional_len())
+ }
+}
+
+
+impl<I> ExactSizeIterator for ExactlyOneError<I> where I: ExactSizeIterator {}
+
+impl<I> Display for ExactlyOneError<I>
+ where I: Iterator,
+{
+ fn fmt(&self, f: &mut Formatter) -> FmtResult {
+ let additional = self.additional_len();
+ if additional > 0 {
+ write!(f, "got at least 2 elements when exactly one was expected")
+ } else {
+ write!(f, "got zero elements when exactly one was expected")
+ }
+ }
+}
+
+impl<I> Debug for ExactlyOneError<I>
+ where I: Iterator + Debug,
+ I::Item: Debug,
+{
+ fn fmt(&self, f: &mut Formatter) -> FmtResult {
+ match &self.first_two {
+ Some(Either::Left([first, second])) => {
+ write!(f, "ExactlyOneError[First: {:?}, Second: {:?}, RemainingIter: {:?}]", first, second, self.inner)
+ },
+ Some(Either::Right(second)) => {
+ write!(f, "ExactlyOneError[Second: {:?}, RemainingIter: {:?}]", second, self.inner)
+ }
+ None => {
+ write!(f, "ExactlyOneError[RemainingIter: {:?}]", self.inner)
+ }
+ }
+ }
+}
+
+#[cfg(feature = "use_std")]
+impl<I> Error for ExactlyOneError<I> where I: Iterator + Debug, I::Item: Debug, {}
+
+
diff --git a/rust/hw/char/pl011/vendor/itertools/src/extrema_set.rs b/rust/hw/char/pl011/vendor/itertools/src/extrema_set.rs
new file mode 100644
index 0000000000..ae128364c5
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/extrema_set.rs
@@ -0,0 +1,48 @@
+use std::cmp::Ordering;
+
+/// Implementation guts for `min_set`, `min_set_by`, and `min_set_by_key`.
+pub fn min_set_impl<I, K, F, Compare>(
+ mut it: I,
+ mut key_for: F,
+ mut compare: Compare,
+) -> Vec<I::Item>
+where
+ I: Iterator,
+ F: FnMut(&I::Item) -> K,
+ Compare: FnMut(&I::Item, &I::Item, &K, &K) -> Ordering,
+{
+ match it.next() {
+ None => Vec::new(),
+ Some(element) => {
+ let mut current_key = key_for(&element);
+ let mut result = vec![element];
+ it.for_each(|element| {
+ let key = key_for(&element);
+ match compare(&element, &result[0], &key, ¤t_key) {
+ Ordering::Less => {
+ result.clear();
+ result.push(element);
+ current_key = key;
+ }
+ Ordering::Equal => {
+ result.push(element);
+ }
+ Ordering::Greater => {}
+ }
+ });
+ result
+ }
+ }
+}
+
+/// Implementation guts for `ax_set`, `max_set_by`, and `max_set_by_key`.
+pub fn max_set_impl<I, K, F, Compare>(it: I, key_for: F, mut compare: Compare) -> Vec<I::Item>
+where
+ I: Iterator,
+ F: FnMut(&I::Item) -> K,
+ Compare: FnMut(&I::Item, &I::Item, &K, &K) -> Ordering,
+{
+ min_set_impl(it, key_for, |it1, it2, key1, key2| {
+ compare(it2, it1, key2, key1)
+ })
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/flatten_ok.rs b/rust/hw/char/pl011/vendor/itertools/src/flatten_ok.rs
new file mode 100644
index 0000000000..21ae1f7223
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/flatten_ok.rs
@@ -0,0 +1,165 @@
+use crate::size_hint;
+use std::{
+ fmt,
+ iter::{DoubleEndedIterator, FusedIterator},
+};
+
+pub fn flatten_ok<I, T, E>(iter: I) -> FlattenOk<I, T, E>
+where
+ I: Iterator<Item = Result<T, E>>,
+ T: IntoIterator,
+{
+ FlattenOk {
+ iter,
+ inner_front: None,
+ inner_back: None,
+ }
+}
+
+/// An iterator adaptor that flattens `Result::Ok` values and
+/// allows `Result::Err` values through unchanged.
+///
+/// See [`.flatten_ok()`](crate::Itertools::flatten_ok) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct FlattenOk<I, T, E>
+where
+ I: Iterator<Item = Result<T, E>>,
+ T: IntoIterator,
+{
+ iter: I,
+ inner_front: Option<T::IntoIter>,
+ inner_back: Option<T::IntoIter>,
+}
+
+impl<I, T, E> Iterator for FlattenOk<I, T, E>
+where
+ I: Iterator<Item = Result<T, E>>,
+ T: IntoIterator,
+{
+ type Item = Result<T::Item, E>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ loop {
+ // Handle the front inner iterator.
+ if let Some(inner) = &mut self.inner_front {
+ if let Some(item) = inner.next() {
+ return Some(Ok(item));
+ }
+
+ // This is necessary for the iterator to implement `FusedIterator`
+ // with only the original iterator being fused.
+ self.inner_front = None;
+ }
+
+ match self.iter.next() {
+ Some(Ok(ok)) => self.inner_front = Some(ok.into_iter()),
+ Some(Err(e)) => return Some(Err(e)),
+ None => {
+ // Handle the back inner iterator.
+ if let Some(inner) = &mut self.inner_back {
+ if let Some(item) = inner.next() {
+ return Some(Ok(item));
+ }
+
+ // This is necessary for the iterator to implement `FusedIterator`
+ // with only the original iterator being fused.
+ self.inner_back = None;
+ } else {
+ return None;
+ }
+ }
+ }
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let inner_hint = |inner: &Option<T::IntoIter>| {
+ inner
+ .as_ref()
+ .map(Iterator::size_hint)
+ .unwrap_or((0, Some(0)))
+ };
+ let inner_front = inner_hint(&self.inner_front);
+ let inner_back = inner_hint(&self.inner_back);
+ // The outer iterator `Ok` case could be (0, None) as we don't know its size_hint yet.
+ let outer = match self.iter.size_hint() {
+ (0, Some(0)) => (0, Some(0)),
+ _ => (0, None),
+ };
+
+ size_hint::add(size_hint::add(inner_front, inner_back), outer)
+ }
+}
+
+impl<I, T, E> DoubleEndedIterator for FlattenOk<I, T, E>
+where
+ I: DoubleEndedIterator<Item = Result<T, E>>,
+ T: IntoIterator,
+ T::IntoIter: DoubleEndedIterator,
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ loop {
+ // Handle the back inner iterator.
+ if let Some(inner) = &mut self.inner_back {
+ if let Some(item) = inner.next_back() {
+ return Some(Ok(item));
+ }
+
+ // This is necessary for the iterator to implement `FusedIterator`
+ // with only the original iterator being fused.
+ self.inner_back = None;
+ }
+
+ match self.iter.next_back() {
+ Some(Ok(ok)) => self.inner_back = Some(ok.into_iter()),
+ Some(Err(e)) => return Some(Err(e)),
+ None => {
+ // Handle the front inner iterator.
+ if let Some(inner) = &mut self.inner_front {
+ if let Some(item) = inner.next_back() {
+ return Some(Ok(item));
+ }
+
+ // This is necessary for the iterator to implement `FusedIterator`
+ // with only the original iterator being fused.
+ self.inner_front = None;
+ } else {
+ return None;
+ }
+ }
+ }
+ }
+ }
+}
+
+impl<I, T, E> Clone for FlattenOk<I, T, E>
+where
+ I: Iterator<Item = Result<T, E>> + Clone,
+ T: IntoIterator,
+ T::IntoIter: Clone,
+{
+ clone_fields!(iter, inner_front, inner_back);
+}
+
+impl<I, T, E> fmt::Debug for FlattenOk<I, T, E>
+where
+ I: Iterator<Item = Result<T, E>> + fmt::Debug,
+ T: IntoIterator,
+ T::IntoIter: fmt::Debug,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("FlattenOk")
+ .field("iter", &self.iter)
+ .field("inner_front", &self.inner_front)
+ .field("inner_back", &self.inner_back)
+ .finish()
+ }
+}
+
+/// Only the iterator being flattened needs to implement [`FusedIterator`].
+impl<I, T, E> FusedIterator for FlattenOk<I, T, E>
+where
+ I: FusedIterator<Item = Result<T, E>>,
+ T: IntoIterator,
+{
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/format.rs b/rust/hw/char/pl011/vendor/itertools/src/format.rs
new file mode 100644
index 0000000000..c4cb65dcb2
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/format.rs
@@ -0,0 +1,168 @@
+use std::cell::Cell;
+use std::fmt;
+
+/// Format all iterator elements lazily, separated by `sep`.
+///
+/// The format value can only be formatted once, after that the iterator is
+/// exhausted.
+///
+/// See [`.format_with()`](crate::Itertools::format_with) for more information.
+pub struct FormatWith<'a, I, F> {
+ sep: &'a str,
+ /// FormatWith uses interior mutability because Display::fmt takes &self.
+ inner: Cell<Option<(I, F)>>,
+}
+
+/// Format all iterator elements lazily, separated by `sep`.
+///
+/// The format value can only be formatted once, after that the iterator is
+/// exhausted.
+///
+/// See [`.format()`](crate::Itertools::format)
+/// for more information.
+pub struct Format<'a, I> {
+ sep: &'a str,
+ /// Format uses interior mutability because Display::fmt takes &self.
+ inner: Cell<Option<I>>,
+}
+
+pub fn new_format<I, F>(iter: I, separator: &str, f: F) -> FormatWith<'_, I, F>
+where
+ I: Iterator,
+ F: FnMut(I::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result,
+{
+ FormatWith {
+ sep: separator,
+ inner: Cell::new(Some((iter, f))),
+ }
+}
+
+pub fn new_format_default<I>(iter: I, separator: &str) -> Format<'_, I>
+where
+ I: Iterator,
+{
+ Format {
+ sep: separator,
+ inner: Cell::new(Some(iter)),
+ }
+}
+
+impl<'a, I, F> fmt::Display for FormatWith<'a, I, F>
+where
+ I: Iterator,
+ F: FnMut(I::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result,
+{
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let (mut iter, mut format) = match self.inner.take() {
+ Some(t) => t,
+ None => panic!("FormatWith: was already formatted once"),
+ };
+
+ if let Some(fst) = iter.next() {
+ format(fst, &mut |disp: &dyn fmt::Display| disp.fmt(f))?;
+ iter.try_for_each(|elt| {
+ if !self.sep.is_empty() {
+ f.write_str(self.sep)?;
+ }
+ format(elt, &mut |disp: &dyn fmt::Display| disp.fmt(f))
+ })?;
+ }
+ Ok(())
+ }
+}
+
+impl<'a, I> Format<'a, I>
+where
+ I: Iterator,
+{
+ fn format(
+ &self,
+ f: &mut fmt::Formatter,
+ cb: fn(&I::Item, &mut fmt::Formatter) -> fmt::Result,
+ ) -> fmt::Result {
+ let mut iter = match self.inner.take() {
+ Some(t) => t,
+ None => panic!("Format: was already formatted once"),
+ };
+
+ if let Some(fst) = iter.next() {
+ cb(&fst, f)?;
+ iter.try_for_each(|elt| {
+ if !self.sep.is_empty() {
+ f.write_str(self.sep)?;
+ }
+ cb(&elt, f)
+ })?;
+ }
+ Ok(())
+ }
+}
+
+macro_rules! impl_format {
+ ($($fmt_trait:ident)*) => {
+ $(
+ impl<'a, I> fmt::$fmt_trait for Format<'a, I>
+ where I: Iterator,
+ I::Item: fmt::$fmt_trait,
+ {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.format(f, fmt::$fmt_trait::fmt)
+ }
+ }
+ )*
+ }
+}
+
+impl_format! {Display Debug UpperExp LowerExp UpperHex LowerHex Octal Binary Pointer}
+
+impl<'a, I, F> Clone for FormatWith<'a, I, F>
+where
+ (I, F): Clone,
+{
+ fn clone(&self) -> Self {
+ struct PutBackOnDrop<'r, 'a, I, F> {
+ into: &'r FormatWith<'a, I, F>,
+ inner: Option<(I, F)>,
+ }
+ // This ensures we preserve the state of the original `FormatWith` if `Clone` panics
+ impl<'r, 'a, I, F> Drop for PutBackOnDrop<'r, 'a, I, F> {
+ fn drop(&mut self) {
+ self.into.inner.set(self.inner.take())
+ }
+ }
+ let pbod = PutBackOnDrop {
+ inner: self.inner.take(),
+ into: self,
+ };
+ Self {
+ inner: Cell::new(pbod.inner.clone()),
+ sep: self.sep,
+ }
+ }
+}
+
+impl<'a, I> Clone for Format<'a, I>
+where
+ I: Clone,
+{
+ fn clone(&self) -> Self {
+ struct PutBackOnDrop<'r, 'a, I> {
+ into: &'r Format<'a, I>,
+ inner: Option<I>,
+ }
+ // This ensures we preserve the state of the original `FormatWith` if `Clone` panics
+ impl<'r, 'a, I> Drop for PutBackOnDrop<'r, 'a, I> {
+ fn drop(&mut self) {
+ self.into.inner.set(self.inner.take())
+ }
+ }
+ let pbod = PutBackOnDrop {
+ inner: self.inner.take(),
+ into: self,
+ };
+ Self {
+ inner: Cell::new(pbod.inner.clone()),
+ sep: self.sep,
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/free.rs b/rust/hw/char/pl011/vendor/itertools/src/free.rs
new file mode 100644
index 0000000000..19e3e28694
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/free.rs
@@ -0,0 +1,286 @@
+//! Free functions that create iterator adaptors or call iterator methods.
+//!
+//! The benefit of free functions is that they accept any [`IntoIterator`] as
+//! argument, so the resulting code may be easier to read.
+
+#[cfg(feature = "use_alloc")]
+use std::fmt::Display;
+use std::iter::{self, Zip};
+#[cfg(feature = "use_alloc")]
+type VecIntoIter<T> = alloc::vec::IntoIter<T>;
+
+#[cfg(feature = "use_alloc")]
+use alloc::{
+ string::String,
+};
+
+use crate::Itertools;
+use crate::intersperse::{Intersperse, IntersperseWith};
+
+pub use crate::adaptors::{
+ interleave,
+ merge,
+ put_back,
+};
+#[cfg(feature = "use_alloc")]
+pub use crate::put_back_n_impl::put_back_n;
+#[cfg(feature = "use_alloc")]
+pub use crate::multipeek_impl::multipeek;
+#[cfg(feature = "use_alloc")]
+pub use crate::peek_nth::peek_nth;
+#[cfg(feature = "use_alloc")]
+pub use crate::kmerge_impl::kmerge;
+pub use crate::zip_eq_impl::zip_eq;
+pub use crate::merge_join::merge_join_by;
+#[cfg(feature = "use_alloc")]
+pub use crate::rciter_impl::rciter;
+
+/// Iterate `iterable` with a particular value inserted between each element.
+///
+/// [`IntoIterator`] enabled version of [`Iterator::intersperse`].
+///
+/// ```
+/// use itertools::intersperse;
+///
+/// itertools::assert_equal(intersperse((0..3), 8), vec![0, 8, 1, 8, 2]);
+/// ```
+pub fn intersperse<I>(iterable: I, element: I::Item) -> Intersperse<I::IntoIter>
+ where I: IntoIterator,
+ <I as IntoIterator>::Item: Clone
+{
+ Itertools::intersperse(iterable.into_iter(), element)
+}
+
+/// Iterate `iterable` with a particular value created by a function inserted
+/// between each element.
+///
+/// [`IntoIterator`] enabled version of [`Iterator::intersperse_with`].
+///
+/// ```
+/// use itertools::intersperse_with;
+///
+/// let mut i = 10;
+/// itertools::assert_equal(intersperse_with((0..3), || { i -= 1; i }), vec![0, 9, 1, 8, 2]);
+/// assert_eq!(i, 8);
+/// ```
+pub fn intersperse_with<I, F>(iterable: I, element: F) -> IntersperseWith<I::IntoIter, F>
+ where I: IntoIterator,
+ F: FnMut() -> I::Item
+{
+ Itertools::intersperse_with(iterable.into_iter(), element)
+}
+
+/// Iterate `iterable` with a running index.
+///
+/// [`IntoIterator`] enabled version of [`Iterator::enumerate`].
+///
+/// ```
+/// use itertools::enumerate;
+///
+/// for (i, elt) in enumerate(&[1, 2, 3]) {
+/// /* loop body */
+/// }
+/// ```
+pub fn enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter>
+ where I: IntoIterator
+{
+ iterable.into_iter().enumerate()
+}
+
+/// Iterate `iterable` in reverse.
+///
+/// [`IntoIterator`] enabled version of [`Iterator::rev`].
+///
+/// ```
+/// use itertools::rev;
+///
+/// for elt in rev(&[1, 2, 3]) {
+/// /* loop body */
+/// }
+/// ```
+pub fn rev<I>(iterable: I) -> iter::Rev<I::IntoIter>
+ where I: IntoIterator,
+ I::IntoIter: DoubleEndedIterator
+{
+ iterable.into_iter().rev()
+}
+
+/// Converts the arguments to iterators and zips them.
+///
+/// [`IntoIterator`] enabled version of [`Iterator::zip`].
+///
+/// ## Example
+///
+/// ```
+/// use itertools::zip;
+///
+/// let mut result: Vec<(i32, char)> = Vec::new();
+///
+/// for (a, b) in zip(&[1, 2, 3, 4, 5], &['a', 'b', 'c']) {
+/// result.push((*a, *b));
+/// }
+/// assert_eq!(result, vec![(1, 'a'),(2, 'b'),(3, 'c')]);
+/// ```
+#[deprecated(note="Use [std::iter::zip](https://doc.rust-lang.org/std/iter/fn.zip.html) instead", since="0.10.4")]
+pub fn zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter>
+ where I: IntoIterator,
+ J: IntoIterator
+{
+ i.into_iter().zip(j)
+}
+
+
+/// Takes two iterables and creates a new iterator over both in sequence.
+///
+/// [`IntoIterator`] enabled version of [`Iterator::chain`].
+///
+/// ## Example
+/// ```
+/// use itertools::chain;
+///
+/// let mut result:Vec<i32> = Vec::new();
+///
+/// for element in chain(&[1, 2, 3], &[4]) {
+/// result.push(*element);
+/// }
+/// assert_eq!(result, vec![1, 2, 3, 4]);
+/// ```
+pub fn chain<I, J>(i: I, j: J) -> iter::Chain<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
+ where I: IntoIterator,
+ J: IntoIterator<Item = I::Item>
+{
+ i.into_iter().chain(j)
+}
+
+/// Create an iterator that clones each element from &T to T
+///
+/// [`IntoIterator`] enabled version of [`Iterator::cloned`].
+///
+/// ```
+/// use itertools::cloned;
+///
+/// assert_eq!(cloned(b"abc").next(), Some(b'a'));
+/// ```
+pub fn cloned<'a, I, T: 'a>(iterable: I) -> iter::Cloned<I::IntoIter>
+ where I: IntoIterator<Item=&'a T>,
+ T: Clone,
+{
+ iterable.into_iter().cloned()
+}
+
+/// Perform a fold operation over the iterable.
+///
+/// [`IntoIterator`] enabled version of [`Iterator::fold`].
+///
+/// ```
+/// use itertools::fold;
+///
+/// assert_eq!(fold(&[1., 2., 3.], 0., |a, &b| f32::max(a, b)), 3.);
+/// ```
+pub fn fold<I, B, F>(iterable: I, init: B, f: F) -> B
+ where I: IntoIterator,
+ F: FnMut(B, I::Item) -> B
+{
+ iterable.into_iter().fold(init, f)
+}
+
+/// Test whether the predicate holds for all elements in the iterable.
+///
+/// [`IntoIterator`] enabled version of [`Iterator::all`].
+///
+/// ```
+/// use itertools::all;
+///
+/// assert!(all(&[1, 2, 3], |elt| *elt > 0));
+/// ```
+pub fn all<I, F>(iterable: I, f: F) -> bool
+ where I: IntoIterator,
+ F: FnMut(I::Item) -> bool
+{
+ iterable.into_iter().all(f)
+}
+
+/// Test whether the predicate holds for any elements in the iterable.
+///
+/// [`IntoIterator`] enabled version of [`Iterator::any`].
+///
+/// ```
+/// use itertools::any;
+///
+/// assert!(any(&[0, -1, 2], |elt| *elt > 0));
+/// ```
+pub fn any<I, F>(iterable: I, f: F) -> bool
+ where I: IntoIterator,
+ F: FnMut(I::Item) -> bool
+{
+ iterable.into_iter().any(f)
+}
+
+/// Return the maximum value of the iterable.
+///
+/// [`IntoIterator`] enabled version of [`Iterator::max`].
+///
+/// ```
+/// use itertools::max;
+///
+/// assert_eq!(max(0..10), Some(9));
+/// ```
+pub fn max<I>(iterable: I) -> Option<I::Item>
+ where I: IntoIterator,
+ I::Item: Ord
+{
+ iterable.into_iter().max()
+}
+
+/// Return the minimum value of the iterable.
+///
+/// [`IntoIterator`] enabled version of [`Iterator::min`].
+///
+/// ```
+/// use itertools::min;
+///
+/// assert_eq!(min(0..10), Some(0));
+/// ```
+pub fn min<I>(iterable: I) -> Option<I::Item>
+ where I: IntoIterator,
+ I::Item: Ord
+{
+ iterable.into_iter().min()
+}
+
+
+/// Combine all iterator elements into one String, separated by `sep`.
+///
+/// [`IntoIterator`] enabled version of [`Itertools::join`].
+///
+/// ```
+/// use itertools::join;
+///
+/// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
+/// ```
+#[cfg(feature = "use_alloc")]
+pub fn join<I>(iterable: I, sep: &str) -> String
+ where I: IntoIterator,
+ I::Item: Display
+{
+ iterable.into_iter().join(sep)
+}
+
+/// Sort all iterator elements into a new iterator in ascending order.
+///
+/// [`IntoIterator`] enabled version of [`Itertools::sorted`].
+///
+/// ```
+/// use itertools::sorted;
+/// use itertools::assert_equal;
+///
+/// assert_equal(sorted("rust".chars()), "rstu".chars());
+/// ```
+#[cfg(feature = "use_alloc")]
+pub fn sorted<I>(iterable: I) -> VecIntoIter<I::Item>
+ where I: IntoIterator,
+ I::Item: Ord
+{
+ iterable.into_iter().sorted()
+}
+
diff --git a/rust/hw/char/pl011/vendor/itertools/src/group_map.rs b/rust/hw/char/pl011/vendor/itertools/src/group_map.rs
new file mode 100644
index 0000000000..a2d0ebb2ab
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/group_map.rs
@@ -0,0 +1,32 @@
+#![cfg(feature = "use_std")]
+
+use std::collections::HashMap;
+use std::hash::Hash;
+use std::iter::Iterator;
+
+/// Return a `HashMap` of keys mapped to a list of their corresponding values.
+///
+/// See [`.into_group_map()`](crate::Itertools::into_group_map)
+/// for more information.
+pub fn into_group_map<I, K, V>(iter: I) -> HashMap<K, Vec<V>>
+ where I: Iterator<Item=(K, V)>,
+ K: Hash + Eq,
+{
+ let mut lookup = HashMap::new();
+
+ iter.for_each(|(key, val)| {
+ lookup.entry(key).or_insert_with(Vec::new).push(val);
+ });
+
+ lookup
+}
+
+pub fn into_group_map_by<I, K, V>(iter: I, f: impl Fn(&V) -> K) -> HashMap<K, Vec<V>>
+ where
+ I: Iterator<Item=V>,
+ K: Hash + Eq,
+{
+ into_group_map(
+ iter.map(|v| (f(&v), v))
+ )
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/groupbylazy.rs b/rust/hw/char/pl011/vendor/itertools/src/groupbylazy.rs
new file mode 100644
index 0000000000..80c6f09f32
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/groupbylazy.rs
@@ -0,0 +1,579 @@
+use std::cell::{Cell, RefCell};
+use alloc::vec::{self, Vec};
+
+/// A trait to unify `FnMut` for `GroupBy` with the chunk key in `IntoChunks`
+trait KeyFunction<A> {
+ type Key;
+ fn call_mut(&mut self, arg: A) -> Self::Key;
+}
+
+impl<A, K, F: ?Sized> KeyFunction<A> for F
+ where F: FnMut(A) -> K
+{
+ type Key = K;
+ #[inline]
+ fn call_mut(&mut self, arg: A) -> Self::Key {
+ (*self)(arg)
+ }
+}
+
+
+/// `ChunkIndex` acts like the grouping key function for `IntoChunks`
+#[derive(Debug, Clone)]
+struct ChunkIndex {
+ size: usize,
+ index: usize,
+ key: usize,
+}
+
+impl ChunkIndex {
+ #[inline(always)]
+ fn new(size: usize) -> Self {
+ ChunkIndex {
+ size,
+ index: 0,
+ key: 0,
+ }
+ }
+}
+
+impl<A> KeyFunction<A> for ChunkIndex {
+ type Key = usize;
+ #[inline(always)]
+ fn call_mut(&mut self, _arg: A) -> Self::Key {
+ if self.index == self.size {
+ self.key += 1;
+ self.index = 0;
+ }
+ self.index += 1;
+ self.key
+ }
+}
+
+#[derive(Clone)]
+struct GroupInner<K, I, F>
+ where I: Iterator
+{
+ key: F,
+ iter: I,
+ current_key: Option<K>,
+ current_elt: Option<I::Item>,
+ /// flag set if iterator is exhausted
+ done: bool,
+ /// Index of group we are currently buffering or visiting
+ top_group: usize,
+ /// Least index for which we still have elements buffered
+ oldest_buffered_group: usize,
+ /// Group index for `buffer[0]` -- the slots
+ /// bottom_group..oldest_buffered_group are unused and will be erased when
+ /// that range is large enough.
+ bottom_group: usize,
+ /// Buffered groups, from `bottom_group` (index 0) to `top_group`.
+ buffer: Vec<vec::IntoIter<I::Item>>,
+ /// index of last group iter that was dropped, usize::MAX == none
+ dropped_group: usize,
+}
+
+impl<K, I, F> GroupInner<K, I, F>
+ where I: Iterator,
+ F: for<'a> KeyFunction<&'a I::Item, Key=K>,
+ K: PartialEq,
+{
+ /// `client`: Index of group that requests next element
+ #[inline(always)]
+ fn step(&mut self, client: usize) -> Option<I::Item> {
+ /*
+ println!("client={}, bottom_group={}, oldest_buffered_group={}, top_group={}, buffers=[{}]",
+ client, self.bottom_group, self.oldest_buffered_group,
+ self.top_group,
+ self.buffer.iter().map(|elt| elt.len()).format(", "));
+ */
+ if client < self.oldest_buffered_group {
+ None
+ } else if client < self.top_group ||
+ (client == self.top_group &&
+ self.buffer.len() > self.top_group - self.bottom_group)
+ {
+ self.lookup_buffer(client)
+ } else if self.done {
+ None
+ } else if self.top_group == client {
+ self.step_current()
+ } else {
+ self.step_buffering(client)
+ }
+ }
+
+ #[inline(never)]
+ fn lookup_buffer(&mut self, client: usize) -> Option<I::Item> {
+ // if `bufidx` doesn't exist in self.buffer, it might be empty
+ let bufidx = client - self.bottom_group;
+ if client < self.oldest_buffered_group {
+ return None;
+ }
+ let elt = self.buffer.get_mut(bufidx).and_then(|queue| queue.next());
+ if elt.is_none() && client == self.oldest_buffered_group {
+ // FIXME: VecDeque is unfortunately not zero allocation when empty,
+ // so we do this job manually.
+ // `bottom_group..oldest_buffered_group` is unused, and if it's large enough, erase it.
+ self.oldest_buffered_group += 1;
+ // skip forward further empty queues too
+ while self.buffer.get(self.oldest_buffered_group - self.bottom_group)
+ .map_or(false, |buf| buf.len() == 0)
+ {
+ self.oldest_buffered_group += 1;
+ }
+
+ let nclear = self.oldest_buffered_group - self.bottom_group;
+ if nclear > 0 && nclear >= self.buffer.len() / 2 {
+ let mut i = 0;
+ self.buffer.retain(|buf| {
+ i += 1;
+ debug_assert!(buf.len() == 0 || i > nclear);
+ i > nclear
+ });
+ self.bottom_group = self.oldest_buffered_group;
+ }
+ }
+ elt
+ }
+
+ /// Take the next element from the iterator, and set the done
+ /// flag if exhausted. Must not be called after done.
+ #[inline(always)]
+ fn next_element(&mut self) -> Option<I::Item> {
+ debug_assert!(!self.done);
+ match self.iter.next() {
+ None => { self.done = true; None }
+ otherwise => otherwise,
+ }
+ }
+
+
+ #[inline(never)]
+ fn step_buffering(&mut self, client: usize) -> Option<I::Item> {
+ // requested a later group -- walk through the current group up to
+ // the requested group index, and buffer the elements (unless
+ // the group is marked as dropped).
+ // Because the `Groups` iterator is always the first to request
+ // each group index, client is the next index efter top_group.
+ debug_assert!(self.top_group + 1 == client);
+ let mut group = Vec::new();
+
+ if let Some(elt) = self.current_elt.take() {
+ if self.top_group != self.dropped_group {
+ group.push(elt);
+ }
+ }
+ let mut first_elt = None; // first element of the next group
+
+ while let Some(elt) = self.next_element() {
+ let key = self.key.call_mut(&elt);
+ match self.current_key.take() {
+ None => {}
+ Some(old_key) => if old_key != key {
+ self.current_key = Some(key);
+ first_elt = Some(elt);
+ break;
+ },
+ }
+ self.current_key = Some(key);
+ if self.top_group != self.dropped_group {
+ group.push(elt);
+ }
+ }
+
+ if self.top_group != self.dropped_group {
+ self.push_next_group(group);
+ }
+ if first_elt.is_some() {
+ self.top_group += 1;
+ debug_assert!(self.top_group == client);
+ }
+ first_elt
+ }
+
+ fn push_next_group(&mut self, group: Vec<I::Item>) {
+ // When we add a new buffered group, fill up slots between oldest_buffered_group and top_group
+ while self.top_group - self.bottom_group > self.buffer.len() {
+ if self.buffer.is_empty() {
+ self.bottom_group += 1;
+ self.oldest_buffered_group += 1;
+ } else {
+ self.buffer.push(Vec::new().into_iter());
+ }
+ }
+ self.buffer.push(group.into_iter());
+ debug_assert!(self.top_group + 1 - self.bottom_group == self.buffer.len());
+ }
+
+ /// This is the immediate case, where we use no buffering
+ #[inline]
+ fn step_current(&mut self) -> Option<I::Item> {
+ debug_assert!(!self.done);
+ if let elt @ Some(..) = self.current_elt.take() {
+ return elt;
+ }
+ match self.next_element() {
+ None => None,
+ Some(elt) => {
+ let key = self.key.call_mut(&elt);
+ match self.current_key.take() {
+ None => {}
+ Some(old_key) => if old_key != key {
+ self.current_key = Some(key);
+ self.current_elt = Some(elt);
+ self.top_group += 1;
+ return None;
+ },
+ }
+ self.current_key = Some(key);
+ Some(elt)
+ }
+ }
+ }
+
+ /// Request the just started groups' key.
+ ///
+ /// `client`: Index of group
+ ///
+ /// **Panics** if no group key is available.
+ fn group_key(&mut self, client: usize) -> K {
+ // This can only be called after we have just returned the first
+ // element of a group.
+ // Perform this by simply buffering one more element, grabbing the
+ // next key.
+ debug_assert!(!self.done);
+ debug_assert!(client == self.top_group);
+ debug_assert!(self.current_key.is_some());
+ debug_assert!(self.current_elt.is_none());
+ let old_key = self.current_key.take().unwrap();
+ if let Some(elt) = self.next_element() {
+ let key = self.key.call_mut(&elt);
+ if old_key != key {
+ self.top_group += 1;
+ }
+ self.current_key = Some(key);
+ self.current_elt = Some(elt);
+ }
+ old_key
+ }
+}
+
+impl<K, I, F> GroupInner<K, I, F>
+ where I: Iterator,
+{
+ /// Called when a group is dropped
+ fn drop_group(&mut self, client: usize) {
+ // It's only useful to track the maximal index
+ if self.dropped_group == !0 || client > self.dropped_group {
+ self.dropped_group = client;
+ }
+ }
+}
+
+/// `GroupBy` is the storage for the lazy grouping operation.
+///
+/// If the groups are consumed in their original order, or if each
+/// group is dropped without keeping it around, then `GroupBy` uses
+/// no allocations. It needs allocations only if several group iterators
+/// are alive at the same time.
+///
+/// This type implements [`IntoIterator`] (it is **not** an iterator
+/// itself), because the group iterators need to borrow from this
+/// value. It should be stored in a local variable or temporary and
+/// iterated.
+///
+/// See [`.group_by()`](crate::Itertools::group_by) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct GroupBy<K, I, F>
+ where I: Iterator,
+{
+ inner: RefCell<GroupInner<K, I, F>>,
+ // the group iterator's current index. Keep this in the main value
+ // so that simultaneous iterators all use the same state.
+ index: Cell<usize>,
+}
+
+/// Create a new
+pub fn new<K, J, F>(iter: J, f: F) -> GroupBy<K, J::IntoIter, F>
+ where J: IntoIterator,
+ F: FnMut(&J::Item) -> K,
+{
+ GroupBy {
+ inner: RefCell::new(GroupInner {
+ key: f,
+ iter: iter.into_iter(),
+ current_key: None,
+ current_elt: None,
+ done: false,
+ top_group: 0,
+ oldest_buffered_group: 0,
+ bottom_group: 0,
+ buffer: Vec::new(),
+ dropped_group: !0,
+ }),
+ index: Cell::new(0),
+ }
+}
+
+impl<K, I, F> GroupBy<K, I, F>
+ where I: Iterator,
+{
+ /// `client`: Index of group that requests next element
+ fn step(&self, client: usize) -> Option<I::Item>
+ where F: FnMut(&I::Item) -> K,
+ K: PartialEq,
+ {
+ self.inner.borrow_mut().step(client)
+ }
+
+ /// `client`: Index of group
+ fn drop_group(&self, client: usize) {
+ self.inner.borrow_mut().drop_group(client);
+ }
+}
+
+impl<'a, K, I, F> IntoIterator for &'a GroupBy<K, I, F>
+ where I: Iterator,
+ I::Item: 'a,
+ F: FnMut(&I::Item) -> K,
+ K: PartialEq
+{
+ type Item = (K, Group<'a, K, I, F>);
+ type IntoIter = Groups<'a, K, I, F>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ Groups { parent: self }
+ }
+}
+
+
+/// An iterator that yields the Group iterators.
+///
+/// Iterator element type is `(K, Group)`:
+/// the group's key `K` and the group's iterator.
+///
+/// See [`.group_by()`](crate::Itertools::group_by) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Groups<'a, K: 'a, I: 'a, F: 'a>
+ where I: Iterator,
+ I::Item: 'a
+{
+ parent: &'a GroupBy<K, I, F>,
+}
+
+impl<'a, K, I, F> Iterator for Groups<'a, K, I, F>
+ where I: Iterator,
+ I::Item: 'a,
+ F: FnMut(&I::Item) -> K,
+ K: PartialEq
+{
+ type Item = (K, Group<'a, K, I, F>);
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ let index = self.parent.index.get();
+ self.parent.index.set(index + 1);
+ let inner = &mut *self.parent.inner.borrow_mut();
+ inner.step(index).map(|elt| {
+ let key = inner.group_key(index);
+ (key, Group {
+ parent: self.parent,
+ index,
+ first: Some(elt),
+ })
+ })
+ }
+}
+
+/// An iterator for the elements in a single group.
+///
+/// Iterator element type is `I::Item`.
+pub struct Group<'a, K: 'a, I: 'a, F: 'a>
+ where I: Iterator,
+ I::Item: 'a,
+{
+ parent: &'a GroupBy<K, I, F>,
+ index: usize,
+ first: Option<I::Item>,
+}
+
+impl<'a, K, I, F> Drop for Group<'a, K, I, F>
+ where I: Iterator,
+ I::Item: 'a,
+{
+ fn drop(&mut self) {
+ self.parent.drop_group(self.index);
+ }
+}
+
+impl<'a, K, I, F> Iterator for Group<'a, K, I, F>
+ where I: Iterator,
+ I::Item: 'a,
+ F: FnMut(&I::Item) -> K,
+ K: PartialEq,
+{
+ type Item = I::Item;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ if let elt @ Some(..) = self.first.take() {
+ return elt;
+ }
+ self.parent.step(self.index)
+ }
+}
+
+///// IntoChunks /////
+
+/// Create a new
+pub fn new_chunks<J>(iter: J, size: usize) -> IntoChunks<J::IntoIter>
+ where J: IntoIterator,
+{
+ IntoChunks {
+ inner: RefCell::new(GroupInner {
+ key: ChunkIndex::new(size),
+ iter: iter.into_iter(),
+ current_key: None,
+ current_elt: None,
+ done: false,
+ top_group: 0,
+ oldest_buffered_group: 0,
+ bottom_group: 0,
+ buffer: Vec::new(),
+ dropped_group: !0,
+ }),
+ index: Cell::new(0),
+ }
+}
+
+
+/// `ChunkLazy` is the storage for a lazy chunking operation.
+///
+/// `IntoChunks` behaves just like `GroupBy`: it is iterable, and
+/// it only buffers if several chunk iterators are alive at the same time.
+///
+/// This type implements [`IntoIterator`] (it is **not** an iterator
+/// itself), because the chunk iterators need to borrow from this
+/// value. It should be stored in a local variable or temporary and
+/// iterated.
+///
+/// Iterator element type is `Chunk`, each chunk's iterator.
+///
+/// See [`.chunks()`](crate::Itertools::chunks) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct IntoChunks<I>
+ where I: Iterator,
+{
+ inner: RefCell<GroupInner<usize, I, ChunkIndex>>,
+ // the chunk iterator's current index. Keep this in the main value
+ // so that simultaneous iterators all use the same state.
+ index: Cell<usize>,
+}
+
+impl<I> Clone for IntoChunks<I>
+ where I: Clone + Iterator,
+ I::Item: Clone,
+{
+ clone_fields!(inner, index);
+}
+
+
+impl<I> IntoChunks<I>
+ where I: Iterator,
+{
+ /// `client`: Index of chunk that requests next element
+ fn step(&self, client: usize) -> Option<I::Item> {
+ self.inner.borrow_mut().step(client)
+ }
+
+ /// `client`: Index of chunk
+ fn drop_group(&self, client: usize) {
+ self.inner.borrow_mut().drop_group(client);
+ }
+}
+
+impl<'a, I> IntoIterator for &'a IntoChunks<I>
+ where I: Iterator,
+ I::Item: 'a,
+{
+ type Item = Chunk<'a, I>;
+ type IntoIter = Chunks<'a, I>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ Chunks {
+ parent: self,
+ }
+ }
+}
+
+
+/// An iterator that yields the Chunk iterators.
+///
+/// Iterator element type is `Chunk`.
+///
+/// See [`.chunks()`](crate::Itertools::chunks) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Clone)]
+pub struct Chunks<'a, I: 'a>
+ where I: Iterator,
+ I::Item: 'a,
+{
+ parent: &'a IntoChunks<I>,
+}
+
+impl<'a, I> Iterator for Chunks<'a, I>
+ where I: Iterator,
+ I::Item: 'a,
+{
+ type Item = Chunk<'a, I>;
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ let index = self.parent.index.get();
+ self.parent.index.set(index + 1);
+ let inner = &mut *self.parent.inner.borrow_mut();
+ inner.step(index).map(|elt| {
+ Chunk {
+ parent: self.parent,
+ index,
+ first: Some(elt),
+ }
+ })
+ }
+}
+
+/// An iterator for the elements in a single chunk.
+///
+/// Iterator element type is `I::Item`.
+pub struct Chunk<'a, I: 'a>
+ where I: Iterator,
+ I::Item: 'a,
+{
+ parent: &'a IntoChunks<I>,
+ index: usize,
+ first: Option<I::Item>,
+}
+
+impl<'a, I> Drop for Chunk<'a, I>
+ where I: Iterator,
+ I::Item: 'a,
+{
+ fn drop(&mut self) {
+ self.parent.drop_group(self.index);
+ }
+}
+
+impl<'a, I> Iterator for Chunk<'a, I>
+ where I: Iterator,
+ I::Item: 'a,
+{
+ type Item = I::Item;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ if let elt @ Some(..) = self.first.take() {
+ return elt;
+ }
+ self.parent.step(self.index)
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/grouping_map.rs b/rust/hw/char/pl011/vendor/itertools/src/grouping_map.rs
new file mode 100644
index 0000000000..bb5b582c92
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/grouping_map.rs
@@ -0,0 +1,535 @@
+#![cfg(feature = "use_std")]
+
+use crate::MinMaxResult;
+use std::collections::HashMap;
+use std::cmp::Ordering;
+use std::hash::Hash;
+use std::iter::Iterator;
+use std::ops::{Add, Mul};
+
+/// A wrapper to allow for an easy [`into_grouping_map_by`](crate::Itertools::into_grouping_map_by)
+#[derive(Clone, Debug)]
+pub struct MapForGrouping<I, F>(I, F);
+
+impl<I, F> MapForGrouping<I, F> {
+ pub(crate) fn new(iter: I, key_mapper: F) -> Self {
+ Self(iter, key_mapper)
+ }
+}
+
+impl<K, V, I, F> Iterator for MapForGrouping<I, F>
+ where I: Iterator<Item = V>,
+ K: Hash + Eq,
+ F: FnMut(&V) -> K,
+{
+ type Item = (K, V);
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next().map(|val| ((self.1)(&val), val))
+ }
+}
+
+/// Creates a new `GroupingMap` from `iter`
+pub fn new<I, K, V>(iter: I) -> GroupingMap<I>
+ where I: Iterator<Item = (K, V)>,
+ K: Hash + Eq,
+{
+ GroupingMap { iter }
+}
+
+/// `GroupingMapBy` is an intermediate struct for efficient group-and-fold operations.
+///
+/// See [`GroupingMap`] for more informations.
+pub type GroupingMapBy<I, F> = GroupingMap<MapForGrouping<I, F>>;
+
+/// `GroupingMap` is an intermediate struct for efficient group-and-fold operations.
+/// It groups elements by their key and at the same time fold each group
+/// using some aggregating operation.
+///
+/// No method on this struct performs temporary allocations.
+#[derive(Clone, Debug)]
+#[must_use = "GroupingMap is lazy and do nothing unless consumed"]
+pub struct GroupingMap<I> {
+ iter: I,
+}
+
+impl<I, K, V> GroupingMap<I>
+ where I: Iterator<Item = (K, V)>,
+ K: Hash + Eq,
+{
+ /// This is the generic way to perform any operation on a `GroupingMap`.
+ /// It's suggested to use this method only to implement custom operations
+ /// when the already provided ones are not enough.
+ ///
+ /// Groups elements from the `GroupingMap` source by key and applies `operation` to the elements
+ /// of each group sequentially, passing the previously accumulated value, a reference to the key
+ /// and the current element as arguments, and stores the results in an `HashMap`.
+ ///
+ /// The `operation` function is invoked on each element with the following parameters:
+ /// - the current value of the accumulator of the group if there is currently one;
+ /// - a reference to the key of the group this element belongs to;
+ /// - the element from the source being aggregated;
+ ///
+ /// If `operation` returns `Some(element)` then the accumulator is updated with `element`,
+ /// otherwise the previous accumulation is discarded.
+ ///
+ /// Return a `HashMap` associating the key of each group with the result of aggregation of
+ /// that group's elements. If the aggregation of the last element of a group discards the
+ /// accumulator then there won't be an entry associated to that group's key.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec![2, 8, 5, 7, 9, 0, 4, 10];
+ /// let lookup = data.into_iter()
+ /// .into_grouping_map_by(|&n| n % 4)
+ /// .aggregate(|acc, _key, val| {
+ /// if val == 0 || val == 10 {
+ /// None
+ /// } else {
+ /// Some(acc.unwrap_or(0) + val)
+ /// }
+ /// });
+ ///
+ /// assert_eq!(lookup[&0], 4); // 0 resets the accumulator so only 4 is summed
+ /// assert_eq!(lookup[&1], 5 + 9);
+ /// assert_eq!(lookup.get(&2), None); // 10 resets the accumulator and nothing is summed afterward
+ /// assert_eq!(lookup[&3], 7);
+ /// assert_eq!(lookup.len(), 3); // The final keys are only 0, 1 and 2
+ /// ```
+ pub fn aggregate<FO, R>(self, mut operation: FO) -> HashMap<K, R>
+ where FO: FnMut(Option<R>, &K, V) -> Option<R>,
+ {
+ let mut destination_map = HashMap::new();
+
+ self.iter.for_each(|(key, val)| {
+ let acc = destination_map.remove(&key);
+ if let Some(op_res) = operation(acc, &key, val) {
+ destination_map.insert(key, op_res);
+ }
+ });
+
+ destination_map
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and applies `operation` to the elements
+ /// of each group sequentially, passing the previously accumulated value, a reference to the key
+ /// and the current element as arguments, and stores the results in a new map.
+ ///
+ /// `init` is the value from which will be cloned the initial value of each accumulator.
+ ///
+ /// `operation` is a function that is invoked on each element with the following parameters:
+ /// - the current value of the accumulator of the group;
+ /// - a reference to the key of the group this element belongs to;
+ /// - the element from the source being accumulated.
+ ///
+ /// Return a `HashMap` associating the key of each group with the result of folding that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let lookup = (1..=7)
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .fold(0, |acc, _key, val| acc + val);
+ ///
+ /// assert_eq!(lookup[&0], 3 + 6);
+ /// assert_eq!(lookup[&1], 1 + 4 + 7);
+ /// assert_eq!(lookup[&2], 2 + 5);
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn fold<FO, R>(self, init: R, mut operation: FO) -> HashMap<K, R>
+ where R: Clone,
+ FO: FnMut(R, &K, V) -> R,
+ {
+ self.aggregate(|acc, key, val| {
+ let acc = acc.unwrap_or_else(|| init.clone());
+ Some(operation(acc, key, val))
+ })
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and applies `operation` to the elements
+ /// of each group sequentially, passing the previously accumulated value, a reference to the key
+ /// and the current element as arguments, and stores the results in a new map.
+ ///
+ /// This is similar to [`fold`] but the initial value of the accumulator is the first element of the group.
+ ///
+ /// `operation` is a function that is invoked on each element with the following parameters:
+ /// - the current value of the accumulator of the group;
+ /// - a reference to the key of the group this element belongs to;
+ /// - the element from the source being accumulated.
+ ///
+ /// Return a `HashMap` associating the key of each group with the result of folding that group's elements.
+ ///
+ /// [`fold`]: GroupingMap::fold
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let lookup = (1..=7)
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .fold_first(|acc, _key, val| acc + val);
+ ///
+ /// assert_eq!(lookup[&0], 3 + 6);
+ /// assert_eq!(lookup[&1], 1 + 4 + 7);
+ /// assert_eq!(lookup[&2], 2 + 5);
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn fold_first<FO>(self, mut operation: FO) -> HashMap<K, V>
+ where FO: FnMut(V, &K, V) -> V,
+ {
+ self.aggregate(|acc, key, val| {
+ Some(match acc {
+ Some(acc) => operation(acc, key, val),
+ None => val,
+ })
+ })
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and collects the elements of each group in
+ /// an instance of `C`. The iteration order is preserved when inserting elements.
+ ///
+ /// Return a `HashMap` associating the key of each group with the collection containing that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// use std::collections::HashSet;
+ ///
+ /// let lookup = vec![0, 1, 2, 3, 4, 5, 6, 2, 3, 6].into_iter()
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .collect::<HashSet<_>>();
+ ///
+ /// assert_eq!(lookup[&0], vec![0, 3, 6].into_iter().collect::<HashSet<_>>());
+ /// assert_eq!(lookup[&1], vec![1, 4].into_iter().collect::<HashSet<_>>());
+ /// assert_eq!(lookup[&2], vec![2, 5].into_iter().collect::<HashSet<_>>());
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn collect<C>(self) -> HashMap<K, C>
+ where C: Default + Extend<V>,
+ {
+ let mut destination_map = HashMap::new();
+
+ self.iter.for_each(|(key, val)| {
+ destination_map.entry(key).or_insert_with(C::default).extend(Some(val));
+ });
+
+ destination_map
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and finds the maximum of each group.
+ ///
+ /// If several elements are equally maximum, the last element is picked.
+ ///
+ /// Returns a `HashMap` associating the key of each group with the maximum of that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let lookup = vec![1, 3, 4, 5, 7, 8, 9, 12].into_iter()
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .max();
+ ///
+ /// assert_eq!(lookup[&0], 12);
+ /// assert_eq!(lookup[&1], 7);
+ /// assert_eq!(lookup[&2], 8);
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn max(self) -> HashMap<K, V>
+ where V: Ord,
+ {
+ self.max_by(|_, v1, v2| V::cmp(v1, v2))
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and finds the maximum of each group
+ /// with respect to the specified comparison function.
+ ///
+ /// If several elements are equally maximum, the last element is picked.
+ ///
+ /// Returns a `HashMap` associating the key of each group with the maximum of that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let lookup = vec![1, 3, 4, 5, 7, 8, 9, 12].into_iter()
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .max_by(|_key, x, y| y.cmp(x));
+ ///
+ /// assert_eq!(lookup[&0], 3);
+ /// assert_eq!(lookup[&1], 1);
+ /// assert_eq!(lookup[&2], 5);
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn max_by<F>(self, mut compare: F) -> HashMap<K, V>
+ where F: FnMut(&K, &V, &V) -> Ordering,
+ {
+ self.fold_first(|acc, key, val| match compare(key, &acc, &val) {
+ Ordering::Less | Ordering::Equal => val,
+ Ordering::Greater => acc
+ })
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and finds the element of each group
+ /// that gives the maximum from the specified function.
+ ///
+ /// If several elements are equally maximum, the last element is picked.
+ ///
+ /// Returns a `HashMap` associating the key of each group with the maximum of that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let lookup = vec![1, 3, 4, 5, 7, 8, 9, 12].into_iter()
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .max_by_key(|_key, &val| val % 4);
+ ///
+ /// assert_eq!(lookup[&0], 3);
+ /// assert_eq!(lookup[&1], 7);
+ /// assert_eq!(lookup[&2], 5);
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn max_by_key<F, CK>(self, mut f: F) -> HashMap<K, V>
+ where F: FnMut(&K, &V) -> CK,
+ CK: Ord,
+ {
+ self.max_by(|key, v1, v2| f(key, v1).cmp(&f(key, v2)))
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and finds the minimum of each group.
+ ///
+ /// If several elements are equally minimum, the first element is picked.
+ ///
+ /// Returns a `HashMap` associating the key of each group with the minimum of that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let lookup = vec![1, 3, 4, 5, 7, 8, 9, 12].into_iter()
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .min();
+ ///
+ /// assert_eq!(lookup[&0], 3);
+ /// assert_eq!(lookup[&1], 1);
+ /// assert_eq!(lookup[&2], 5);
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn min(self) -> HashMap<K, V>
+ where V: Ord,
+ {
+ self.min_by(|_, v1, v2| V::cmp(v1, v2))
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and finds the minimum of each group
+ /// with respect to the specified comparison function.
+ ///
+ /// If several elements are equally minimum, the first element is picked.
+ ///
+ /// Returns a `HashMap` associating the key of each group with the minimum of that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let lookup = vec![1, 3, 4, 5, 7, 8, 9, 12].into_iter()
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .min_by(|_key, x, y| y.cmp(x));
+ ///
+ /// assert_eq!(lookup[&0], 12);
+ /// assert_eq!(lookup[&1], 7);
+ /// assert_eq!(lookup[&2], 8);
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn min_by<F>(self, mut compare: F) -> HashMap<K, V>
+ where F: FnMut(&K, &V, &V) -> Ordering,
+ {
+ self.fold_first(|acc, key, val| match compare(key, &acc, &val) {
+ Ordering::Less | Ordering::Equal => acc,
+ Ordering::Greater => val
+ })
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and finds the element of each group
+ /// that gives the minimum from the specified function.
+ ///
+ /// If several elements are equally minimum, the first element is picked.
+ ///
+ /// Returns a `HashMap` associating the key of each group with the minimum of that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let lookup = vec![1, 3, 4, 5, 7, 8, 9, 12].into_iter()
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .min_by_key(|_key, &val| val % 4);
+ ///
+ /// assert_eq!(lookup[&0], 12);
+ /// assert_eq!(lookup[&1], 4);
+ /// assert_eq!(lookup[&2], 8);
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn min_by_key<F, CK>(self, mut f: F) -> HashMap<K, V>
+ where F: FnMut(&K, &V) -> CK,
+ CK: Ord,
+ {
+ self.min_by(|key, v1, v2| f(key, v1).cmp(&f(key, v2)))
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and find the maximum and minimum of
+ /// each group.
+ ///
+ /// If several elements are equally maximum, the last element is picked.
+ /// If several elements are equally minimum, the first element is picked.
+ ///
+ /// See [.minmax()](crate::Itertools::minmax) for the non-grouping version.
+ ///
+ /// Differences from the non grouping version:
+ /// - It never produces a `MinMaxResult::NoElements`
+ /// - It doesn't have any speedup
+ ///
+ /// Returns a `HashMap` associating the key of each group with the minimum and maximum of that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// use itertools::MinMaxResult::{OneElement, MinMax};
+ ///
+ /// let lookup = vec![1, 3, 4, 5, 7, 9, 12].into_iter()
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .minmax();
+ ///
+ /// assert_eq!(lookup[&0], MinMax(3, 12));
+ /// assert_eq!(lookup[&1], MinMax(1, 7));
+ /// assert_eq!(lookup[&2], OneElement(5));
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn minmax(self) -> HashMap<K, MinMaxResult<V>>
+ where V: Ord,
+ {
+ self.minmax_by(|_, v1, v2| V::cmp(v1, v2))
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and find the maximum and minimum of
+ /// each group with respect to the specified comparison function.
+ ///
+ /// If several elements are equally maximum, the last element is picked.
+ /// If several elements are equally minimum, the first element is picked.
+ ///
+ /// It has the same differences from the non-grouping version as `minmax`.
+ ///
+ /// Returns a `HashMap` associating the key of each group with the minimum and maximum of that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// use itertools::MinMaxResult::{OneElement, MinMax};
+ ///
+ /// let lookup = vec![1, 3, 4, 5, 7, 9, 12].into_iter()
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .minmax_by(|_key, x, y| y.cmp(x));
+ ///
+ /// assert_eq!(lookup[&0], MinMax(12, 3));
+ /// assert_eq!(lookup[&1], MinMax(7, 1));
+ /// assert_eq!(lookup[&2], OneElement(5));
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn minmax_by<F>(self, mut compare: F) -> HashMap<K, MinMaxResult<V>>
+ where F: FnMut(&K, &V, &V) -> Ordering,
+ {
+ self.aggregate(|acc, key, val| {
+ Some(match acc {
+ Some(MinMaxResult::OneElement(e)) => {
+ if compare(key, &val, &e) == Ordering::Less {
+ MinMaxResult::MinMax(val, e)
+ } else {
+ MinMaxResult::MinMax(e, val)
+ }
+ }
+ Some(MinMaxResult::MinMax(min, max)) => {
+ if compare(key, &val, &min) == Ordering::Less {
+ MinMaxResult::MinMax(val, max)
+ } else if compare(key, &val, &max) != Ordering::Less {
+ MinMaxResult::MinMax(min, val)
+ } else {
+ MinMaxResult::MinMax(min, max)
+ }
+ }
+ None => MinMaxResult::OneElement(val),
+ Some(MinMaxResult::NoElements) => unreachable!(),
+ })
+ })
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and find the elements of each group
+ /// that gives the minimum and maximum from the specified function.
+ ///
+ /// If several elements are equally maximum, the last element is picked.
+ /// If several elements are equally minimum, the first element is picked.
+ ///
+ /// It has the same differences from the non-grouping version as `minmax`.
+ ///
+ /// Returns a `HashMap` associating the key of each group with the minimum and maximum of that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// use itertools::MinMaxResult::{OneElement, MinMax};
+ ///
+ /// let lookup = vec![1, 3, 4, 5, 7, 9, 12].into_iter()
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .minmax_by_key(|_key, &val| val % 4);
+ ///
+ /// assert_eq!(lookup[&0], MinMax(12, 3));
+ /// assert_eq!(lookup[&1], MinMax(4, 7));
+ /// assert_eq!(lookup[&2], OneElement(5));
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn minmax_by_key<F, CK>(self, mut f: F) -> HashMap<K, MinMaxResult<V>>
+ where F: FnMut(&K, &V) -> CK,
+ CK: Ord,
+ {
+ self.minmax_by(|key, v1, v2| f(key, v1).cmp(&f(key, v2)))
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and sums them.
+ ///
+ /// This is just a shorthand for `self.fold_first(|acc, _, val| acc + val)`.
+ /// It is more limited than `Iterator::sum` since it doesn't use the `Sum` trait.
+ ///
+ /// Returns a `HashMap` associating the key of each group with the sum of that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let lookup = vec![1, 3, 4, 5, 7, 8, 9, 12].into_iter()
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .sum();
+ ///
+ /// assert_eq!(lookup[&0], 3 + 9 + 12);
+ /// assert_eq!(lookup[&1], 1 + 4 + 7);
+ /// assert_eq!(lookup[&2], 5 + 8);
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn sum(self) -> HashMap<K, V>
+ where V: Add<V, Output = V>
+ {
+ self.fold_first(|acc, _, val| acc + val)
+ }
+
+ /// Groups elements from the `GroupingMap` source by key and multiply them.
+ ///
+ /// This is just a shorthand for `self.fold_first(|acc, _, val| acc * val)`.
+ /// It is more limited than `Iterator::product` since it doesn't use the `Product` trait.
+ ///
+ /// Returns a `HashMap` associating the key of each group with the product of that group's elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let lookup = vec![1, 3, 4, 5, 7, 8, 9, 12].into_iter()
+ /// .into_grouping_map_by(|&n| n % 3)
+ /// .product();
+ ///
+ /// assert_eq!(lookup[&0], 3 * 9 * 12);
+ /// assert_eq!(lookup[&1], 1 * 4 * 7);
+ /// assert_eq!(lookup[&2], 5 * 8);
+ /// assert_eq!(lookup.len(), 3);
+ /// ```
+ pub fn product(self) -> HashMap<K, V>
+ where V: Mul<V, Output = V>,
+ {
+ self.fold_first(|acc, _, val| acc * val)
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/impl_macros.rs b/rust/hw/char/pl011/vendor/itertools/src/impl_macros.rs
new file mode 100644
index 0000000000..a029843b05
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/impl_macros.rs
@@ -0,0 +1,29 @@
+//!
+//! Implementation's internal macros
+
+macro_rules! debug_fmt_fields {
+ ($tyname:ident, $($($field:tt/*TODO ideally we would accept ident or tuple element here*/).+),*) => {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ f.debug_struct(stringify!($tyname))
+ $(
+ .field(stringify!($($field).+), &self.$($field).+)
+ )*
+ .finish()
+ }
+ }
+}
+
+macro_rules! clone_fields {
+ ($($field:ident),*) => {
+ #[inline] // TODO is this sensible?
+ fn clone(&self) -> Self {
+ Self {
+ $($field: self.$field.clone(),)*
+ }
+ }
+ }
+}
+
+macro_rules! ignore_ident{
+ ($id:ident, $($t:tt)*) => {$($t)*};
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/intersperse.rs b/rust/hw/char/pl011/vendor/itertools/src/intersperse.rs
new file mode 100644
index 0000000000..10a3a5389c
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/intersperse.rs
@@ -0,0 +1,118 @@
+use std::iter::{Fuse, FusedIterator};
+use super::size_hint;
+
+pub trait IntersperseElement<Item> {
+ fn generate(&mut self) -> Item;
+}
+
+#[derive(Debug, Clone)]
+pub struct IntersperseElementSimple<Item>(Item);
+
+impl<Item: Clone> IntersperseElement<Item> for IntersperseElementSimple<Item> {
+ fn generate(&mut self) -> Item {
+ self.0.clone()
+ }
+}
+
+/// An iterator adaptor to insert a particular value
+/// between each element of the adapted iterator.
+///
+/// Iterator element type is `I::Item`
+///
+/// This iterator is *fused*.
+///
+/// See [`.intersperse()`](crate::Itertools::intersperse) for more information.
+pub type Intersperse<I> = IntersperseWith<I, IntersperseElementSimple<<I as Iterator>::Item>>;
+
+/// Create a new Intersperse iterator
+pub fn intersperse<I>(iter: I, elt: I::Item) -> Intersperse<I>
+ where I: Iterator,
+{
+ intersperse_with(iter, IntersperseElementSimple(elt))
+}
+
+impl<Item, F: FnMut()->Item> IntersperseElement<Item> for F {
+ fn generate(&mut self) -> Item {
+ self()
+ }
+}
+
+/// An iterator adaptor to insert a particular value created by a function
+/// between each element of the adapted iterator.
+///
+/// Iterator element type is `I::Item`
+///
+/// This iterator is *fused*.
+///
+/// See [`.intersperse_with()`](crate::Itertools::intersperse_with) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Clone, Debug)]
+pub struct IntersperseWith<I, ElemF>
+ where I: Iterator,
+{
+ element: ElemF,
+ iter: Fuse<I>,
+ peek: Option<I::Item>,
+}
+
+/// Create a new `IntersperseWith` iterator
+pub fn intersperse_with<I, ElemF>(iter: I, elt: ElemF) -> IntersperseWith<I, ElemF>
+ where I: Iterator,
+{
+ let mut iter = iter.fuse();
+ IntersperseWith {
+ peek: iter.next(),
+ iter,
+ element: elt,
+ }
+}
+
+impl<I, ElemF> Iterator for IntersperseWith<I, ElemF>
+ where I: Iterator,
+ ElemF: IntersperseElement<I::Item>
+{
+ type Item = I::Item;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.peek.is_some() {
+ self.peek.take()
+ } else {
+ self.peek = self.iter.next();
+ if self.peek.is_some() {
+ Some(self.element.generate())
+ } else {
+ None
+ }
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ // 2 * SH + { 1 or 0 }
+ let has_peek = self.peek.is_some() as usize;
+ let sh = self.iter.size_hint();
+ size_hint::add_scalar(size_hint::add(sh, sh), has_peek)
+ }
+
+ fn fold<B, F>(mut self, init: B, mut f: F) -> B where
+ Self: Sized, F: FnMut(B, Self::Item) -> B,
+ {
+ let mut accum = init;
+
+ if let Some(x) = self.peek.take() {
+ accum = f(accum, x);
+ }
+
+ let element = &mut self.element;
+
+ self.iter.fold(accum,
+ |accum, x| {
+ let accum = f(accum, element.generate());
+ f(accum, x)
+ })
+ }
+}
+
+impl<I, ElemF> FusedIterator for IntersperseWith<I, ElemF>
+ where I: Iterator,
+ ElemF: IntersperseElement<I::Item>
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/k_smallest.rs b/rust/hw/char/pl011/vendor/itertools/src/k_smallest.rs
new file mode 100644
index 0000000000..acaea5941c
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/k_smallest.rs
@@ -0,0 +1,20 @@
+use alloc::collections::BinaryHeap;
+use core::cmp::Ord;
+
+pub(crate) fn k_smallest<T: Ord, I: Iterator<Item = T>>(mut iter: I, k: usize) -> BinaryHeap<T> {
+ if k == 0 { return BinaryHeap::new(); }
+
+ let mut heap = iter.by_ref().take(k).collect::<BinaryHeap<_>>();
+
+ iter.for_each(|i| {
+ debug_assert_eq!(heap.len(), k);
+ // Equivalent to heap.push(min(i, heap.pop())) but more efficient.
+ // This should be done with a single `.peek_mut().unwrap()` but
+ // `PeekMut` sifts-down unconditionally on Rust 1.46.0 and prior.
+ if *heap.peek().unwrap() > i {
+ *heap.peek_mut().unwrap() = i;
+ }
+ });
+
+ heap
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/kmerge_impl.rs b/rust/hw/char/pl011/vendor/itertools/src/kmerge_impl.rs
new file mode 100644
index 0000000000..509d5fc6a3
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/kmerge_impl.rs
@@ -0,0 +1,227 @@
+use crate::size_hint;
+use crate::Itertools;
+
+use alloc::vec::Vec;
+use std::iter::FusedIterator;
+use std::mem::replace;
+use std::fmt;
+
+/// Head element and Tail iterator pair
+///
+/// `PartialEq`, `Eq`, `PartialOrd` and `Ord` are implemented by comparing sequences based on
+/// first items (which are guaranteed to exist).
+///
+/// The meanings of `PartialOrd` and `Ord` are reversed so as to turn the heap used in
+/// `KMerge` into a min-heap.
+#[derive(Debug)]
+struct HeadTail<I>
+ where I: Iterator
+{
+ head: I::Item,
+ tail: I,
+}
+
+impl<I> HeadTail<I>
+ where I: Iterator
+{
+ /// Constructs a `HeadTail` from an `Iterator`. Returns `None` if the `Iterator` is empty.
+ fn new(mut it: I) -> Option<HeadTail<I>> {
+ let head = it.next();
+ head.map(|h| {
+ HeadTail {
+ head: h,
+ tail: it,
+ }
+ })
+ }
+
+ /// Get the next element and update `head`, returning the old head in `Some`.
+ ///
+ /// Returns `None` when the tail is exhausted (only `head` then remains).
+ fn next(&mut self) -> Option<I::Item> {
+ if let Some(next) = self.tail.next() {
+ Some(replace(&mut self.head, next))
+ } else {
+ None
+ }
+ }
+
+ /// Hints at the size of the sequence, same as the `Iterator` method.
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ size_hint::add_scalar(self.tail.size_hint(), 1)
+ }
+}
+
+impl<I> Clone for HeadTail<I>
+ where I: Iterator + Clone,
+ I::Item: Clone
+{
+ clone_fields!(head, tail);
+}
+
+/// Make `data` a heap (min-heap w.r.t the sorting).
+fn heapify<T, S>(data: &mut [T], mut less_than: S)
+ where S: FnMut(&T, &T) -> bool
+{
+ for i in (0..data.len() / 2).rev() {
+ sift_down(data, i, &mut less_than);
+ }
+}
+
+/// Sift down element at `index` (`heap` is a min-heap wrt the ordering)
+fn sift_down<T, S>(heap: &mut [T], index: usize, mut less_than: S)
+ where S: FnMut(&T, &T) -> bool
+{
+ debug_assert!(index <= heap.len());
+ let mut pos = index;
+ let mut child = 2 * pos + 1;
+ // Require the right child to be present
+ // This allows to find the index of the smallest child without a branch
+ // that wouldn't be predicted if present
+ while child + 1 < heap.len() {
+ // pick the smaller of the two children
+ // use arithmetic to avoid an unpredictable branch
+ child += less_than(&heap[child+1], &heap[child]) as usize;
+
+ // sift down is done if we are already in order
+ if !less_than(&heap[child], &heap[pos]) {
+ return;
+ }
+ heap.swap(pos, child);
+ pos = child;
+ child = 2 * pos + 1;
+ }
+ // Check if the last (left) child was an only child
+ // if it is then it has to be compared with the parent
+ if child + 1 == heap.len() && less_than(&heap[child], &heap[pos]) {
+ heap.swap(pos, child);
+ }
+}
+
+/// An iterator adaptor that merges an abitrary number of base iterators in ascending order.
+/// If all base iterators are sorted (ascending), the result is sorted.
+///
+/// Iterator element type is `I::Item`.
+///
+/// See [`.kmerge()`](crate::Itertools::kmerge) for more information.
+pub type KMerge<I> = KMergeBy<I, KMergeByLt>;
+
+pub trait KMergePredicate<T> {
+ fn kmerge_pred(&mut self, a: &T, b: &T) -> bool;
+}
+
+#[derive(Clone, Debug)]
+pub struct KMergeByLt;
+
+impl<T: PartialOrd> KMergePredicate<T> for KMergeByLt {
+ fn kmerge_pred(&mut self, a: &T, b: &T) -> bool {
+ a < b
+ }
+}
+
+impl<T, F: FnMut(&T, &T)->bool> KMergePredicate<T> for F {
+ fn kmerge_pred(&mut self, a: &T, b: &T) -> bool {
+ self(a, b)
+ }
+}
+
+/// Create an iterator that merges elements of the contained iterators using
+/// the ordering function.
+///
+/// [`IntoIterator`] enabled version of [`Itertools::kmerge`].
+///
+/// ```
+/// use itertools::kmerge;
+///
+/// for elt in kmerge(vec![vec![0, 2, 4], vec![1, 3, 5], vec![6, 7]]) {
+/// /* loop body */
+/// }
+/// ```
+pub fn kmerge<I>(iterable: I) -> KMerge<<I::Item as IntoIterator>::IntoIter>
+ where I: IntoIterator,
+ I::Item: IntoIterator,
+ <<I as IntoIterator>::Item as IntoIterator>::Item: PartialOrd
+{
+ kmerge_by(iterable, KMergeByLt)
+}
+
+/// An iterator adaptor that merges an abitrary number of base iterators
+/// according to an ordering function.
+///
+/// Iterator element type is `I::Item`.
+///
+/// See [`.kmerge_by()`](crate::Itertools::kmerge_by) for more
+/// information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct KMergeBy<I, F>
+ where I: Iterator,
+{
+ heap: Vec<HeadTail<I>>,
+ less_than: F,
+}
+
+impl<I, F> fmt::Debug for KMergeBy<I, F>
+ where I: Iterator + fmt::Debug,
+ I::Item: fmt::Debug,
+{
+ debug_fmt_fields!(KMergeBy, heap);
+}
+
+/// Create an iterator that merges elements of the contained iterators.
+///
+/// [`IntoIterator`] enabled version of [`Itertools::kmerge_by`].
+pub fn kmerge_by<I, F>(iterable: I, mut less_than: F)
+ -> KMergeBy<<I::Item as IntoIterator>::IntoIter, F>
+ where I: IntoIterator,
+ I::Item: IntoIterator,
+ F: KMergePredicate<<<I as IntoIterator>::Item as IntoIterator>::Item>,
+{
+ let iter = iterable.into_iter();
+ let (lower, _) = iter.size_hint();
+ let mut heap: Vec<_> = Vec::with_capacity(lower);
+ heap.extend(iter.filter_map(|it| HeadTail::new(it.into_iter())));
+ heapify(&mut heap, |a, b| less_than.kmerge_pred(&a.head, &b.head));
+ KMergeBy { heap, less_than }
+}
+
+impl<I, F> Clone for KMergeBy<I, F>
+ where I: Iterator + Clone,
+ I::Item: Clone,
+ F: Clone,
+{
+ clone_fields!(heap, less_than);
+}
+
+impl<I, F> Iterator for KMergeBy<I, F>
+ where I: Iterator,
+ F: KMergePredicate<I::Item>
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.heap.is_empty() {
+ return None;
+ }
+ let result = if let Some(next) = self.heap[0].next() {
+ next
+ } else {
+ self.heap.swap_remove(0).head
+ };
+ let less_than = &mut self.less_than;
+ sift_down(&mut self.heap, 0, |a, b| less_than.kmerge_pred(&a.head, &b.head));
+ Some(result)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ #[allow(deprecated)] //TODO: once msrv hits 1.51. replace `fold1` with `reduce`
+ self.heap.iter()
+ .map(|i| i.size_hint())
+ .fold1(size_hint::add)
+ .unwrap_or((0, Some(0)))
+ }
+}
+
+impl<I, F> FusedIterator for KMergeBy<I, F>
+ where I: Iterator,
+ F: KMergePredicate<I::Item>
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/lazy_buffer.rs b/rust/hw/char/pl011/vendor/itertools/src/lazy_buffer.rs
new file mode 100644
index 0000000000..ca24062aab
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/lazy_buffer.rs
@@ -0,0 +1,63 @@
+use std::ops::Index;
+use alloc::vec::Vec;
+
+#[derive(Debug, Clone)]
+pub struct LazyBuffer<I: Iterator> {
+ pub it: I,
+ done: bool,
+ buffer: Vec<I::Item>,
+}
+
+impl<I> LazyBuffer<I>
+where
+ I: Iterator,
+{
+ pub fn new(it: I) -> LazyBuffer<I> {
+ LazyBuffer {
+ it,
+ done: false,
+ buffer: Vec::new(),
+ }
+ }
+
+ pub fn len(&self) -> usize {
+ self.buffer.len()
+ }
+
+ pub fn get_next(&mut self) -> bool {
+ if self.done {
+ return false;
+ }
+ if let Some(x) = self.it.next() {
+ self.buffer.push(x);
+ true
+ } else {
+ self.done = true;
+ false
+ }
+ }
+
+ pub fn prefill(&mut self, len: usize) {
+ let buffer_len = self.buffer.len();
+
+ if !self.done && len > buffer_len {
+ let delta = len - buffer_len;
+
+ self.buffer.extend(self.it.by_ref().take(delta));
+ self.done = self.buffer.len() < len;
+ }
+ }
+}
+
+impl<I, J> Index<J> for LazyBuffer<I>
+where
+ I: Iterator,
+ I::Item: Sized,
+ Vec<I::Item>: Index<J>
+{
+ type Output = <Vec<I::Item> as Index<J>>::Output;
+
+ fn index(&self, index: J) -> &Self::Output {
+ self.buffer.index(index)
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/lib.rs b/rust/hw/char/pl011/vendor/itertools/src/lib.rs
new file mode 100644
index 0000000000..c23a65db5c
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/lib.rs
@@ -0,0 +1,3967 @@
+#![warn(missing_docs)]
+#![crate_name="itertools"]
+#![cfg_attr(not(feature = "use_std"), no_std)]
+
+//! Extra iterator adaptors, functions and macros.
+//!
+//! To extend [`Iterator`] with methods in this crate, import
+//! the [`Itertools`] trait:
+//!
+//! ```
+//! use itertools::Itertools;
+//! ```
+//!
+//! Now, new methods like [`interleave`](Itertools::interleave)
+//! are available on all iterators:
+//!
+//! ```
+//! use itertools::Itertools;
+//!
+//! let it = (1..3).interleave(vec![-1, -2]);
+//! itertools::assert_equal(it, vec![1, -1, 2, -2]);
+//! ```
+//!
+//! Most iterator methods are also provided as functions (with the benefit
+//! that they convert parameters using [`IntoIterator`]):
+//!
+//! ```
+//! use itertools::interleave;
+//!
+//! for elt in interleave(&[1, 2, 3], &[2, 3, 4]) {
+//! /* loop body */
+//! }
+//! ```
+//!
+//! ## Crate Features
+//!
+//! - `use_std`
+//! - Enabled by default.
+//! - Disable to compile itertools using `#![no_std]`. This disables
+//! any items that depend on collections (like `group_by`, `unique`,
+//! `kmerge`, `join` and many more).
+//!
+//! ## Rust Version
+//!
+//! This version of itertools requires Rust 1.32 or later.
+#![doc(html_root_url="https://docs.rs/itertools/0.8/")]
+
+#[cfg(not(feature = "use_std"))]
+extern crate core as std;
+
+#[cfg(feature = "use_alloc")]
+extern crate alloc;
+
+#[cfg(feature = "use_alloc")]
+use alloc::{
+ string::String,
+ vec::Vec,
+};
+
+pub use either::Either;
+
+use core::borrow::Borrow;
+#[cfg(feature = "use_std")]
+use std::collections::HashMap;
+use std::iter::{IntoIterator, once};
+use std::cmp::Ordering;
+use std::fmt;
+#[cfg(feature = "use_std")]
+use std::collections::HashSet;
+#[cfg(feature = "use_std")]
+use std::hash::Hash;
+#[cfg(feature = "use_alloc")]
+use std::fmt::Write;
+#[cfg(feature = "use_alloc")]
+type VecIntoIter<T> = alloc::vec::IntoIter<T>;
+#[cfg(feature = "use_alloc")]
+use std::iter::FromIterator;
+
+#[macro_use]
+mod impl_macros;
+
+// for compatibility with no std and macros
+#[doc(hidden)]
+pub use std::iter as __std_iter;
+
+/// The concrete iterator types.
+pub mod structs {
+ pub use crate::adaptors::{
+ Dedup,
+ DedupBy,
+ DedupWithCount,
+ DedupByWithCount,
+ Interleave,
+ InterleaveShortest,
+ FilterMapOk,
+ FilterOk,
+ Product,
+ PutBack,
+ Batching,
+ MapInto,
+ MapOk,
+ Merge,
+ MergeBy,
+ TakeWhileRef,
+ WhileSome,
+ Coalesce,
+ TupleCombinations,
+ Positions,
+ Update,
+ };
+ #[allow(deprecated)]
+ pub use crate::adaptors::{MapResults, Step};
+ #[cfg(feature = "use_alloc")]
+ pub use crate::adaptors::MultiProduct;
+ #[cfg(feature = "use_alloc")]
+ pub use crate::combinations::Combinations;
+ #[cfg(feature = "use_alloc")]
+ pub use crate::combinations_with_replacement::CombinationsWithReplacement;
+ pub use crate::cons_tuples_impl::ConsTuples;
+ pub use crate::exactly_one_err::ExactlyOneError;
+ pub use crate::format::{Format, FormatWith};
+ pub use crate::flatten_ok::FlattenOk;
+ #[cfg(feature = "use_std")]
+ pub use crate::grouping_map::{GroupingMap, GroupingMapBy};
+ #[cfg(feature = "use_alloc")]
+ pub use crate::groupbylazy::{IntoChunks, Chunk, Chunks, GroupBy, Group, Groups};
+ pub use crate::intersperse::{Intersperse, IntersperseWith};
+ #[cfg(feature = "use_alloc")]
+ pub use crate::kmerge_impl::{KMerge, KMergeBy};
+ pub use crate::merge_join::MergeJoinBy;
+ #[cfg(feature = "use_alloc")]
+ pub use crate::multipeek_impl::MultiPeek;
+ #[cfg(feature = "use_alloc")]
+ pub use crate::peek_nth::PeekNth;
+ pub use crate::pad_tail::PadUsing;
+ pub use crate::peeking_take_while::PeekingTakeWhile;
+ #[cfg(feature = "use_alloc")]
+ pub use crate::permutations::Permutations;
+ pub use crate::process_results_impl::ProcessResults;
+ #[cfg(feature = "use_alloc")]
+ pub use crate::powerset::Powerset;
+ #[cfg(feature = "use_alloc")]
+ pub use crate::put_back_n_impl::PutBackN;
+ #[cfg(feature = "use_alloc")]
+ pub use crate::rciter_impl::RcIter;
+ pub use crate::repeatn::RepeatN;
+ #[allow(deprecated)]
+ pub use crate::sources::{RepeatCall, Unfold, Iterate};
+ pub use crate::take_while_inclusive::TakeWhileInclusive;
+ #[cfg(feature = "use_alloc")]
+ pub use crate::tee::Tee;
+ pub use crate::tuple_impl::{TupleBuffer, TupleWindows, CircularTupleWindows, Tuples};
+ #[cfg(feature = "use_std")]
+ pub use crate::duplicates_impl::{Duplicates, DuplicatesBy};
+ #[cfg(feature = "use_std")]
+ pub use crate::unique_impl::{Unique, UniqueBy};
+ pub use crate::with_position::WithPosition;
+ pub use crate::zip_eq_impl::ZipEq;
+ pub use crate::zip_longest::ZipLongest;
+ pub use crate::ziptuple::Zip;
+}
+
+/// Traits helpful for using certain `Itertools` methods in generic contexts.
+pub mod traits {
+ pub use crate::tuple_impl::HomogeneousTuple;
+}
+
+#[allow(deprecated)]
+pub use crate::structs::*;
+pub use crate::concat_impl::concat;
+pub use crate::cons_tuples_impl::cons_tuples;
+pub use crate::diff::diff_with;
+pub use crate::diff::Diff;
+#[cfg(feature = "use_alloc")]
+pub use crate::kmerge_impl::{kmerge_by};
+pub use crate::minmax::MinMaxResult;
+pub use crate::peeking_take_while::PeekingNext;
+pub use crate::process_results_impl::process_results;
+pub use crate::repeatn::repeat_n;
+#[allow(deprecated)]
+pub use crate::sources::{repeat_call, unfold, iterate};
+pub use crate::with_position::Position;
+pub use crate::unziptuple::{multiunzip, MultiUnzip};
+pub use crate::ziptuple::multizip;
+mod adaptors;
+mod either_or_both;
+pub use crate::either_or_both::EitherOrBoth;
+#[doc(hidden)]
+pub mod free;
+#[doc(inline)]
+pub use crate::free::*;
+mod concat_impl;
+mod cons_tuples_impl;
+#[cfg(feature = "use_alloc")]
+mod combinations;
+#[cfg(feature = "use_alloc")]
+mod combinations_with_replacement;
+mod exactly_one_err;
+mod diff;
+mod flatten_ok;
+#[cfg(feature = "use_std")]
+mod extrema_set;
+mod format;
+#[cfg(feature = "use_std")]
+mod grouping_map;
+#[cfg(feature = "use_alloc")]
+mod group_map;
+#[cfg(feature = "use_alloc")]
+mod groupbylazy;
+mod intersperse;
+#[cfg(feature = "use_alloc")]
+mod k_smallest;
+#[cfg(feature = "use_alloc")]
+mod kmerge_impl;
+#[cfg(feature = "use_alloc")]
+mod lazy_buffer;
+mod merge_join;
+mod minmax;
+#[cfg(feature = "use_alloc")]
+mod multipeek_impl;
+mod pad_tail;
+#[cfg(feature = "use_alloc")]
+mod peek_nth;
+mod peeking_take_while;
+#[cfg(feature = "use_alloc")]
+mod permutations;
+#[cfg(feature = "use_alloc")]
+mod powerset;
+mod process_results_impl;
+#[cfg(feature = "use_alloc")]
+mod put_back_n_impl;
+#[cfg(feature = "use_alloc")]
+mod rciter_impl;
+mod repeatn;
+mod size_hint;
+mod sources;
+mod take_while_inclusive;
+#[cfg(feature = "use_alloc")]
+mod tee;
+mod tuple_impl;
+#[cfg(feature = "use_std")]
+mod duplicates_impl;
+#[cfg(feature = "use_std")]
+mod unique_impl;
+mod unziptuple;
+mod with_position;
+mod zip_eq_impl;
+mod zip_longest;
+mod ziptuple;
+
+#[macro_export]
+/// Create an iterator over the “cartesian product” of iterators.
+///
+/// Iterator element type is like `(A, B, ..., E)` if formed
+/// from iterators `(I, J, ..., M)` with element types `I::Item = A`, `J::Item = B`, etc.
+///
+/// ```
+/// # use itertools::iproduct;
+/// #
+/// # fn main() {
+/// // Iterate over the coordinates of a 4 x 4 x 4 grid
+/// // from (0, 0, 0), (0, 0, 1), .., (0, 1, 0), (0, 1, 1), .. etc until (3, 3, 3)
+/// for (i, j, k) in iproduct!(0..4, 0..4, 0..4) {
+/// // ..
+/// }
+/// # }
+/// ```
+macro_rules! iproduct {
+ (@flatten $I:expr,) => (
+ $I
+ );
+ (@flatten $I:expr, $J:expr, $($K:expr,)*) => (
+ $crate::iproduct!(@flatten $crate::cons_tuples($crate::iproduct!($I, $J)), $($K,)*)
+ );
+ ($I:expr) => (
+ $crate::__std_iter::IntoIterator::into_iter($I)
+ );
+ ($I:expr, $J:expr) => (
+ $crate::Itertools::cartesian_product($crate::iproduct!($I), $crate::iproduct!($J))
+ );
+ ($I:expr, $J:expr, $($K:expr),+) => (
+ $crate::iproduct!(@flatten $crate::iproduct!($I, $J), $($K,)+)
+ );
+}
+
+#[macro_export]
+/// Create an iterator running multiple iterators in lockstep.
+///
+/// The `izip!` iterator yields elements until any subiterator
+/// returns `None`.
+///
+/// This is a version of the standard ``.zip()`` that's supporting more than
+/// two iterators. The iterator element type is a tuple with one element
+/// from each of the input iterators. Just like ``.zip()``, the iteration stops
+/// when the shortest of the inputs reaches its end.
+///
+/// **Note:** The result of this macro is in the general case an iterator
+/// composed of repeated `.zip()` and a `.map()`; it has an anonymous type.
+/// The special cases of one and two arguments produce the equivalent of
+/// `$a.into_iter()` and `$a.into_iter().zip($b)` respectively.
+///
+/// Prefer this macro `izip!()` over [`multizip`] for the performance benefits
+/// of using the standard library `.zip()`.
+///
+/// ```
+/// # use itertools::izip;
+/// #
+/// # fn main() {
+///
+/// // iterate over three sequences side-by-side
+/// let mut results = [0, 0, 0, 0];
+/// let inputs = [3, 7, 9, 6];
+///
+/// for (r, index, input) in izip!(&mut results, 0..10, &inputs) {
+/// *r = index * 10 + input;
+/// }
+///
+/// assert_eq!(results, [0 + 3, 10 + 7, 29, 36]);
+/// # }
+/// ```
+macro_rules! izip {
+ // @closure creates a tuple-flattening closure for .map() call. usage:
+ // @closure partial_pattern => partial_tuple , rest , of , iterators
+ // eg. izip!( @closure ((a, b), c) => (a, b, c) , dd , ee )
+ ( @closure $p:pat => $tup:expr ) => {
+ |$p| $tup
+ };
+
+ // The "b" identifier is a different identifier on each recursion level thanks to hygiene.
+ ( @closure $p:pat => ( $($tup:tt)* ) , $_iter:expr $( , $tail:expr )* ) => {
+ $crate::izip!(@closure ($p, b) => ( $($tup)*, b ) $( , $tail )*)
+ };
+
+ // unary
+ ($first:expr $(,)*) => {
+ $crate::__std_iter::IntoIterator::into_iter($first)
+ };
+
+ // binary
+ ($first:expr, $second:expr $(,)*) => {
+ $crate::izip!($first)
+ .zip($second)
+ };
+
+ // n-ary where n > 2
+ ( $first:expr $( , $rest:expr )* $(,)* ) => {
+ $crate::izip!($first)
+ $(
+ .zip($rest)
+ )*
+ .map(
+ $crate::izip!(@closure a => (a) $( , $rest )*)
+ )
+ };
+}
+
+#[macro_export]
+/// [Chain][`chain`] zero or more iterators together into one sequence.
+///
+/// The comma-separated arguments must implement [`IntoIterator`].
+/// The final argument may be followed by a trailing comma.
+///
+/// [`chain`]: Iterator::chain
+///
+/// # Examples
+///
+/// Empty invocations of `chain!` expand to an invocation of [`std::iter::empty`]:
+/// ```
+/// use std::iter;
+/// use itertools::chain;
+///
+/// let _: iter::Empty<()> = chain!();
+/// let _: iter::Empty<i8> = chain!();
+/// ```
+///
+/// Invocations of `chain!` with one argument expand to [`arg.into_iter()`](IntoIterator):
+/// ```
+/// use std::{ops::Range, slice};
+/// use itertools::chain;
+/// let _: <Range<_> as IntoIterator>::IntoIter = chain!((2..6),); // trailing comma optional!
+/// let _: <&[_] as IntoIterator>::IntoIter = chain!(&[2, 3, 4]);
+/// ```
+///
+/// Invocations of `chain!` with multiple arguments [`.into_iter()`](IntoIterator) each
+/// argument, and then [`chain`] them together:
+/// ```
+/// use std::{iter::*, ops::Range, slice};
+/// use itertools::{assert_equal, chain};
+///
+/// // e.g., this:
+/// let with_macro: Chain<Chain<Once<_>, Take<Repeat<_>>>, slice::Iter<_>> =
+/// chain![once(&0), repeat(&1).take(2), &[2, 3, 5],];
+///
+/// // ...is equivalent to this:
+/// let with_method: Chain<Chain<Once<_>, Take<Repeat<_>>>, slice::Iter<_>> =
+/// once(&0)
+/// .chain(repeat(&1).take(2))
+/// .chain(&[2, 3, 5]);
+///
+/// assert_equal(with_macro, with_method);
+/// ```
+macro_rules! chain {
+ () => {
+ core::iter::empty()
+ };
+ ($first:expr $(, $rest:expr )* $(,)?) => {
+ {
+ let iter = core::iter::IntoIterator::into_iter($first);
+ $(
+ let iter =
+ core::iter::Iterator::chain(
+ iter,
+ core::iter::IntoIterator::into_iter($rest));
+ )*
+ iter
+ }
+ };
+}
+
+/// An [`Iterator`] blanket implementation that provides extra adaptors and
+/// methods.
+///
+/// This trait defines a number of methods. They are divided into two groups:
+///
+/// * *Adaptors* take an iterator and parameter as input, and return
+/// a new iterator value. These are listed first in the trait. An example
+/// of an adaptor is [`.interleave()`](Itertools::interleave)
+///
+/// * *Regular methods* are those that don't return iterators and instead
+/// return a regular value of some other kind.
+/// [`.next_tuple()`](Itertools::next_tuple) is an example and the first regular
+/// method in the list.
+pub trait Itertools : Iterator {
+ // adaptors
+
+ /// Alternate elements from two iterators until both have run out.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// This iterator is *fused*.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let it = (1..7).interleave(vec![-1, -2]);
+ /// itertools::assert_equal(it, vec![1, -1, 2, -2, 3, 4, 5, 6]);
+ /// ```
+ fn interleave<J>(self, other: J) -> Interleave<Self, J::IntoIter>
+ where J: IntoIterator<Item = Self::Item>,
+ Self: Sized
+ {
+ interleave(self, other)
+ }
+
+ /// Alternate elements from two iterators until at least one of them has run
+ /// out.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let it = (1..7).interleave_shortest(vec![-1, -2]);
+ /// itertools::assert_equal(it, vec![1, -1, 2, -2, 3]);
+ /// ```
+ fn interleave_shortest<J>(self, other: J) -> InterleaveShortest<Self, J::IntoIter>
+ where J: IntoIterator<Item = Self::Item>,
+ Self: Sized
+ {
+ adaptors::interleave_shortest(self, other.into_iter())
+ }
+
+ /// An iterator adaptor to insert a particular value
+ /// between each element of the adapted iterator.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// This iterator is *fused*.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// itertools::assert_equal((0..3).intersperse(8), vec![0, 8, 1, 8, 2]);
+ /// ```
+ fn intersperse(self, element: Self::Item) -> Intersperse<Self>
+ where Self: Sized,
+ Self::Item: Clone
+ {
+ intersperse::intersperse(self, element)
+ }
+
+ /// An iterator adaptor to insert a particular value created by a function
+ /// between each element of the adapted iterator.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// This iterator is *fused*.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let mut i = 10;
+ /// itertools::assert_equal((0..3).intersperse_with(|| { i -= 1; i }), vec![0, 9, 1, 8, 2]);
+ /// assert_eq!(i, 8);
+ /// ```
+ fn intersperse_with<F>(self, element: F) -> IntersperseWith<Self, F>
+ where Self: Sized,
+ F: FnMut() -> Self::Item
+ {
+ intersperse::intersperse_with(self, element)
+ }
+
+ /// Create an iterator which iterates over both this and the specified
+ /// iterator simultaneously, yielding pairs of two optional elements.
+ ///
+ /// This iterator is *fused*.
+ ///
+ /// As long as neither input iterator is exhausted yet, it yields two values
+ /// via `EitherOrBoth::Both`.
+ ///
+ /// When the parameter iterator is exhausted, it only yields a value from the
+ /// `self` iterator via `EitherOrBoth::Left`.
+ ///
+ /// When the `self` iterator is exhausted, it only yields a value from the
+ /// parameter iterator via `EitherOrBoth::Right`.
+ ///
+ /// When both iterators return `None`, all further invocations of `.next()`
+ /// will return `None`.
+ ///
+ /// Iterator element type is
+ /// [`EitherOrBoth<Self::Item, J::Item>`](EitherOrBoth).
+ ///
+ /// ```rust
+ /// use itertools::EitherOrBoth::{Both, Right};
+ /// use itertools::Itertools;
+ /// let it = (0..1).zip_longest(1..3);
+ /// itertools::assert_equal(it, vec![Both(0, 1), Right(2)]);
+ /// ```
+ #[inline]
+ fn zip_longest<J>(self, other: J) -> ZipLongest<Self, J::IntoIter>
+ where J: IntoIterator,
+ Self: Sized
+ {
+ zip_longest::zip_longest(self, other.into_iter())
+ }
+
+ /// Create an iterator which iterates over both this and the specified
+ /// iterator simultaneously, yielding pairs of elements.
+ ///
+ /// **Panics** if the iterators reach an end and they are not of equal
+ /// lengths.
+ #[inline]
+ fn zip_eq<J>(self, other: J) -> ZipEq<Self, J::IntoIter>
+ where J: IntoIterator,
+ Self: Sized
+ {
+ zip_eq(self, other)
+ }
+
+ /// A “meta iterator adaptor”. Its closure receives a reference to the
+ /// iterator and may pick off as many elements as it likes, to produce the
+ /// next iterator element.
+ ///
+ /// Iterator element type is `B`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // An adaptor that gathers elements in pairs
+ /// let pit = (0..4).batching(|it| {
+ /// match it.next() {
+ /// None => None,
+ /// Some(x) => match it.next() {
+ /// None => None,
+ /// Some(y) => Some((x, y)),
+ /// }
+ /// }
+ /// });
+ ///
+ /// itertools::assert_equal(pit, vec![(0, 1), (2, 3)]);
+ /// ```
+ ///
+ fn batching<B, F>(self, f: F) -> Batching<Self, F>
+ where F: FnMut(&mut Self) -> Option<B>,
+ Self: Sized
+ {
+ adaptors::batching(self, f)
+ }
+
+ /// Return an *iterable* that can group iterator elements.
+ /// Consecutive elements that map to the same key (“runs”), are assigned
+ /// to the same group.
+ ///
+ /// `GroupBy` is the storage for the lazy grouping operation.
+ ///
+ /// If the groups are consumed in order, or if each group's iterator is
+ /// dropped without keeping it around, then `GroupBy` uses no
+ /// allocations. It needs allocations only if several group iterators
+ /// are alive at the same time.
+ ///
+ /// This type implements [`IntoIterator`] (it is **not** an iterator
+ /// itself), because the group iterators need to borrow from this
+ /// value. It should be stored in a local variable or temporary and
+ /// iterated.
+ ///
+ /// Iterator element type is `(K, Group)`: the group's key and the
+ /// group iterator.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // group data into runs of larger than zero or not.
+ /// let data = vec![1, 3, -2, -2, 1, 0, 1, 2];
+ /// // groups: |---->|------>|--------->|
+ ///
+ /// // Note: The `&` is significant here, `GroupBy` is iterable
+ /// // only by reference. You can also call `.into_iter()` explicitly.
+ /// let mut data_grouped = Vec::new();
+ /// for (key, group) in &data.into_iter().group_by(|elt| *elt >= 0) {
+ /// data_grouped.push((key, group.collect()));
+ /// }
+ /// assert_eq!(data_grouped, vec![(true, vec![1, 3]), (false, vec![-2, -2]), (true, vec![1, 0, 1, 2])]);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn group_by<K, F>(self, key: F) -> GroupBy<K, Self, F>
+ where Self: Sized,
+ F: FnMut(&Self::Item) -> K,
+ K: PartialEq,
+ {
+ groupbylazy::new(self, key)
+ }
+
+ /// Return an *iterable* that can chunk the iterator.
+ ///
+ /// Yield subiterators (chunks) that each yield a fixed number elements,
+ /// determined by `size`. The last chunk will be shorter if there aren't
+ /// enough elements.
+ ///
+ /// `IntoChunks` is based on `GroupBy`: it is iterable (implements
+ /// `IntoIterator`, **not** `Iterator`), and it only buffers if several
+ /// chunk iterators are alive at the same time.
+ ///
+ /// Iterator element type is `Chunk`, each chunk's iterator.
+ ///
+ /// **Panics** if `size` is 0.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec![1, 1, 2, -2, 6, 0, 3, 1];
+ /// //chunk size=3 |------->|-------->|--->|
+ ///
+ /// // Note: The `&` is significant here, `IntoChunks` is iterable
+ /// // only by reference. You can also call `.into_iter()` explicitly.
+ /// for chunk in &data.into_iter().chunks(3) {
+ /// // Check that the sum of each chunk is 4.
+ /// assert_eq!(4, chunk.sum());
+ /// }
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn chunks(self, size: usize) -> IntoChunks<Self>
+ where Self: Sized,
+ {
+ assert!(size != 0);
+ groupbylazy::new_chunks(self, size)
+ }
+
+ /// Return an iterator over all contiguous windows producing tuples of
+ /// a specific size (up to 12).
+ ///
+ /// `tuple_windows` clones the iterator elements so that they can be
+ /// part of successive windows, this makes it most suited for iterators
+ /// of references and other values that are cheap to copy.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// let mut v = Vec::new();
+ ///
+ /// // pairwise iteration
+ /// for (a, b) in (1..5).tuple_windows() {
+ /// v.push((a, b));
+ /// }
+ /// assert_eq!(v, vec![(1, 2), (2, 3), (3, 4)]);
+ ///
+ /// let mut it = (1..5).tuple_windows();
+ /// assert_eq!(Some((1, 2, 3)), it.next());
+ /// assert_eq!(Some((2, 3, 4)), it.next());
+ /// assert_eq!(None, it.next());
+ ///
+ /// // this requires a type hint
+ /// let it = (1..5).tuple_windows::<(_, _, _)>();
+ /// itertools::assert_equal(it, vec![(1, 2, 3), (2, 3, 4)]);
+ ///
+ /// // you can also specify the complete type
+ /// use itertools::TupleWindows;
+ /// use std::ops::Range;
+ ///
+ /// let it: TupleWindows<Range<u32>, (u32, u32, u32)> = (1..5).tuple_windows();
+ /// itertools::assert_equal(it, vec![(1, 2, 3), (2, 3, 4)]);
+ /// ```
+ fn tuple_windows<T>(self) -> TupleWindows<Self, T>
+ where Self: Sized + Iterator<Item = T::Item>,
+ T: traits::HomogeneousTuple,
+ T::Item: Clone
+ {
+ tuple_impl::tuple_windows(self)
+ }
+
+ /// Return an iterator over all windows, wrapping back to the first
+ /// elements when the window would otherwise exceed the length of the
+ /// iterator, producing tuples of a specific size (up to 12).
+ ///
+ /// `circular_tuple_windows` clones the iterator elements so that they can be
+ /// part of successive windows, this makes it most suited for iterators
+ /// of references and other values that are cheap to copy.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// let mut v = Vec::new();
+ /// for (a, b) in (1..5).circular_tuple_windows() {
+ /// v.push((a, b));
+ /// }
+ /// assert_eq!(v, vec![(1, 2), (2, 3), (3, 4), (4, 1)]);
+ ///
+ /// let mut it = (1..5).circular_tuple_windows();
+ /// assert_eq!(Some((1, 2, 3)), it.next());
+ /// assert_eq!(Some((2, 3, 4)), it.next());
+ /// assert_eq!(Some((3, 4, 1)), it.next());
+ /// assert_eq!(Some((4, 1, 2)), it.next());
+ /// assert_eq!(None, it.next());
+ ///
+ /// // this requires a type hint
+ /// let it = (1..5).circular_tuple_windows::<(_, _, _)>();
+ /// itertools::assert_equal(it, vec![(1, 2, 3), (2, 3, 4), (3, 4, 1), (4, 1, 2)]);
+ /// ```
+ fn circular_tuple_windows<T>(self) -> CircularTupleWindows<Self, T>
+ where Self: Sized + Clone + Iterator<Item = T::Item> + ExactSizeIterator,
+ T: tuple_impl::TupleCollect + Clone,
+ T::Item: Clone
+ {
+ tuple_impl::circular_tuple_windows(self)
+ }
+ /// Return an iterator that groups the items in tuples of a specific size
+ /// (up to 12).
+ ///
+ /// See also the method [`.next_tuple()`](Itertools::next_tuple).
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// let mut v = Vec::new();
+ /// for (a, b) in (1..5).tuples() {
+ /// v.push((a, b));
+ /// }
+ /// assert_eq!(v, vec![(1, 2), (3, 4)]);
+ ///
+ /// let mut it = (1..7).tuples();
+ /// assert_eq!(Some((1, 2, 3)), it.next());
+ /// assert_eq!(Some((4, 5, 6)), it.next());
+ /// assert_eq!(None, it.next());
+ ///
+ /// // this requires a type hint
+ /// let it = (1..7).tuples::<(_, _, _)>();
+ /// itertools::assert_equal(it, vec![(1, 2, 3), (4, 5, 6)]);
+ ///
+ /// // you can also specify the complete type
+ /// use itertools::Tuples;
+ /// use std::ops::Range;
+ ///
+ /// let it: Tuples<Range<u32>, (u32, u32, u32)> = (1..7).tuples();
+ /// itertools::assert_equal(it, vec![(1, 2, 3), (4, 5, 6)]);
+ /// ```
+ ///
+ /// See also [`Tuples::into_buffer`].
+ fn tuples<T>(self) -> Tuples<Self, T>
+ where Self: Sized + Iterator<Item = T::Item>,
+ T: traits::HomogeneousTuple
+ {
+ tuple_impl::tuples(self)
+ }
+
+ /// Split into an iterator pair that both yield all elements from
+ /// the original iterator.
+ ///
+ /// **Note:** If the iterator is clonable, prefer using that instead
+ /// of using this method. Cloning is likely to be more efficient.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// let xs = vec![0, 1, 2, 3];
+ ///
+ /// let (mut t1, t2) = xs.into_iter().tee();
+ /// itertools::assert_equal(t1.next(), Some(0));
+ /// itertools::assert_equal(t2, 0..4);
+ /// itertools::assert_equal(t1, 1..4);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn tee(self) -> (Tee<Self>, Tee<Self>)
+ where Self: Sized,
+ Self::Item: Clone
+ {
+ tee::new(self)
+ }
+
+ /// Return an iterator adaptor that steps `n` elements in the base iterator
+ /// for each iteration.
+ ///
+ /// The iterator steps by yielding the next element from the base iterator,
+ /// then skipping forward `n - 1` elements.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// **Panics** if the step is 0.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let it = (0..8).step(3);
+ /// itertools::assert_equal(it, vec![0, 3, 6]);
+ /// ```
+ #[deprecated(note="Use std .step_by() instead", since="0.8.0")]
+ #[allow(deprecated)]
+ fn step(self, n: usize) -> Step<Self>
+ where Self: Sized
+ {
+ adaptors::step(self, n)
+ }
+
+ /// Convert each item of the iterator using the [`Into`] trait.
+ ///
+ /// ```rust
+ /// use itertools::Itertools;
+ ///
+ /// (1i32..42i32).map_into::<f64>().collect_vec();
+ /// ```
+ fn map_into<R>(self) -> MapInto<Self, R>
+ where Self: Sized,
+ Self::Item: Into<R>,
+ {
+ adaptors::map_into(self)
+ }
+
+ /// See [`.map_ok()`](Itertools::map_ok).
+ #[deprecated(note="Use .map_ok() instead", since="0.10.0")]
+ fn map_results<F, T, U, E>(self, f: F) -> MapOk<Self, F>
+ where Self: Iterator<Item = Result<T, E>> + Sized,
+ F: FnMut(T) -> U,
+ {
+ self.map_ok(f)
+ }
+
+ /// Return an iterator adaptor that applies the provided closure
+ /// to every `Result::Ok` value. `Result::Err` values are
+ /// unchanged.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let input = vec![Ok(41), Err(false), Ok(11)];
+ /// let it = input.into_iter().map_ok(|i| i + 1);
+ /// itertools::assert_equal(it, vec![Ok(42), Err(false), Ok(12)]);
+ /// ```
+ fn map_ok<F, T, U, E>(self, f: F) -> MapOk<Self, F>
+ where Self: Iterator<Item = Result<T, E>> + Sized,
+ F: FnMut(T) -> U,
+ {
+ adaptors::map_ok(self, f)
+ }
+
+ /// Return an iterator adaptor that filters every `Result::Ok`
+ /// value with the provided closure. `Result::Err` values are
+ /// unchanged.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let input = vec![Ok(22), Err(false), Ok(11)];
+ /// let it = input.into_iter().filter_ok(|&i| i > 20);
+ /// itertools::assert_equal(it, vec![Ok(22), Err(false)]);
+ /// ```
+ fn filter_ok<F, T, E>(self, f: F) -> FilterOk<Self, F>
+ where Self: Iterator<Item = Result<T, E>> + Sized,
+ F: FnMut(&T) -> bool,
+ {
+ adaptors::filter_ok(self, f)
+ }
+
+ /// Return an iterator adaptor that filters and transforms every
+ /// `Result::Ok` value with the provided closure. `Result::Err`
+ /// values are unchanged.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let input = vec![Ok(22), Err(false), Ok(11)];
+ /// let it = input.into_iter().filter_map_ok(|i| if i > 20 { Some(i * 2) } else { None });
+ /// itertools::assert_equal(it, vec![Ok(44), Err(false)]);
+ /// ```
+ fn filter_map_ok<F, T, U, E>(self, f: F) -> FilterMapOk<Self, F>
+ where Self: Iterator<Item = Result<T, E>> + Sized,
+ F: FnMut(T) -> Option<U>,
+ {
+ adaptors::filter_map_ok(self, f)
+ }
+
+ /// Return an iterator adaptor that flattens every `Result::Ok` value into
+ /// a series of `Result::Ok` values. `Result::Err` values are unchanged.
+ ///
+ /// This is useful when you have some common error type for your crate and
+ /// need to propagate it upwards, but the `Result::Ok` case needs to be flattened.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let input = vec![Ok(0..2), Err(false), Ok(2..4)];
+ /// let it = input.iter().cloned().flatten_ok();
+ /// itertools::assert_equal(it.clone(), vec![Ok(0), Ok(1), Err(false), Ok(2), Ok(3)]);
+ ///
+ /// // This can also be used to propagate errors when collecting.
+ /// let output_result: Result<Vec<i32>, bool> = it.collect();
+ /// assert_eq!(output_result, Err(false));
+ /// ```
+ fn flatten_ok<T, E>(self) -> FlattenOk<Self, T, E>
+ where Self: Iterator<Item = Result<T, E>> + Sized,
+ T: IntoIterator
+ {
+ flatten_ok::flatten_ok(self)
+ }
+
+ /// “Lift” a function of the values of the current iterator so as to process
+ /// an iterator of `Result` values instead.
+ ///
+ /// `processor` is a closure that receives an adapted version of the iterator
+ /// as the only argument — the adapted iterator produces elements of type `T`,
+ /// as long as the original iterator produces `Ok` values.
+ ///
+ /// If the original iterable produces an error at any point, the adapted
+ /// iterator ends and it will return the error iself.
+ ///
+ /// Otherwise, the return value from the closure is returned wrapped
+ /// inside `Ok`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// type Item = Result<i32, &'static str>;
+ ///
+ /// let first_values: Vec<Item> = vec![Ok(1), Ok(0), Ok(3)];
+ /// let second_values: Vec<Item> = vec![Ok(2), Ok(1), Err("overflow")];
+ ///
+ /// // “Lift” the iterator .max() method to work on the Ok-values.
+ /// let first_max = first_values.into_iter().process_results(|iter| iter.max().unwrap_or(0));
+ /// let second_max = second_values.into_iter().process_results(|iter| iter.max().unwrap_or(0));
+ ///
+ /// assert_eq!(first_max, Ok(3));
+ /// assert!(second_max.is_err());
+ /// ```
+ fn process_results<F, T, E, R>(self, processor: F) -> Result<R, E>
+ where Self: Iterator<Item = Result<T, E>> + Sized,
+ F: FnOnce(ProcessResults<Self, E>) -> R
+ {
+ process_results(self, processor)
+ }
+
+ /// Return an iterator adaptor that merges the two base iterators in
+ /// ascending order. If both base iterators are sorted (ascending), the
+ /// result is sorted.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a = (0..11).step_by(3);
+ /// let b = (0..11).step_by(5);
+ /// let it = a.merge(b);
+ /// itertools::assert_equal(it, vec![0, 0, 3, 5, 6, 9, 10]);
+ /// ```
+ fn merge<J>(self, other: J) -> Merge<Self, J::IntoIter>
+ where Self: Sized,
+ Self::Item: PartialOrd,
+ J: IntoIterator<Item = Self::Item>
+ {
+ merge(self, other)
+ }
+
+ /// Return an iterator adaptor that merges the two base iterators in order.
+ /// This is much like [`.merge()`](Itertools::merge) but allows for a custom ordering.
+ ///
+ /// This can be especially useful for sequences of tuples.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a = (0..).zip("bc".chars());
+ /// let b = (0..).zip("ad".chars());
+ /// let it = a.merge_by(b, |x, y| x.1 <= y.1);
+ /// itertools::assert_equal(it, vec![(0, 'a'), (0, 'b'), (1, 'c'), (1, 'd')]);
+ /// ```
+
+ fn merge_by<J, F>(self, other: J, is_first: F) -> MergeBy<Self, J::IntoIter, F>
+ where Self: Sized,
+ J: IntoIterator<Item = Self::Item>,
+ F: FnMut(&Self::Item, &Self::Item) -> bool
+ {
+ adaptors::merge_by_new(self, other.into_iter(), is_first)
+ }
+
+ /// Create an iterator that merges items from both this and the specified
+ /// iterator in ascending order.
+ ///
+ /// The function can either return an `Ordering` variant or a boolean.
+ ///
+ /// If `cmp_fn` returns `Ordering`,
+ /// it chooses whether to pair elements based on the `Ordering` returned by the
+ /// specified compare function. At any point, inspecting the tip of the
+ /// iterators `I` and `J` as items `i` of type `I::Item` and `j` of type
+ /// `J::Item` respectively, the resulting iterator will:
+ ///
+ /// - Emit `EitherOrBoth::Left(i)` when `i < j`,
+ /// and remove `i` from its source iterator
+ /// - Emit `EitherOrBoth::Right(j)` when `i > j`,
+ /// and remove `j` from its source iterator
+ /// - Emit `EitherOrBoth::Both(i, j)` when `i == j`,
+ /// and remove both `i` and `j` from their respective source iterators
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// use itertools::EitherOrBoth::{Left, Right, Both};
+ ///
+ /// let a = vec![0, 2, 4, 6, 1].into_iter();
+ /// let b = (0..10).step_by(3);
+ ///
+ /// itertools::assert_equal(
+ /// a.merge_join_by(b, |i, j| i.cmp(j)),
+ /// vec![Both(0, 0), Left(2), Right(3), Left(4), Both(6, 6), Left(1), Right(9)]
+ /// );
+ /// ```
+ ///
+ /// If `cmp_fn` returns `bool`,
+ /// it chooses whether to pair elements based on the boolean returned by the
+ /// specified function. At any point, inspecting the tip of the
+ /// iterators `I` and `J` as items `i` of type `I::Item` and `j` of type
+ /// `J::Item` respectively, the resulting iterator will:
+ ///
+ /// - Emit `Either::Left(i)` when `true`,
+ /// and remove `i` from its source iterator
+ /// - Emit `Either::Right(j)` when `false`,
+ /// and remove `j` from its source iterator
+ ///
+ /// It is similar to the `Ordering` case if the first argument is considered
+ /// "less" than the second argument.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// use itertools::Either::{Left, Right};
+ ///
+ /// let a = vec![0, 2, 4, 6, 1].into_iter();
+ /// let b = (0..10).step_by(3);
+ ///
+ /// itertools::assert_equal(
+ /// a.merge_join_by(b, |i, j| i <= j),
+ /// vec![Left(0), Right(0), Left(2), Right(3), Left(4), Left(6), Left(1), Right(6), Right(9)]
+ /// );
+ /// ```
+ #[inline]
+ fn merge_join_by<J, F, T>(self, other: J, cmp_fn: F) -> MergeJoinBy<Self, J::IntoIter, F>
+ where J: IntoIterator,
+ F: FnMut(&Self::Item, &J::Item) -> T,
+ T: merge_join::OrderingOrBool<Self::Item, J::Item>,
+ Self: Sized
+ {
+ merge_join_by(self, other, cmp_fn)
+ }
+
+ /// Return an iterator adaptor that flattens an iterator of iterators by
+ /// merging them in ascending order.
+ ///
+ /// If all base iterators are sorted (ascending), the result is sorted.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a = (0..6).step_by(3);
+ /// let b = (1..6).step_by(3);
+ /// let c = (2..6).step_by(3);
+ /// let it = vec![a, b, c].into_iter().kmerge();
+ /// itertools::assert_equal(it, vec![0, 1, 2, 3, 4, 5]);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn kmerge(self) -> KMerge<<Self::Item as IntoIterator>::IntoIter>
+ where Self: Sized,
+ Self::Item: IntoIterator,
+ <Self::Item as IntoIterator>::Item: PartialOrd,
+ {
+ kmerge(self)
+ }
+
+ /// Return an iterator adaptor that flattens an iterator of iterators by
+ /// merging them according to the given closure.
+ ///
+ /// The closure `first` is called with two elements *a*, *b* and should
+ /// return `true` if *a* is ordered before *b*.
+ ///
+ /// If all base iterators are sorted according to `first`, the result is
+ /// sorted.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a = vec![-1f64, 2., 3., -5., 6., -7.];
+ /// let b = vec![0., 2., -4.];
+ /// let mut it = vec![a, b].into_iter().kmerge_by(|a, b| a.abs() < b.abs());
+ /// assert_eq!(it.next(), Some(0.));
+ /// assert_eq!(it.last(), Some(-7.));
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn kmerge_by<F>(self, first: F)
+ -> KMergeBy<<Self::Item as IntoIterator>::IntoIter, F>
+ where Self: Sized,
+ Self::Item: IntoIterator,
+ F: FnMut(&<Self::Item as IntoIterator>::Item,
+ &<Self::Item as IntoIterator>::Item) -> bool
+ {
+ kmerge_by(self, first)
+ }
+
+ /// Return an iterator adaptor that iterates over the cartesian product of
+ /// the element sets of two iterators `self` and `J`.
+ ///
+ /// Iterator element type is `(Self::Item, J::Item)`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let it = (0..2).cartesian_product("αβ".chars());
+ /// itertools::assert_equal(it, vec![(0, 'α'), (0, 'β'), (1, 'α'), (1, 'β')]);
+ /// ```
+ fn cartesian_product<J>(self, other: J) -> Product<Self, J::IntoIter>
+ where Self: Sized,
+ Self::Item: Clone,
+ J: IntoIterator,
+ J::IntoIter: Clone
+ {
+ adaptors::cartesian_product(self, other.into_iter())
+ }
+
+ /// Return an iterator adaptor that iterates over the cartesian product of
+ /// all subiterators returned by meta-iterator `self`.
+ ///
+ /// All provided iterators must yield the same `Item` type. To generate
+ /// the product of iterators yielding multiple types, use the
+ /// [`iproduct`] macro instead.
+ ///
+ ///
+ /// The iterator element type is `Vec<T>`, where `T` is the iterator element
+ /// of the subiterators.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// let mut multi_prod = (0..3).map(|i| (i * 2)..(i * 2 + 2))
+ /// .multi_cartesian_product();
+ /// assert_eq!(multi_prod.next(), Some(vec![0, 2, 4]));
+ /// assert_eq!(multi_prod.next(), Some(vec![0, 2, 5]));
+ /// assert_eq!(multi_prod.next(), Some(vec![0, 3, 4]));
+ /// assert_eq!(multi_prod.next(), Some(vec![0, 3, 5]));
+ /// assert_eq!(multi_prod.next(), Some(vec![1, 2, 4]));
+ /// assert_eq!(multi_prod.next(), Some(vec![1, 2, 5]));
+ /// assert_eq!(multi_prod.next(), Some(vec![1, 3, 4]));
+ /// assert_eq!(multi_prod.next(), Some(vec![1, 3, 5]));
+ /// assert_eq!(multi_prod.next(), None);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn multi_cartesian_product(self) -> MultiProduct<<Self::Item as IntoIterator>::IntoIter>
+ where Self: Sized,
+ Self::Item: IntoIterator,
+ <Self::Item as IntoIterator>::IntoIter: Clone,
+ <Self::Item as IntoIterator>::Item: Clone
+ {
+ adaptors::multi_cartesian_product(self)
+ }
+
+ /// Return an iterator adaptor that uses the passed-in closure to
+ /// optionally merge together consecutive elements.
+ ///
+ /// The closure `f` is passed two elements, `previous` and `current` and may
+ /// return either (1) `Ok(combined)` to merge the two values or
+ /// (2) `Err((previous', current'))` to indicate they can't be merged.
+ /// In (2), the value `previous'` is emitted by the iterator.
+ /// Either (1) `combined` or (2) `current'` becomes the previous value
+ /// when coalesce continues with the next pair of elements to merge. The
+ /// value that remains at the end is also emitted by the iterator.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// This iterator is *fused*.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // sum same-sign runs together
+ /// let data = vec![-1., -2., -3., 3., 1., 0., -1.];
+ /// itertools::assert_equal(data.into_iter().coalesce(|x, y|
+ /// if (x >= 0.) == (y >= 0.) {
+ /// Ok(x + y)
+ /// } else {
+ /// Err((x, y))
+ /// }),
+ /// vec![-6., 4., -1.]);
+ /// ```
+ fn coalesce<F>(self, f: F) -> Coalesce<Self, F>
+ where Self: Sized,
+ F: FnMut(Self::Item, Self::Item)
+ -> Result<Self::Item, (Self::Item, Self::Item)>
+ {
+ adaptors::coalesce(self, f)
+ }
+
+ /// Remove duplicates from sections of consecutive identical elements.
+ /// If the iterator is sorted, all elements will be unique.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// This iterator is *fused*.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec![1., 1., 2., 3., 3., 2., 2.];
+ /// itertools::assert_equal(data.into_iter().dedup(),
+ /// vec![1., 2., 3., 2.]);
+ /// ```
+ fn dedup(self) -> Dedup<Self>
+ where Self: Sized,
+ Self::Item: PartialEq,
+ {
+ adaptors::dedup(self)
+ }
+
+ /// Remove duplicates from sections of consecutive identical elements,
+ /// determining equality using a comparison function.
+ /// If the iterator is sorted, all elements will be unique.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// This iterator is *fused*.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec![(0, 1.), (1, 1.), (0, 2.), (0, 3.), (1, 3.), (1, 2.), (2, 2.)];
+ /// itertools::assert_equal(data.into_iter().dedup_by(|x, y| x.1 == y.1),
+ /// vec![(0, 1.), (0, 2.), (0, 3.), (1, 2.)]);
+ /// ```
+ fn dedup_by<Cmp>(self, cmp: Cmp) -> DedupBy<Self, Cmp>
+ where Self: Sized,
+ Cmp: FnMut(&Self::Item, &Self::Item)->bool,
+ {
+ adaptors::dedup_by(self, cmp)
+ }
+
+ /// Remove duplicates from sections of consecutive identical elements, while keeping a count of
+ /// how many repeated elements were present.
+ /// If the iterator is sorted, all elements will be unique.
+ ///
+ /// Iterator element type is `(usize, Self::Item)`.
+ ///
+ /// This iterator is *fused*.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec!['a', 'a', 'b', 'c', 'c', 'b', 'b'];
+ /// itertools::assert_equal(data.into_iter().dedup_with_count(),
+ /// vec![(2, 'a'), (1, 'b'), (2, 'c'), (2, 'b')]);
+ /// ```
+ fn dedup_with_count(self) -> DedupWithCount<Self>
+ where
+ Self: Sized,
+ {
+ adaptors::dedup_with_count(self)
+ }
+
+ /// Remove duplicates from sections of consecutive identical elements, while keeping a count of
+ /// how many repeated elements were present.
+ /// This will determine equality using a comparison function.
+ /// If the iterator is sorted, all elements will be unique.
+ ///
+ /// Iterator element type is `(usize, Self::Item)`.
+ ///
+ /// This iterator is *fused*.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec![(0, 'a'), (1, 'a'), (0, 'b'), (0, 'c'), (1, 'c'), (1, 'b'), (2, 'b')];
+ /// itertools::assert_equal(data.into_iter().dedup_by_with_count(|x, y| x.1 == y.1),
+ /// vec![(2, (0, 'a')), (1, (0, 'b')), (2, (0, 'c')), (2, (1, 'b'))]);
+ /// ```
+ fn dedup_by_with_count<Cmp>(self, cmp: Cmp) -> DedupByWithCount<Self, Cmp>
+ where
+ Self: Sized,
+ Cmp: FnMut(&Self::Item, &Self::Item) -> bool,
+ {
+ adaptors::dedup_by_with_count(self, cmp)
+ }
+
+ /// Return an iterator adaptor that produces elements that appear more than once during the
+ /// iteration. Duplicates are detected using hash and equality.
+ ///
+ /// The iterator is stable, returning the duplicate items in the order in which they occur in
+ /// the adapted iterator. Each duplicate item is returned exactly once. If an item appears more
+ /// than twice, the second item is the item retained and the rest are discarded.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec![10, 20, 30, 20, 40, 10, 50];
+ /// itertools::assert_equal(data.into_iter().duplicates(),
+ /// vec![20, 10]);
+ /// ```
+ #[cfg(feature = "use_std")]
+ fn duplicates(self) -> Duplicates<Self>
+ where Self: Sized,
+ Self::Item: Eq + Hash
+ {
+ duplicates_impl::duplicates(self)
+ }
+
+ /// Return an iterator adaptor that produces elements that appear more than once during the
+ /// iteration. Duplicates are detected using hash and equality.
+ ///
+ /// Duplicates are detected by comparing the key they map to with the keying function `f` by
+ /// hash and equality. The keys are stored in a hash map in the iterator.
+ ///
+ /// The iterator is stable, returning the duplicate items in the order in which they occur in
+ /// the adapted iterator. Each duplicate item is returned exactly once. If an item appears more
+ /// than twice, the second item is the item retained and the rest are discarded.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec!["a", "bb", "aa", "c", "ccc"];
+ /// itertools::assert_equal(data.into_iter().duplicates_by(|s| s.len()),
+ /// vec!["aa", "c"]);
+ /// ```
+ #[cfg(feature = "use_std")]
+ fn duplicates_by<V, F>(self, f: F) -> DuplicatesBy<Self, V, F>
+ where Self: Sized,
+ V: Eq + Hash,
+ F: FnMut(&Self::Item) -> V
+ {
+ duplicates_impl::duplicates_by(self, f)
+ }
+
+ /// Return an iterator adaptor that filters out elements that have
+ /// already been produced once during the iteration. Duplicates
+ /// are detected using hash and equality.
+ ///
+ /// Clones of visited elements are stored in a hash set in the
+ /// iterator.
+ ///
+ /// The iterator is stable, returning the non-duplicate items in the order
+ /// in which they occur in the adapted iterator. In a set of duplicate
+ /// items, the first item encountered is the item retained.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec![10, 20, 30, 20, 40, 10, 50];
+ /// itertools::assert_equal(data.into_iter().unique(),
+ /// vec![10, 20, 30, 40, 50]);
+ /// ```
+ #[cfg(feature = "use_std")]
+ fn unique(self) -> Unique<Self>
+ where Self: Sized,
+ Self::Item: Clone + Eq + Hash
+ {
+ unique_impl::unique(self)
+ }
+
+ /// Return an iterator adaptor that filters out elements that have
+ /// already been produced once during the iteration.
+ ///
+ /// Duplicates are detected by comparing the key they map to
+ /// with the keying function `f` by hash and equality.
+ /// The keys are stored in a hash set in the iterator.
+ ///
+ /// The iterator is stable, returning the non-duplicate items in the order
+ /// in which they occur in the adapted iterator. In a set of duplicate
+ /// items, the first item encountered is the item retained.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec!["a", "bb", "aa", "c", "ccc"];
+ /// itertools::assert_equal(data.into_iter().unique_by(|s| s.len()),
+ /// vec!["a", "bb", "ccc"]);
+ /// ```
+ #[cfg(feature = "use_std")]
+ fn unique_by<V, F>(self, f: F) -> UniqueBy<Self, V, F>
+ where Self: Sized,
+ V: Eq + Hash,
+ F: FnMut(&Self::Item) -> V
+ {
+ unique_impl::unique_by(self, f)
+ }
+
+ /// Return an iterator adaptor that borrows from this iterator and
+ /// takes items while the closure `accept` returns `true`.
+ ///
+ /// This adaptor can only be used on iterators that implement `PeekingNext`
+ /// like `.peekable()`, `put_back` and a few other collection iterators.
+ ///
+ /// The last and rejected element (first `false`) is still available when
+ /// `peeking_take_while` is done.
+ ///
+ ///
+ /// See also [`.take_while_ref()`](Itertools::take_while_ref)
+ /// which is a similar adaptor.
+ fn peeking_take_while<F>(&mut self, accept: F) -> PeekingTakeWhile<Self, F>
+ where Self: Sized + PeekingNext,
+ F: FnMut(&Self::Item) -> bool,
+ {
+ peeking_take_while::peeking_take_while(self, accept)
+ }
+
+ /// Return an iterator adaptor that borrows from a `Clone`-able iterator
+ /// to only pick off elements while the predicate `accept` returns `true`.
+ ///
+ /// It uses the `Clone` trait to restore the original iterator so that the
+ /// last and rejected element (first `false`) is still available when
+ /// `take_while_ref` is done.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let mut hexadecimals = "0123456789abcdef".chars();
+ ///
+ /// let decimals = hexadecimals.take_while_ref(|c| c.is_numeric())
+ /// .collect::<String>();
+ /// assert_eq!(decimals, "0123456789");
+ /// assert_eq!(hexadecimals.next(), Some('a'));
+ ///
+ /// ```
+ fn take_while_ref<F>(&mut self, accept: F) -> TakeWhileRef<Self, F>
+ where Self: Clone,
+ F: FnMut(&Self::Item) -> bool
+ {
+ adaptors::take_while_ref(self, accept)
+ }
+
+ /// Returns an iterator adaptor that consumes elements while the given
+ /// predicate is `true`, *including* the element for which the predicate
+ /// first returned `false`.
+ ///
+ /// The [`.take_while()`][std::iter::Iterator::take_while] adaptor is useful
+ /// when you want items satisfying a predicate, but to know when to stop
+ /// taking elements, we have to consume that first element that doesn't
+ /// satisfy the predicate. This adaptor includes that element where
+ /// [`.take_while()`][std::iter::Iterator::take_while] would drop it.
+ ///
+ /// The [`.take_while_ref()`][crate::Itertools::take_while_ref] adaptor
+ /// serves a similar purpose, but this adaptor doesn't require [`Clone`]ing
+ /// the underlying elements.
+ ///
+ /// ```rust
+ /// # use itertools::Itertools;
+ /// let items = vec![1, 2, 3, 4, 5];
+ /// let filtered: Vec<_> = items
+ /// .into_iter()
+ /// .take_while_inclusive(|&n| n % 3 != 0)
+ /// .collect();
+ ///
+ /// assert_eq!(filtered, vec![1, 2, 3]);
+ /// ```
+ ///
+ /// ```rust
+ /// # use itertools::Itertools;
+ /// let items = vec![1, 2, 3, 4, 5];
+ ///
+ /// let take_while_inclusive_result: Vec<_> = items
+ /// .iter()
+ /// .copied()
+ /// .take_while_inclusive(|&n| n % 3 != 0)
+ /// .collect();
+ /// let take_while_result: Vec<_> = items
+ /// .into_iter()
+ /// .take_while(|&n| n % 3 != 0)
+ /// .collect();
+ ///
+ /// assert_eq!(take_while_inclusive_result, vec![1, 2, 3]);
+ /// assert_eq!(take_while_result, vec![1, 2]);
+ /// // both iterators have the same items remaining at this point---the 3
+ /// // is lost from the `take_while` vec
+ /// ```
+ ///
+ /// ```rust
+ /// # use itertools::Itertools;
+ /// #[derive(Debug, PartialEq)]
+ /// struct NoCloneImpl(i32);
+ ///
+ /// let non_clonable_items: Vec<_> = vec![1, 2, 3, 4, 5]
+ /// .into_iter()
+ /// .map(NoCloneImpl)
+ /// .collect();
+ /// let filtered: Vec<_> = non_clonable_items
+ /// .into_iter()
+ /// .take_while_inclusive(|n| n.0 % 3 != 0)
+ /// .collect();
+ /// let expected: Vec<_> = vec![1, 2, 3].into_iter().map(NoCloneImpl).collect();
+ /// assert_eq!(filtered, expected);
+ fn take_while_inclusive<F>(&mut self, accept: F) -> TakeWhileInclusive<Self, F>
+ where
+ Self: Sized,
+ F: FnMut(&Self::Item) -> bool,
+ {
+ take_while_inclusive::TakeWhileInclusive::new(self, accept)
+ }
+
+ /// Return an iterator adaptor that filters `Option<A>` iterator elements
+ /// and produces `A`. Stops on the first `None` encountered.
+ ///
+ /// Iterator element type is `A`, the unwrapped element.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // List all hexadecimal digits
+ /// itertools::assert_equal(
+ /// (0..).map(|i| std::char::from_digit(i, 16)).while_some(),
+ /// "0123456789abcdef".chars());
+ ///
+ /// ```
+ fn while_some<A>(self) -> WhileSome<Self>
+ where Self: Sized + Iterator<Item = Option<A>>
+ {
+ adaptors::while_some(self)
+ }
+
+ /// Return an iterator adaptor that iterates over the combinations of the
+ /// elements from an iterator.
+ ///
+ /// Iterator element can be any homogeneous tuple of type `Self::Item` with
+ /// size up to 12.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let mut v = Vec::new();
+ /// for (a, b) in (1..5).tuple_combinations() {
+ /// v.push((a, b));
+ /// }
+ /// assert_eq!(v, vec![(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]);
+ ///
+ /// let mut it = (1..5).tuple_combinations();
+ /// assert_eq!(Some((1, 2, 3)), it.next());
+ /// assert_eq!(Some((1, 2, 4)), it.next());
+ /// assert_eq!(Some((1, 3, 4)), it.next());
+ /// assert_eq!(Some((2, 3, 4)), it.next());
+ /// assert_eq!(None, it.next());
+ ///
+ /// // this requires a type hint
+ /// let it = (1..5).tuple_combinations::<(_, _, _)>();
+ /// itertools::assert_equal(it, vec![(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]);
+ ///
+ /// // you can also specify the complete type
+ /// use itertools::TupleCombinations;
+ /// use std::ops::Range;
+ ///
+ /// let it: TupleCombinations<Range<u32>, (u32, u32, u32)> = (1..5).tuple_combinations();
+ /// itertools::assert_equal(it, vec![(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]);
+ /// ```
+ fn tuple_combinations<T>(self) -> TupleCombinations<Self, T>
+ where Self: Sized + Clone,
+ Self::Item: Clone,
+ T: adaptors::HasCombination<Self>,
+ {
+ adaptors::tuple_combinations(self)
+ }
+
+ /// Return an iterator adaptor that iterates over the `k`-length combinations of
+ /// the elements from an iterator.
+ ///
+ /// Iterator element type is `Vec<Self::Item>`. The iterator produces a new Vec per iteration,
+ /// and clones the iterator elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let it = (1..5).combinations(3);
+ /// itertools::assert_equal(it, vec![
+ /// vec![1, 2, 3],
+ /// vec![1, 2, 4],
+ /// vec![1, 3, 4],
+ /// vec![2, 3, 4],
+ /// ]);
+ /// ```
+ ///
+ /// Note: Combinations does not take into account the equality of the iterated values.
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let it = vec![1, 2, 2].into_iter().combinations(2);
+ /// itertools::assert_equal(it, vec![
+ /// vec![1, 2], // Note: these are the same
+ /// vec![1, 2], // Note: these are the same
+ /// vec![2, 2],
+ /// ]);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn combinations(self, k: usize) -> Combinations<Self>
+ where Self: Sized,
+ Self::Item: Clone
+ {
+ combinations::combinations(self, k)
+ }
+
+ /// Return an iterator that iterates over the `k`-length combinations of
+ /// the elements from an iterator, with replacement.
+ ///
+ /// Iterator element type is `Vec<Self::Item>`. The iterator produces a new Vec per iteration,
+ /// and clones the iterator elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let it = (1..4).combinations_with_replacement(2);
+ /// itertools::assert_equal(it, vec![
+ /// vec![1, 1],
+ /// vec![1, 2],
+ /// vec![1, 3],
+ /// vec![2, 2],
+ /// vec![2, 3],
+ /// vec![3, 3],
+ /// ]);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn combinations_with_replacement(self, k: usize) -> CombinationsWithReplacement<Self>
+ where
+ Self: Sized,
+ Self::Item: Clone,
+ {
+ combinations_with_replacement::combinations_with_replacement(self, k)
+ }
+
+ /// Return an iterator adaptor that iterates over all k-permutations of the
+ /// elements from an iterator.
+ ///
+ /// Iterator element type is `Vec<Self::Item>` with length `k`. The iterator
+ /// produces a new Vec per iteration, and clones the iterator elements.
+ ///
+ /// If `k` is greater than the length of the input iterator, the resultant
+ /// iterator adaptor will be empty.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let perms = (5..8).permutations(2);
+ /// itertools::assert_equal(perms, vec![
+ /// vec![5, 6],
+ /// vec![5, 7],
+ /// vec![6, 5],
+ /// vec![6, 7],
+ /// vec![7, 5],
+ /// vec![7, 6],
+ /// ]);
+ /// ```
+ ///
+ /// Note: Permutations does not take into account the equality of the iterated values.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let it = vec![2, 2].into_iter().permutations(2);
+ /// itertools::assert_equal(it, vec![
+ /// vec![2, 2], // Note: these are the same
+ /// vec![2, 2], // Note: these are the same
+ /// ]);
+ /// ```
+ ///
+ /// Note: The source iterator is collected lazily, and will not be
+ /// re-iterated if the permutations adaptor is completed and re-iterated.
+ #[cfg(feature = "use_alloc")]
+ fn permutations(self, k: usize) -> Permutations<Self>
+ where Self: Sized,
+ Self::Item: Clone
+ {
+ permutations::permutations(self, k)
+ }
+
+ /// Return an iterator that iterates through the powerset of the elements from an
+ /// iterator.
+ ///
+ /// Iterator element type is `Vec<Self::Item>`. The iterator produces a new `Vec`
+ /// per iteration, and clones the iterator elements.
+ ///
+ /// The powerset of a set contains all subsets including the empty set and the full
+ /// input set. A powerset has length _2^n_ where _n_ is the length of the input
+ /// set.
+ ///
+ /// Each `Vec` produced by this iterator represents a subset of the elements
+ /// produced by the source iterator.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let sets = (1..4).powerset().collect::<Vec<_>>();
+ /// itertools::assert_equal(sets, vec![
+ /// vec![],
+ /// vec![1],
+ /// vec![2],
+ /// vec![3],
+ /// vec![1, 2],
+ /// vec![1, 3],
+ /// vec![2, 3],
+ /// vec![1, 2, 3],
+ /// ]);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn powerset(self) -> Powerset<Self>
+ where Self: Sized,
+ Self::Item: Clone,
+ {
+ powerset::powerset(self)
+ }
+
+ /// Return an iterator adaptor that pads the sequence to a minimum length of
+ /// `min` by filling missing elements using a closure `f`.
+ ///
+ /// Iterator element type is `Self::Item`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let it = (0..5).pad_using(10, |i| 2*i);
+ /// itertools::assert_equal(it, vec![0, 1, 2, 3, 4, 10, 12, 14, 16, 18]);
+ ///
+ /// let it = (0..10).pad_using(5, |i| 2*i);
+ /// itertools::assert_equal(it, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+ ///
+ /// let it = (0..5).pad_using(10, |i| 2*i).rev();
+ /// itertools::assert_equal(it, vec![18, 16, 14, 12, 10, 4, 3, 2, 1, 0]);
+ /// ```
+ fn pad_using<F>(self, min: usize, f: F) -> PadUsing<Self, F>
+ where Self: Sized,
+ F: FnMut(usize) -> Self::Item
+ {
+ pad_tail::pad_using(self, min, f)
+ }
+
+ /// Return an iterator adaptor that combines each element with a `Position` to
+ /// ease special-case handling of the first or last elements.
+ ///
+ /// Iterator element type is
+ /// [`(Position, Self::Item)`](Position)
+ ///
+ /// ```
+ /// use itertools::{Itertools, Position};
+ ///
+ /// let it = (0..4).with_position();
+ /// itertools::assert_equal(it,
+ /// vec![(Position::First, 0),
+ /// (Position::Middle, 1),
+ /// (Position::Middle, 2),
+ /// (Position::Last, 3)]);
+ ///
+ /// let it = (0..1).with_position();
+ /// itertools::assert_equal(it, vec![(Position::Only, 0)]);
+ /// ```
+ fn with_position(self) -> WithPosition<Self>
+ where Self: Sized,
+ {
+ with_position::with_position(self)
+ }
+
+ /// Return an iterator adaptor that yields the indices of all elements
+ /// satisfying a predicate, counted from the start of the iterator.
+ ///
+ /// Equivalent to `iter.enumerate().filter(|(_, v)| predicate(v)).map(|(i, _)| i)`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec![1, 2, 3, 3, 4, 6, 7, 9];
+ /// itertools::assert_equal(data.iter().positions(|v| v % 2 == 0), vec![1, 4, 5]);
+ ///
+ /// itertools::assert_equal(data.iter().positions(|v| v % 2 == 1).rev(), vec![7, 6, 3, 2, 0]);
+ /// ```
+ fn positions<P>(self, predicate: P) -> Positions<Self, P>
+ where Self: Sized,
+ P: FnMut(Self::Item) -> bool,
+ {
+ adaptors::positions(self, predicate)
+ }
+
+ /// Return an iterator adaptor that applies a mutating function
+ /// to each element before yielding it.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let input = vec![vec![1], vec![3, 2, 1]];
+ /// let it = input.into_iter().update(|mut v| v.push(0));
+ /// itertools::assert_equal(it, vec![vec![1, 0], vec![3, 2, 1, 0]]);
+ /// ```
+ fn update<F>(self, updater: F) -> Update<Self, F>
+ where Self: Sized,
+ F: FnMut(&mut Self::Item),
+ {
+ adaptors::update(self, updater)
+ }
+
+ // non-adaptor methods
+ /// Advances the iterator and returns the next items grouped in a tuple of
+ /// a specific size (up to 12).
+ ///
+ /// If there are enough elements to be grouped in a tuple, then the tuple is
+ /// returned inside `Some`, otherwise `None` is returned.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let mut iter = 1..5;
+ ///
+ /// assert_eq!(Some((1, 2)), iter.next_tuple());
+ /// ```
+ fn next_tuple<T>(&mut self) -> Option<T>
+ where Self: Sized + Iterator<Item = T::Item>,
+ T: traits::HomogeneousTuple
+ {
+ T::collect_from_iter_no_buf(self)
+ }
+
+ /// Collects all items from the iterator into a tuple of a specific size
+ /// (up to 12).
+ ///
+ /// If the number of elements inside the iterator is **exactly** equal to
+ /// the tuple size, then the tuple is returned inside `Some`, otherwise
+ /// `None` is returned.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let iter = 1..3;
+ ///
+ /// if let Some((x, y)) = iter.collect_tuple() {
+ /// assert_eq!((x, y), (1, 2))
+ /// } else {
+ /// panic!("Expected two elements")
+ /// }
+ /// ```
+ fn collect_tuple<T>(mut self) -> Option<T>
+ where Self: Sized + Iterator<Item = T::Item>,
+ T: traits::HomogeneousTuple
+ {
+ match self.next_tuple() {
+ elt @ Some(_) => match self.next() {
+ Some(_) => None,
+ None => elt,
+ },
+ _ => None
+ }
+ }
+
+
+ /// Find the position and value of the first element satisfying a predicate.
+ ///
+ /// The iterator is not advanced past the first element found.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let text = "Hα";
+ /// assert_eq!(text.chars().find_position(|ch| ch.is_lowercase()), Some((1, 'α')));
+ /// ```
+ fn find_position<P>(&mut self, mut pred: P) -> Option<(usize, Self::Item)>
+ where P: FnMut(&Self::Item) -> bool
+ {
+ for (index, elt) in self.enumerate() {
+ if pred(&elt) {
+ return Some((index, elt));
+ }
+ }
+ None
+ }
+ /// Find the value of the first element satisfying a predicate or return the last element, if any.
+ ///
+ /// The iterator is not advanced past the first element found.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let numbers = [1, 2, 3, 4];
+ /// assert_eq!(numbers.iter().find_or_last(|&&x| x > 5), Some(&4));
+ /// assert_eq!(numbers.iter().find_or_last(|&&x| x > 2), Some(&3));
+ /// assert_eq!(std::iter::empty::<i32>().find_or_last(|&x| x > 5), None);
+ /// ```
+ fn find_or_last<P>(mut self, mut predicate: P) -> Option<Self::Item>
+ where Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
+ {
+ let mut prev = None;
+ self.find_map(|x| if predicate(&x) { Some(x) } else { prev = Some(x); None })
+ .or(prev)
+ }
+ /// Find the value of the first element satisfying a predicate or return the first element, if any.
+ ///
+ /// The iterator is not advanced past the first element found.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let numbers = [1, 2, 3, 4];
+ /// assert_eq!(numbers.iter().find_or_first(|&&x| x > 5), Some(&1));
+ /// assert_eq!(numbers.iter().find_or_first(|&&x| x > 2), Some(&3));
+ /// assert_eq!(std::iter::empty::<i32>().find_or_first(|&x| x > 5), None);
+ /// ```
+ fn find_or_first<P>(mut self, mut predicate: P) -> Option<Self::Item>
+ where Self: Sized,
+ P: FnMut(&Self::Item) -> bool,
+ {
+ let first = self.next()?;
+ Some(if predicate(&first) {
+ first
+ } else {
+ self.find(|x| predicate(x)).unwrap_or(first)
+ })
+ }
+ /// Returns `true` if the given item is present in this iterator.
+ ///
+ /// This method is short-circuiting. If the given item is present in this
+ /// iterator, this method will consume the iterator up-to-and-including
+ /// the item. If the given item is not present in this iterator, the
+ /// iterator will be exhausted.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// #[derive(PartialEq, Debug)]
+ /// enum Enum { A, B, C, D, E, }
+ ///
+ /// let mut iter = vec![Enum::A, Enum::B, Enum::C, Enum::D].into_iter();
+ ///
+ /// // search `iter` for `B`
+ /// assert_eq!(iter.contains(&Enum::B), true);
+ /// // `B` was found, so the iterator now rests at the item after `B` (i.e, `C`).
+ /// assert_eq!(iter.next(), Some(Enum::C));
+ ///
+ /// // search `iter` for `E`
+ /// assert_eq!(iter.contains(&Enum::E), false);
+ /// // `E` wasn't found, so `iter` is now exhausted
+ /// assert_eq!(iter.next(), None);
+ /// ```
+ fn contains<Q>(&mut self, query: &Q) -> bool
+ where
+ Self: Sized,
+ Self::Item: Borrow<Q>,
+ Q: PartialEq,
+ {
+ self.any(|x| x.borrow() == query)
+ }
+
+ /// Check whether all elements compare equal.
+ ///
+ /// Empty iterators are considered to have equal elements:
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec![1, 1, 1, 2, 2, 3, 3, 3, 4, 5, 5];
+ /// assert!(!data.iter().all_equal());
+ /// assert!(data[0..3].iter().all_equal());
+ /// assert!(data[3..5].iter().all_equal());
+ /// assert!(data[5..8].iter().all_equal());
+ ///
+ /// let data : Option<usize> = None;
+ /// assert!(data.into_iter().all_equal());
+ /// ```
+ fn all_equal(&mut self) -> bool
+ where Self: Sized,
+ Self::Item: PartialEq,
+ {
+ match self.next() {
+ None => true,
+ Some(a) => self.all(|x| a == x),
+ }
+ }
+
+ /// If there are elements and they are all equal, return a single copy of that element.
+ /// If there are no elements, return an Error containing None.
+ /// If there are elements and they are not all equal, return a tuple containing the first
+ /// two non-equal elements found.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec![1, 1, 1, 2, 2, 3, 3, 3, 4, 5, 5];
+ /// assert_eq!(data.iter().all_equal_value(), Err(Some((&1, &2))));
+ /// assert_eq!(data[0..3].iter().all_equal_value(), Ok(&1));
+ /// assert_eq!(data[3..5].iter().all_equal_value(), Ok(&2));
+ /// assert_eq!(data[5..8].iter().all_equal_value(), Ok(&3));
+ ///
+ /// let data : Option<usize> = None;
+ /// assert_eq!(data.into_iter().all_equal_value(), Err(None));
+ /// ```
+ fn all_equal_value(&mut self) -> Result<Self::Item, Option<(Self::Item, Self::Item)>>
+ where
+ Self: Sized,
+ Self::Item: PartialEq
+ {
+ let first = self.next().ok_or(None)?;
+ let other = self.find(|x| x != &first);
+ if let Some(other) = other {
+ Err(Some((first, other)))
+ } else {
+ Ok(first)
+ }
+ }
+
+ /// Check whether all elements are unique (non equal).
+ ///
+ /// Empty iterators are considered to have unique elements:
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec![1, 2, 3, 4, 1, 5];
+ /// assert!(!data.iter().all_unique());
+ /// assert!(data[0..4].iter().all_unique());
+ /// assert!(data[1..6].iter().all_unique());
+ ///
+ /// let data : Option<usize> = None;
+ /// assert!(data.into_iter().all_unique());
+ /// ```
+ #[cfg(feature = "use_std")]
+ fn all_unique(&mut self) -> bool
+ where Self: Sized,
+ Self::Item: Eq + Hash
+ {
+ let mut used = HashSet::new();
+ self.all(move |elt| used.insert(elt))
+ }
+
+ /// Consume the first `n` elements from the iterator eagerly,
+ /// and return the same iterator again.
+ ///
+ /// It works similarly to *.skip(* `n` *)* except it is eager and
+ /// preserves the iterator type.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let mut iter = "αβγ".chars().dropping(2);
+ /// itertools::assert_equal(iter, "γ".chars());
+ /// ```
+ ///
+ /// *Fusing notes: if the iterator is exhausted by dropping,
+ /// the result of calling `.next()` again depends on the iterator implementation.*
+ fn dropping(mut self, n: usize) -> Self
+ where Self: Sized
+ {
+ if n > 0 {
+ self.nth(n - 1);
+ }
+ self
+ }
+
+ /// Consume the last `n` elements from the iterator eagerly,
+ /// and return the same iterator again.
+ ///
+ /// This is only possible on double ended iterators. `n` may be
+ /// larger than the number of elements.
+ ///
+ /// Note: This method is eager, dropping the back elements immediately and
+ /// preserves the iterator type.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let init = vec![0, 3, 6, 9].into_iter().dropping_back(1);
+ /// itertools::assert_equal(init, vec![0, 3, 6]);
+ /// ```
+ fn dropping_back(mut self, n: usize) -> Self
+ where Self: Sized,
+ Self: DoubleEndedIterator
+ {
+ if n > 0 {
+ (&mut self).rev().nth(n - 1);
+ }
+ self
+ }
+
+ /// Run the closure `f` eagerly on each element of the iterator.
+ ///
+ /// Consumes the iterator until its end.
+ ///
+ /// ```
+ /// use std::sync::mpsc::channel;
+ /// use itertools::Itertools;
+ ///
+ /// let (tx, rx) = channel();
+ ///
+ /// // use .foreach() to apply a function to each value -- sending it
+ /// (0..5).map(|x| x * 2 + 1).foreach(|x| { tx.send(x).unwrap(); } );
+ ///
+ /// drop(tx);
+ ///
+ /// itertools::assert_equal(rx.iter(), vec![1, 3, 5, 7, 9]);
+ /// ```
+ #[deprecated(note="Use .for_each() instead", since="0.8.0")]
+ fn foreach<F>(self, f: F)
+ where F: FnMut(Self::Item),
+ Self: Sized,
+ {
+ self.for_each(f);
+ }
+
+ /// Combine all an iterator's elements into one element by using [`Extend`].
+ ///
+ /// This combinator will extend the first item with each of the rest of the
+ /// items of the iterator. If the iterator is empty, the default value of
+ /// `I::Item` is returned.
+ ///
+ /// ```rust
+ /// use itertools::Itertools;
+ ///
+ /// let input = vec![vec![1], vec![2, 3], vec![4, 5, 6]];
+ /// assert_eq!(input.into_iter().concat(),
+ /// vec![1, 2, 3, 4, 5, 6]);
+ /// ```
+ fn concat(self) -> Self::Item
+ where Self: Sized,
+ Self::Item: Extend<<<Self as Iterator>::Item as IntoIterator>::Item> + IntoIterator + Default
+ {
+ concat(self)
+ }
+
+ /// `.collect_vec()` is simply a type specialization of [`Iterator::collect`],
+ /// for convenience.
+ #[cfg(feature = "use_alloc")]
+ fn collect_vec(self) -> Vec<Self::Item>
+ where Self: Sized
+ {
+ self.collect()
+ }
+
+ /// `.try_collect()` is more convenient way of writing
+ /// `.collect::<Result<_, _>>()`
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::{fs, io};
+ /// use itertools::Itertools;
+ ///
+ /// fn process_dir_entries(entries: &[fs::DirEntry]) {
+ /// // ...
+ /// }
+ ///
+ /// fn do_stuff() -> std::io::Result<()> {
+ /// let entries: Vec<_> = fs::read_dir(".")?.try_collect()?;
+ /// process_dir_entries(&entries);
+ ///
+ /// Ok(())
+ /// }
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn try_collect<T, U, E>(self) -> Result<U, E>
+ where
+ Self: Sized + Iterator<Item = Result<T, E>>,
+ Result<U, E>: FromIterator<Result<T, E>>,
+ {
+ self.collect()
+ }
+
+ /// Assign to each reference in `self` from the `from` iterator,
+ /// stopping at the shortest of the two iterators.
+ ///
+ /// The `from` iterator is queried for its next element before the `self`
+ /// iterator, and if either is exhausted the method is done.
+ ///
+ /// Return the number of elements written.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let mut xs = [0; 4];
+ /// xs.iter_mut().set_from(1..);
+ /// assert_eq!(xs, [1, 2, 3, 4]);
+ /// ```
+ #[inline]
+ fn set_from<'a, A: 'a, J>(&mut self, from: J) -> usize
+ where Self: Iterator<Item = &'a mut A>,
+ J: IntoIterator<Item = A>
+ {
+ let mut count = 0;
+ for elt in from {
+ match self.next() {
+ None => break,
+ Some(ptr) => *ptr = elt,
+ }
+ count += 1;
+ }
+ count
+ }
+
+ /// Combine all iterator elements into one String, separated by `sep`.
+ ///
+ /// Use the `Display` implementation of each element.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// assert_eq!(["a", "b", "c"].iter().join(", "), "a, b, c");
+ /// assert_eq!([1, 2, 3].iter().join(", "), "1, 2, 3");
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn join(&mut self, sep: &str) -> String
+ where Self::Item: std::fmt::Display
+ {
+ match self.next() {
+ None => String::new(),
+ Some(first_elt) => {
+ // estimate lower bound of capacity needed
+ let (lower, _) = self.size_hint();
+ let mut result = String::with_capacity(sep.len() * lower);
+ write!(&mut result, "{}", first_elt).unwrap();
+ self.for_each(|elt| {
+ result.push_str(sep);
+ write!(&mut result, "{}", elt).unwrap();
+ });
+ result
+ }
+ }
+ }
+
+ /// Format all iterator elements, separated by `sep`.
+ ///
+ /// All elements are formatted (any formatting trait)
+ /// with `sep` inserted between each element.
+ ///
+ /// **Panics** if the formatter helper is formatted more than once.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = [1.1, 2.71828, -3.];
+ /// assert_eq!(
+ /// format!("{:.2}", data.iter().format(", ")),
+ /// "1.10, 2.72, -3.00");
+ /// ```
+ fn format(self, sep: &str) -> Format<Self>
+ where Self: Sized,
+ {
+ format::new_format_default(self, sep)
+ }
+
+ /// Format all iterator elements, separated by `sep`.
+ ///
+ /// This is a customizable version of [`.format()`](Itertools::format).
+ ///
+ /// The supplied closure `format` is called once per iterator element,
+ /// with two arguments: the element and a callback that takes a
+ /// `&Display` value, i.e. any reference to type that implements `Display`.
+ ///
+ /// Using `&format_args!(...)` is the most versatile way to apply custom
+ /// element formatting. The callback can be called multiple times if needed.
+ ///
+ /// **Panics** if the formatter helper is formatted more than once.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = [1.1, 2.71828, -3.];
+ /// let data_formatter = data.iter().format_with(", ", |elt, f| f(&format_args!("{:.2}", elt)));
+ /// assert_eq!(format!("{}", data_formatter),
+ /// "1.10, 2.72, -3.00");
+ ///
+ /// // .format_with() is recursively composable
+ /// let matrix = [[1., 2., 3.],
+ /// [4., 5., 6.]];
+ /// let matrix_formatter = matrix.iter().format_with("\n", |row, f| {
+ /// f(&row.iter().format_with(", ", |elt, g| g(&elt)))
+ /// });
+ /// assert_eq!(format!("{}", matrix_formatter),
+ /// "1, 2, 3\n4, 5, 6");
+ ///
+ ///
+ /// ```
+ fn format_with<F>(self, sep: &str, format: F) -> FormatWith<Self, F>
+ where Self: Sized,
+ F: FnMut(Self::Item, &mut dyn FnMut(&dyn fmt::Display) -> fmt::Result) -> fmt::Result,
+ {
+ format::new_format(self, sep, format)
+ }
+
+ /// See [`.fold_ok()`](Itertools::fold_ok).
+ #[deprecated(note="Use .fold_ok() instead", since="0.10.0")]
+ fn fold_results<A, E, B, F>(&mut self, start: B, f: F) -> Result<B, E>
+ where Self: Iterator<Item = Result<A, E>>,
+ F: FnMut(B, A) -> B
+ {
+ self.fold_ok(start, f)
+ }
+
+ /// Fold `Result` values from an iterator.
+ ///
+ /// Only `Ok` values are folded. If no error is encountered, the folded
+ /// value is returned inside `Ok`. Otherwise, the operation terminates
+ /// and returns the first `Err` value it encounters. No iterator elements are
+ /// consumed after the first error.
+ ///
+ /// The first accumulator value is the `start` parameter.
+ /// Each iteration passes the accumulator value and the next value inside `Ok`
+ /// to the fold function `f` and its return value becomes the new accumulator value.
+ ///
+ /// For example the sequence *Ok(1), Ok(2), Ok(3)* will result in a
+ /// computation like this:
+ ///
+ /// ```ignore
+ /// let mut accum = start;
+ /// accum = f(accum, 1);
+ /// accum = f(accum, 2);
+ /// accum = f(accum, 3);
+ /// ```
+ ///
+ /// With a `start` value of 0 and an addition as folding function,
+ /// this effectively results in *((0 + 1) + 2) + 3*
+ ///
+ /// ```
+ /// use std::ops::Add;
+ /// use itertools::Itertools;
+ ///
+ /// let values = [1, 2, -2, -1, 2, 1];
+ /// assert_eq!(
+ /// values.iter()
+ /// .map(Ok::<_, ()>)
+ /// .fold_ok(0, Add::add),
+ /// Ok(3)
+ /// );
+ /// assert!(
+ /// values.iter()
+ /// .map(|&x| if x >= 0 { Ok(x) } else { Err("Negative number") })
+ /// .fold_ok(0, Add::add)
+ /// .is_err()
+ /// );
+ /// ```
+ fn fold_ok<A, E, B, F>(&mut self, mut start: B, mut f: F) -> Result<B, E>
+ where Self: Iterator<Item = Result<A, E>>,
+ F: FnMut(B, A) -> B
+ {
+ for elt in self {
+ match elt {
+ Ok(v) => start = f(start, v),
+ Err(u) => return Err(u),
+ }
+ }
+ Ok(start)
+ }
+
+ /// Fold `Option` values from an iterator.
+ ///
+ /// Only `Some` values are folded. If no `None` is encountered, the folded
+ /// value is returned inside `Some`. Otherwise, the operation terminates
+ /// and returns `None`. No iterator elements are consumed after the `None`.
+ ///
+ /// This is the `Option` equivalent to [`fold_ok`](Itertools::fold_ok).
+ ///
+ /// ```
+ /// use std::ops::Add;
+ /// use itertools::Itertools;
+ ///
+ /// let mut values = vec![Some(1), Some(2), Some(-2)].into_iter();
+ /// assert_eq!(values.fold_options(5, Add::add), Some(5 + 1 + 2 - 2));
+ ///
+ /// let mut more_values = vec![Some(2), None, Some(0)].into_iter();
+ /// assert!(more_values.fold_options(0, Add::add).is_none());
+ /// assert_eq!(more_values.next().unwrap(), Some(0));
+ /// ```
+ fn fold_options<A, B, F>(&mut self, mut start: B, mut f: F) -> Option<B>
+ where Self: Iterator<Item = Option<A>>,
+ F: FnMut(B, A) -> B
+ {
+ for elt in self {
+ match elt {
+ Some(v) => start = f(start, v),
+ None => return None,
+ }
+ }
+ Some(start)
+ }
+
+ /// Accumulator of the elements in the iterator.
+ ///
+ /// Like `.fold()`, without a base case. If the iterator is
+ /// empty, return `None`. With just one element, return it.
+ /// Otherwise elements are accumulated in sequence using the closure `f`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// assert_eq!((0..10).fold1(|x, y| x + y).unwrap_or(0), 45);
+ /// assert_eq!((0..0).fold1(|x, y| x * y), None);
+ /// ```
+ #[deprecated(since = "0.10.2", note = "Use `Iterator::reduce` instead")]
+ fn fold1<F>(mut self, f: F) -> Option<Self::Item>
+ where F: FnMut(Self::Item, Self::Item) -> Self::Item,
+ Self: Sized,
+ {
+ self.next().map(move |x| self.fold(x, f))
+ }
+
+ /// Accumulate the elements in the iterator in a tree-like manner.
+ ///
+ /// You can think of it as, while there's more than one item, repeatedly
+ /// combining adjacent items. It does so in bottom-up-merge-sort order,
+ /// however, so that it needs only logarithmic stack space.
+ ///
+ /// This produces a call tree like the following (where the calls under
+ /// an item are done after reading that item):
+ ///
+ /// ```text
+ /// 1 2 3 4 5 6 7
+ /// │ │ │ │ │ │ │
+ /// └─f └─f └─f │
+ /// │ │ │ │
+ /// └───f └─f
+ /// │ │
+ /// └─────f
+ /// ```
+ ///
+ /// Which, for non-associative functions, will typically produce a different
+ /// result than the linear call tree used by [`Iterator::reduce`]:
+ ///
+ /// ```text
+ /// 1 2 3 4 5 6 7
+ /// │ │ │ │ │ │ │
+ /// └─f─f─f─f─f─f
+ /// ```
+ ///
+ /// If `f` is associative, prefer the normal [`Iterator::reduce`] instead.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // The same tree as above
+ /// let num_strings = (1..8).map(|x| x.to_string());
+ /// assert_eq!(num_strings.tree_fold1(|x, y| format!("f({}, {})", x, y)),
+ /// Some(String::from("f(f(f(1, 2), f(3, 4)), f(f(5, 6), 7))")));
+ ///
+ /// // Like fold1, an empty iterator produces None
+ /// assert_eq!((0..0).tree_fold1(|x, y| x * y), None);
+ ///
+ /// // tree_fold1 matches fold1 for associative operations...
+ /// assert_eq!((0..10).tree_fold1(|x, y| x + y),
+ /// (0..10).fold1(|x, y| x + y));
+ /// // ...but not for non-associative ones
+ /// assert_ne!((0..10).tree_fold1(|x, y| x - y),
+ /// (0..10).fold1(|x, y| x - y));
+ /// ```
+ fn tree_fold1<F>(mut self, mut f: F) -> Option<Self::Item>
+ where F: FnMut(Self::Item, Self::Item) -> Self::Item,
+ Self: Sized,
+ {
+ type State<T> = Result<T, Option<T>>;
+
+ fn inner0<T, II, FF>(it: &mut II, f: &mut FF) -> State<T>
+ where
+ II: Iterator<Item = T>,
+ FF: FnMut(T, T) -> T
+ {
+ // This function could be replaced with `it.next().ok_or(None)`,
+ // but half the useful tree_fold1 work is combining adjacent items,
+ // so put that in a form that LLVM is more likely to optimize well.
+
+ let a =
+ if let Some(v) = it.next() { v }
+ else { return Err(None) };
+ let b =
+ if let Some(v) = it.next() { v }
+ else { return Err(Some(a)) };
+ Ok(f(a, b))
+ }
+
+ fn inner<T, II, FF>(stop: usize, it: &mut II, f: &mut FF) -> State<T>
+ where
+ II: Iterator<Item = T>,
+ FF: FnMut(T, T) -> T
+ {
+ let mut x = inner0(it, f)?;
+ for height in 0..stop {
+ // Try to get another tree the same size with which to combine it,
+ // creating a new tree that's twice as big for next time around.
+ let next =
+ if height == 0 {
+ inner0(it, f)
+ } else {
+ inner(height, it, f)
+ };
+ match next {
+ Ok(y) => x = f(x, y),
+
+ // If we ran out of items, combine whatever we did manage
+ // to get. It's better combined with the current value
+ // than something in a parent frame, because the tree in
+ // the parent is always as least as big as this one.
+ Err(None) => return Err(Some(x)),
+ Err(Some(y)) => return Err(Some(f(x, y))),
+ }
+ }
+ Ok(x)
+ }
+
+ match inner(usize::max_value(), &mut self, &mut f) {
+ Err(x) => x,
+ _ => unreachable!(),
+ }
+ }
+
+ /// An iterator method that applies a function, producing a single, final value.
+ ///
+ /// `fold_while()` is basically equivalent to [`Iterator::fold`] but with additional support for
+ /// early exit via short-circuiting.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// use itertools::FoldWhile::{Continue, Done};
+ ///
+ /// let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ ///
+ /// let mut result = 0;
+ ///
+ /// // for loop:
+ /// for i in &numbers {
+ /// if *i > 5 {
+ /// break;
+ /// }
+ /// result = result + i;
+ /// }
+ ///
+ /// // fold:
+ /// let result2 = numbers.iter().fold(0, |acc, x| {
+ /// if *x > 5 { acc } else { acc + x }
+ /// });
+ ///
+ /// // fold_while:
+ /// let result3 = numbers.iter().fold_while(0, |acc, x| {
+ /// if *x > 5 { Done(acc) } else { Continue(acc + x) }
+ /// }).into_inner();
+ ///
+ /// // they're the same
+ /// assert_eq!(result, result2);
+ /// assert_eq!(result2, result3);
+ /// ```
+ ///
+ /// The big difference between the computations of `result2` and `result3` is that while
+ /// `fold()` called the provided closure for every item of the callee iterator,
+ /// `fold_while()` actually stopped iterating as soon as it encountered `Fold::Done(_)`.
+ fn fold_while<B, F>(&mut self, init: B, mut f: F) -> FoldWhile<B>
+ where Self: Sized,
+ F: FnMut(B, Self::Item) -> FoldWhile<B>
+ {
+ use Result::{
+ Ok as Continue,
+ Err as Break,
+ };
+
+ let result = self.try_fold(init, #[inline(always)] |acc, v|
+ match f(acc, v) {
+ FoldWhile::Continue(acc) => Continue(acc),
+ FoldWhile::Done(acc) => Break(acc),
+ }
+ );
+
+ match result {
+ Continue(acc) => FoldWhile::Continue(acc),
+ Break(acc) => FoldWhile::Done(acc),
+ }
+ }
+
+ /// Iterate over the entire iterator and add all the elements.
+ ///
+ /// An empty iterator returns `None`, otherwise `Some(sum)`.
+ ///
+ /// # Panics
+ ///
+ /// When calling `sum1()` and a primitive integer type is being returned, this
+ /// method will panic if the computation overflows and debug assertions are
+ /// enabled.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let empty_sum = (1..1).sum1::<i32>();
+ /// assert_eq!(empty_sum, None);
+ ///
+ /// let nonempty_sum = (1..11).sum1::<i32>();
+ /// assert_eq!(nonempty_sum, Some(55));
+ /// ```
+ fn sum1<S>(mut self) -> Option<S>
+ where Self: Sized,
+ S: std::iter::Sum<Self::Item>,
+ {
+ self.next()
+ .map(|first| once(first).chain(self).sum())
+ }
+
+ /// Iterate over the entire iterator and multiply all the elements.
+ ///
+ /// An empty iterator returns `None`, otherwise `Some(product)`.
+ ///
+ /// # Panics
+ ///
+ /// When calling `product1()` and a primitive integer type is being returned,
+ /// method will panic if the computation overflows and debug assertions are
+ /// enabled.
+ ///
+ /// # Examples
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let empty_product = (1..1).product1::<i32>();
+ /// assert_eq!(empty_product, None);
+ ///
+ /// let nonempty_product = (1..11).product1::<i32>();
+ /// assert_eq!(nonempty_product, Some(3628800));
+ /// ```
+ fn product1<P>(mut self) -> Option<P>
+ where Self: Sized,
+ P: std::iter::Product<Self::Item>,
+ {
+ self.next()
+ .map(|first| once(first).chain(self).product())
+ }
+
+ /// Sort all iterator elements into a new iterator in ascending order.
+ ///
+ /// **Note:** This consumes the entire iterator, uses the
+ /// [`slice::sort_unstable`] method and returns the result as a new
+ /// iterator that owns its elements.
+ ///
+ /// This sort is unstable (i.e., may reorder equal elements).
+ ///
+ /// The sorted iterator, if directly collected to a `Vec`, is converted
+ /// without any extra copying or allocation cost.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // sort the letters of the text in ascending order
+ /// let text = "bdacfe";
+ /// itertools::assert_equal(text.chars().sorted_unstable(),
+ /// "abcdef".chars());
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn sorted_unstable(self) -> VecIntoIter<Self::Item>
+ where Self: Sized,
+ Self::Item: Ord
+ {
+ // Use .sort_unstable() directly since it is not quite identical with
+ // .sort_by(Ord::cmp)
+ let mut v = Vec::from_iter(self);
+ v.sort_unstable();
+ v.into_iter()
+ }
+
+ /// Sort all iterator elements into a new iterator in ascending order.
+ ///
+ /// **Note:** This consumes the entire iterator, uses the
+ /// [`slice::sort_unstable_by`] method and returns the result as a new
+ /// iterator that owns its elements.
+ ///
+ /// This sort is unstable (i.e., may reorder equal elements).
+ ///
+ /// The sorted iterator, if directly collected to a `Vec`, is converted
+ /// without any extra copying or allocation cost.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // sort people in descending order by age
+ /// let people = vec![("Jane", 20), ("John", 18), ("Jill", 30), ("Jack", 27)];
+ ///
+ /// let oldest_people_first = people
+ /// .into_iter()
+ /// .sorted_unstable_by(|a, b| Ord::cmp(&b.1, &a.1))
+ /// .map(|(person, _age)| person);
+ ///
+ /// itertools::assert_equal(oldest_people_first,
+ /// vec!["Jill", "Jack", "Jane", "John"]);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn sorted_unstable_by<F>(self, cmp: F) -> VecIntoIter<Self::Item>
+ where Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
+ {
+ let mut v = Vec::from_iter(self);
+ v.sort_unstable_by(cmp);
+ v.into_iter()
+ }
+
+ /// Sort all iterator elements into a new iterator in ascending order.
+ ///
+ /// **Note:** This consumes the entire iterator, uses the
+ /// [`slice::sort_unstable_by_key`] method and returns the result as a new
+ /// iterator that owns its elements.
+ ///
+ /// This sort is unstable (i.e., may reorder equal elements).
+ ///
+ /// The sorted iterator, if directly collected to a `Vec`, is converted
+ /// without any extra copying or allocation cost.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // sort people in descending order by age
+ /// let people = vec![("Jane", 20), ("John", 18), ("Jill", 30), ("Jack", 27)];
+ ///
+ /// let oldest_people_first = people
+ /// .into_iter()
+ /// .sorted_unstable_by_key(|x| -x.1)
+ /// .map(|(person, _age)| person);
+ ///
+ /// itertools::assert_equal(oldest_people_first,
+ /// vec!["Jill", "Jack", "Jane", "John"]);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn sorted_unstable_by_key<K, F>(self, f: F) -> VecIntoIter<Self::Item>
+ where Self: Sized,
+ K: Ord,
+ F: FnMut(&Self::Item) -> K,
+ {
+ let mut v = Vec::from_iter(self);
+ v.sort_unstable_by_key(f);
+ v.into_iter()
+ }
+
+ /// Sort all iterator elements into a new iterator in ascending order.
+ ///
+ /// **Note:** This consumes the entire iterator, uses the
+ /// [`slice::sort`] method and returns the result as a new
+ /// iterator that owns its elements.
+ ///
+ /// This sort is stable (i.e., does not reorder equal elements).
+ ///
+ /// The sorted iterator, if directly collected to a `Vec`, is converted
+ /// without any extra copying or allocation cost.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // sort the letters of the text in ascending order
+ /// let text = "bdacfe";
+ /// itertools::assert_equal(text.chars().sorted(),
+ /// "abcdef".chars());
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn sorted(self) -> VecIntoIter<Self::Item>
+ where Self: Sized,
+ Self::Item: Ord
+ {
+ // Use .sort() directly since it is not quite identical with
+ // .sort_by(Ord::cmp)
+ let mut v = Vec::from_iter(self);
+ v.sort();
+ v.into_iter()
+ }
+
+ /// Sort all iterator elements into a new iterator in ascending order.
+ ///
+ /// **Note:** This consumes the entire iterator, uses the
+ /// [`slice::sort_by`] method and returns the result as a new
+ /// iterator that owns its elements.
+ ///
+ /// This sort is stable (i.e., does not reorder equal elements).
+ ///
+ /// The sorted iterator, if directly collected to a `Vec`, is converted
+ /// without any extra copying or allocation cost.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // sort people in descending order by age
+ /// let people = vec![("Jane", 20), ("John", 18), ("Jill", 30), ("Jack", 30)];
+ ///
+ /// let oldest_people_first = people
+ /// .into_iter()
+ /// .sorted_by(|a, b| Ord::cmp(&b.1, &a.1))
+ /// .map(|(person, _age)| person);
+ ///
+ /// itertools::assert_equal(oldest_people_first,
+ /// vec!["Jill", "Jack", "Jane", "John"]);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn sorted_by<F>(self, cmp: F) -> VecIntoIter<Self::Item>
+ where Self: Sized,
+ F: FnMut(&Self::Item, &Self::Item) -> Ordering,
+ {
+ let mut v = Vec::from_iter(self);
+ v.sort_by(cmp);
+ v.into_iter()
+ }
+
+ /// Sort all iterator elements into a new iterator in ascending order.
+ ///
+ /// **Note:** This consumes the entire iterator, uses the
+ /// [`slice::sort_by_key`] method and returns the result as a new
+ /// iterator that owns its elements.
+ ///
+ /// This sort is stable (i.e., does not reorder equal elements).
+ ///
+ /// The sorted iterator, if directly collected to a `Vec`, is converted
+ /// without any extra copying or allocation cost.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // sort people in descending order by age
+ /// let people = vec![("Jane", 20), ("John", 18), ("Jill", 30), ("Jack", 30)];
+ ///
+ /// let oldest_people_first = people
+ /// .into_iter()
+ /// .sorted_by_key(|x| -x.1)
+ /// .map(|(person, _age)| person);
+ ///
+ /// itertools::assert_equal(oldest_people_first,
+ /// vec!["Jill", "Jack", "Jane", "John"]);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn sorted_by_key<K, F>(self, f: F) -> VecIntoIter<Self::Item>
+ where Self: Sized,
+ K: Ord,
+ F: FnMut(&Self::Item) -> K,
+ {
+ let mut v = Vec::from_iter(self);
+ v.sort_by_key(f);
+ v.into_iter()
+ }
+
+ /// Sort all iterator elements into a new iterator in ascending order. The key function is
+ /// called exactly once per key.
+ ///
+ /// **Note:** This consumes the entire iterator, uses the
+ /// [`slice::sort_by_cached_key`] method and returns the result as a new
+ /// iterator that owns its elements.
+ ///
+ /// This sort is stable (i.e., does not reorder equal elements).
+ ///
+ /// The sorted iterator, if directly collected to a `Vec`, is converted
+ /// without any extra copying or allocation cost.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // sort people in descending order by age
+ /// let people = vec![("Jane", 20), ("John", 18), ("Jill", 30), ("Jack", 30)];
+ ///
+ /// let oldest_people_first = people
+ /// .into_iter()
+ /// .sorted_by_cached_key(|x| -x.1)
+ /// .map(|(person, _age)| person);
+ ///
+ /// itertools::assert_equal(oldest_people_first,
+ /// vec!["Jill", "Jack", "Jane", "John"]);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn sorted_by_cached_key<K, F>(self, f: F) -> VecIntoIter<Self::Item>
+ where
+ Self: Sized,
+ K: Ord,
+ F: FnMut(&Self::Item) -> K,
+ {
+ let mut v = Vec::from_iter(self);
+ v.sort_by_cached_key(f);
+ v.into_iter()
+ }
+
+ /// Sort the k smallest elements into a new iterator, in ascending order.
+ ///
+ /// **Note:** This consumes the entire iterator, and returns the result
+ /// as a new iterator that owns its elements. If the input contains
+ /// less than k elements, the result is equivalent to `self.sorted()`.
+ ///
+ /// This is guaranteed to use `k * sizeof(Self::Item) + O(1)` memory
+ /// and `O(n log k)` time, with `n` the number of elements in the input.
+ ///
+ /// The sorted iterator, if directly collected to a `Vec`, is converted
+ /// without any extra copying or allocation cost.
+ ///
+ /// **Note:** This is functionally-equivalent to `self.sorted().take(k)`
+ /// but much more efficient.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// // A random permutation of 0..15
+ /// let numbers = vec![6, 9, 1, 14, 0, 4, 8, 7, 11, 2, 10, 3, 13, 12, 5];
+ ///
+ /// let five_smallest = numbers
+ /// .into_iter()
+ /// .k_smallest(5);
+ ///
+ /// itertools::assert_equal(five_smallest, 0..5);
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn k_smallest(self, k: usize) -> VecIntoIter<Self::Item>
+ where Self: Sized,
+ Self::Item: Ord
+ {
+ crate::k_smallest::k_smallest(self, k)
+ .into_sorted_vec()
+ .into_iter()
+ }
+
+ /// Collect all iterator elements into one of two
+ /// partitions. Unlike [`Iterator::partition`], each partition may
+ /// have a distinct type.
+ ///
+ /// ```
+ /// use itertools::{Itertools, Either};
+ ///
+ /// let successes_and_failures = vec![Ok(1), Err(false), Err(true), Ok(2)];
+ ///
+ /// let (successes, failures): (Vec<_>, Vec<_>) = successes_and_failures
+ /// .into_iter()
+ /// .partition_map(|r| {
+ /// match r {
+ /// Ok(v) => Either::Left(v),
+ /// Err(v) => Either::Right(v),
+ /// }
+ /// });
+ ///
+ /// assert_eq!(successes, [1, 2]);
+ /// assert_eq!(failures, [false, true]);
+ /// ```
+ fn partition_map<A, B, F, L, R>(self, mut predicate: F) -> (A, B)
+ where Self: Sized,
+ F: FnMut(Self::Item) -> Either<L, R>,
+ A: Default + Extend<L>,
+ B: Default + Extend<R>,
+ {
+ let mut left = A::default();
+ let mut right = B::default();
+
+ self.for_each(|val| match predicate(val) {
+ Either::Left(v) => left.extend(Some(v)),
+ Either::Right(v) => right.extend(Some(v)),
+ });
+
+ (left, right)
+ }
+
+ /// Partition a sequence of `Result`s into one list of all the `Ok` elements
+ /// and another list of all the `Err` elements.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let successes_and_failures = vec![Ok(1), Err(false), Err(true), Ok(2)];
+ ///
+ /// let (successes, failures): (Vec<_>, Vec<_>) = successes_and_failures
+ /// .into_iter()
+ /// .partition_result();
+ ///
+ /// assert_eq!(successes, [1, 2]);
+ /// assert_eq!(failures, [false, true]);
+ /// ```
+ fn partition_result<A, B, T, E>(self) -> (A, B)
+ where
+ Self: Iterator<Item = Result<T, E>> + Sized,
+ A: Default + Extend<T>,
+ B: Default + Extend<E>,
+ {
+ self.partition_map(|r| match r {
+ Ok(v) => Either::Left(v),
+ Err(v) => Either::Right(v),
+ })
+ }
+
+ /// Return a `HashMap` of keys mapped to `Vec`s of values. Keys and values
+ /// are taken from `(Key, Value)` tuple pairs yielded by the input iterator.
+ ///
+ /// Essentially a shorthand for `.into_grouping_map().collect::<Vec<_>>()`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let data = vec![(0, 10), (2, 12), (3, 13), (0, 20), (3, 33), (2, 42)];
+ /// let lookup = data.into_iter().into_group_map();
+ ///
+ /// assert_eq!(lookup[&0], vec![10, 20]);
+ /// assert_eq!(lookup.get(&1), None);
+ /// assert_eq!(lookup[&2], vec![12, 42]);
+ /// assert_eq!(lookup[&3], vec![13, 33]);
+ /// ```
+ #[cfg(feature = "use_std")]
+ fn into_group_map<K, V>(self) -> HashMap<K, Vec<V>>
+ where Self: Iterator<Item=(K, V)> + Sized,
+ K: Hash + Eq,
+ {
+ group_map::into_group_map(self)
+ }
+
+ /// Return an `Iterator` on a `HashMap`. Keys mapped to `Vec`s of values. The key is specified
+ /// in the closure.
+ ///
+ /// Essentially a shorthand for `.into_grouping_map_by(f).collect::<Vec<_>>()`.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// use std::collections::HashMap;
+ ///
+ /// let data = vec![(0, 10), (2, 12), (3, 13), (0, 20), (3, 33), (2, 42)];
+ /// let lookup: HashMap<u32,Vec<(u32, u32)>> =
+ /// data.clone().into_iter().into_group_map_by(|a| a.0);
+ ///
+ /// assert_eq!(lookup[&0], vec![(0,10),(0,20)]);
+ /// assert_eq!(lookup.get(&1), None);
+ /// assert_eq!(lookup[&2], vec![(2,12), (2,42)]);
+ /// assert_eq!(lookup[&3], vec![(3,13), (3,33)]);
+ ///
+ /// assert_eq!(
+ /// data.into_iter()
+ /// .into_group_map_by(|x| x.0)
+ /// .into_iter()
+ /// .map(|(key, values)| (key, values.into_iter().fold(0,|acc, (_,v)| acc + v )))
+ /// .collect::<HashMap<u32,u32>>()[&0],
+ /// 30,
+ /// );
+ /// ```
+ #[cfg(feature = "use_std")]
+ fn into_group_map_by<K, V, F>(self, f: F) -> HashMap<K, Vec<V>>
+ where
+ Self: Iterator<Item=V> + Sized,
+ K: Hash + Eq,
+ F: Fn(&V) -> K,
+ {
+ group_map::into_group_map_by(self, f)
+ }
+
+ /// Constructs a `GroupingMap` to be used later with one of the efficient
+ /// group-and-fold operations it allows to perform.
+ ///
+ /// The input iterator must yield item in the form of `(K, V)` where the
+ /// value of type `K` will be used as key to identify the groups and the
+ /// value of type `V` as value for the folding operation.
+ ///
+ /// See [`GroupingMap`] for more informations
+ /// on what operations are available.
+ #[cfg(feature = "use_std")]
+ fn into_grouping_map<K, V>(self) -> GroupingMap<Self>
+ where Self: Iterator<Item=(K, V)> + Sized,
+ K: Hash + Eq,
+ {
+ grouping_map::new(self)
+ }
+
+ /// Constructs a `GroupingMap` to be used later with one of the efficient
+ /// group-and-fold operations it allows to perform.
+ ///
+ /// The values from this iterator will be used as values for the folding operation
+ /// while the keys will be obtained from the values by calling `key_mapper`.
+ ///
+ /// See [`GroupingMap`] for more informations
+ /// on what operations are available.
+ #[cfg(feature = "use_std")]
+ fn into_grouping_map_by<K, V, F>(self, key_mapper: F) -> GroupingMapBy<Self, F>
+ where Self: Iterator<Item=V> + Sized,
+ K: Hash + Eq,
+ F: FnMut(&V) -> K
+ {
+ grouping_map::new(grouping_map::MapForGrouping::new(self, key_mapper))
+ }
+
+ /// Return all minimum elements of an iterator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a: [i32; 0] = [];
+ /// assert_eq!(a.iter().min_set(), Vec::<&i32>::new());
+ ///
+ /// let a = [1];
+ /// assert_eq!(a.iter().min_set(), vec![&1]);
+ ///
+ /// let a = [1, 2, 3, 4, 5];
+ /// assert_eq!(a.iter().min_set(), vec![&1]);
+ ///
+ /// let a = [1, 1, 1, 1];
+ /// assert_eq!(a.iter().min_set(), vec![&1, &1, &1, &1]);
+ /// ```
+ ///
+ /// The elements can be floats but no particular result is guaranteed
+ /// if an element is NaN.
+ #[cfg(feature = "use_std")]
+ fn min_set(self) -> Vec<Self::Item>
+ where Self: Sized, Self::Item: Ord
+ {
+ extrema_set::min_set_impl(self, |_| (), |x, y, _, _| x.cmp(y))
+ }
+
+ /// Return all minimum elements of an iterator, as determined by
+ /// the specified function.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use std::cmp::Ordering;
+ /// use itertools::Itertools;
+ ///
+ /// let a: [(i32, i32); 0] = [];
+ /// assert_eq!(a.iter().min_set_by(|_, _| Ordering::Equal), Vec::<&(i32, i32)>::new());
+ ///
+ /// let a = [(1, 2)];
+ /// assert_eq!(a.iter().min_set_by(|&&(k1,_), &&(k2, _)| k1.cmp(&k2)), vec![&(1, 2)]);
+ ///
+ /// let a = [(1, 2), (2, 2), (3, 9), (4, 8), (5, 9)];
+ /// assert_eq!(a.iter().min_set_by(|&&(_,k1), &&(_,k2)| k1.cmp(&k2)), vec![&(1, 2), &(2, 2)]);
+ ///
+ /// let a = [(1, 2), (1, 3), (1, 4), (1, 5)];
+ /// assert_eq!(a.iter().min_set_by(|&&(k1,_), &&(k2, _)| k1.cmp(&k2)), vec![&(1, 2), &(1, 3), &(1, 4), &(1, 5)]);
+ /// ```
+ ///
+ /// The elements can be floats but no particular result is guaranteed
+ /// if an element is NaN.
+ #[cfg(feature = "use_std")]
+ fn min_set_by<F>(self, mut compare: F) -> Vec<Self::Item>
+ where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+ {
+ extrema_set::min_set_impl(
+ self,
+ |_| (),
+ |x, y, _, _| compare(x, y)
+ )
+ }
+
+ /// Return all minimum elements of an iterator, as determined by
+ /// the specified function.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a: [(i32, i32); 0] = [];
+ /// assert_eq!(a.iter().min_set_by_key(|_| ()), Vec::<&(i32, i32)>::new());
+ ///
+ /// let a = [(1, 2)];
+ /// assert_eq!(a.iter().min_set_by_key(|&&(k,_)| k), vec![&(1, 2)]);
+ ///
+ /// let a = [(1, 2), (2, 2), (3, 9), (4, 8), (5, 9)];
+ /// assert_eq!(a.iter().min_set_by_key(|&&(_, k)| k), vec![&(1, 2), &(2, 2)]);
+ ///
+ /// let a = [(1, 2), (1, 3), (1, 4), (1, 5)];
+ /// assert_eq!(a.iter().min_set_by_key(|&&(k, _)| k), vec![&(1, 2), &(1, 3), &(1, 4), &(1, 5)]);
+ /// ```
+ ///
+ /// The elements can be floats but no particular result is guaranteed
+ /// if an element is NaN.
+ #[cfg(feature = "use_std")]
+ fn min_set_by_key<K, F>(self, key: F) -> Vec<Self::Item>
+ where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K
+ {
+ extrema_set::min_set_impl(self, key, |_, _, kx, ky| kx.cmp(ky))
+ }
+
+ /// Return all maximum elements of an iterator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a: [i32; 0] = [];
+ /// assert_eq!(a.iter().max_set(), Vec::<&i32>::new());
+ ///
+ /// let a = [1];
+ /// assert_eq!(a.iter().max_set(), vec![&1]);
+ ///
+ /// let a = [1, 2, 3, 4, 5];
+ /// assert_eq!(a.iter().max_set(), vec![&5]);
+ ///
+ /// let a = [1, 1, 1, 1];
+ /// assert_eq!(a.iter().max_set(), vec![&1, &1, &1, &1]);
+ /// ```
+ ///
+ /// The elements can be floats but no particular result is guaranteed
+ /// if an element is NaN.
+ #[cfg(feature = "use_std")]
+ fn max_set(self) -> Vec<Self::Item>
+ where Self: Sized, Self::Item: Ord
+ {
+ extrema_set::max_set_impl(self, |_| (), |x, y, _, _| x.cmp(y))
+ }
+
+ /// Return all maximum elements of an iterator, as determined by
+ /// the specified function.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use std::cmp::Ordering;
+ /// use itertools::Itertools;
+ ///
+ /// let a: [(i32, i32); 0] = [];
+ /// assert_eq!(a.iter().max_set_by(|_, _| Ordering::Equal), Vec::<&(i32, i32)>::new());
+ ///
+ /// let a = [(1, 2)];
+ /// assert_eq!(a.iter().max_set_by(|&&(k1,_), &&(k2, _)| k1.cmp(&k2)), vec![&(1, 2)]);
+ ///
+ /// let a = [(1, 2), (2, 2), (3, 9), (4, 8), (5, 9)];
+ /// assert_eq!(a.iter().max_set_by(|&&(_,k1), &&(_,k2)| k1.cmp(&k2)), vec![&(3, 9), &(5, 9)]);
+ ///
+ /// let a = [(1, 2), (1, 3), (1, 4), (1, 5)];
+ /// assert_eq!(a.iter().max_set_by(|&&(k1,_), &&(k2, _)| k1.cmp(&k2)), vec![&(1, 2), &(1, 3), &(1, 4), &(1, 5)]);
+ /// ```
+ ///
+ /// The elements can be floats but no particular result is guaranteed
+ /// if an element is NaN.
+ #[cfg(feature = "use_std")]
+ fn max_set_by<F>(self, mut compare: F) -> Vec<Self::Item>
+ where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+ {
+ extrema_set::max_set_impl(
+ self,
+ |_| (),
+ |x, y, _, _| compare(x, y)
+ )
+ }
+
+ /// Return all maximum elements of an iterator, as determined by
+ /// the specified function.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a: [(i32, i32); 0] = [];
+ /// assert_eq!(a.iter().max_set_by_key(|_| ()), Vec::<&(i32, i32)>::new());
+ ///
+ /// let a = [(1, 2)];
+ /// assert_eq!(a.iter().max_set_by_key(|&&(k,_)| k), vec![&(1, 2)]);
+ ///
+ /// let a = [(1, 2), (2, 2), (3, 9), (4, 8), (5, 9)];
+ /// assert_eq!(a.iter().max_set_by_key(|&&(_, k)| k), vec![&(3, 9), &(5, 9)]);
+ ///
+ /// let a = [(1, 2), (1, 3), (1, 4), (1, 5)];
+ /// assert_eq!(a.iter().max_set_by_key(|&&(k, _)| k), vec![&(1, 2), &(1, 3), &(1, 4), &(1, 5)]);
+ /// ```
+ ///
+ /// The elements can be floats but no particular result is guaranteed
+ /// if an element is NaN.
+ #[cfg(feature = "use_std")]
+ fn max_set_by_key<K, F>(self, key: F) -> Vec<Self::Item>
+ where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K
+ {
+ extrema_set::max_set_impl(self, key, |_, _, kx, ky| kx.cmp(ky))
+ }
+
+ /// Return the minimum and maximum elements in the iterator.
+ ///
+ /// The return type `MinMaxResult` is an enum of three variants:
+ ///
+ /// - `NoElements` if the iterator is empty.
+ /// - `OneElement(x)` if the iterator has exactly one element.
+ /// - `MinMax(x, y)` is returned otherwise, where `x <= y`. Two
+ /// values are equal if and only if there is more than one
+ /// element in the iterator and all elements are equal.
+ ///
+ /// On an iterator of length `n`, `minmax` does `1.5 * n` comparisons,
+ /// and so is faster than calling `min` and `max` separately which does
+ /// `2 * n` comparisons.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// use itertools::MinMaxResult::{NoElements, OneElement, MinMax};
+ ///
+ /// let a: [i32; 0] = [];
+ /// assert_eq!(a.iter().minmax(), NoElements);
+ ///
+ /// let a = [1];
+ /// assert_eq!(a.iter().minmax(), OneElement(&1));
+ ///
+ /// let a = [1, 2, 3, 4, 5];
+ /// assert_eq!(a.iter().minmax(), MinMax(&1, &5));
+ ///
+ /// let a = [1, 1, 1, 1];
+ /// assert_eq!(a.iter().minmax(), MinMax(&1, &1));
+ /// ```
+ ///
+ /// The elements can be floats but no particular result is guaranteed
+ /// if an element is NaN.
+ fn minmax(self) -> MinMaxResult<Self::Item>
+ where Self: Sized, Self::Item: PartialOrd
+ {
+ minmax::minmax_impl(self, |_| (), |x, y, _, _| x < y)
+ }
+
+ /// Return the minimum and maximum element of an iterator, as determined by
+ /// the specified function.
+ ///
+ /// The return value is a variant of [`MinMaxResult`] like for [`.minmax()`](Itertools::minmax).
+ ///
+ /// For the minimum, the first minimal element is returned. For the maximum,
+ /// the last maximal element wins. This matches the behavior of the standard
+ /// [`Iterator::min`] and [`Iterator::max`] methods.
+ ///
+ /// The keys can be floats but no particular result is guaranteed
+ /// if a key is NaN.
+ fn minmax_by_key<K, F>(self, key: F) -> MinMaxResult<Self::Item>
+ where Self: Sized, K: PartialOrd, F: FnMut(&Self::Item) -> K
+ {
+ minmax::minmax_impl(self, key, |_, _, xk, yk| xk < yk)
+ }
+
+ /// Return the minimum and maximum element of an iterator, as determined by
+ /// the specified comparison function.
+ ///
+ /// The return value is a variant of [`MinMaxResult`] like for [`.minmax()`](Itertools::minmax).
+ ///
+ /// For the minimum, the first minimal element is returned. For the maximum,
+ /// the last maximal element wins. This matches the behavior of the standard
+ /// [`Iterator::min`] and [`Iterator::max`] methods.
+ fn minmax_by<F>(self, mut compare: F) -> MinMaxResult<Self::Item>
+ where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+ {
+ minmax::minmax_impl(
+ self,
+ |_| (),
+ |x, y, _, _| Ordering::Less == compare(x, y)
+ )
+ }
+
+ /// Return the position of the maximum element in the iterator.
+ ///
+ /// If several elements are equally maximum, the position of the
+ /// last of them is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a: [i32; 0] = [];
+ /// assert_eq!(a.iter().position_max(), None);
+ ///
+ /// let a = [-3, 0, 1, 5, -10];
+ /// assert_eq!(a.iter().position_max(), Some(3));
+ ///
+ /// let a = [1, 1, -1, -1];
+ /// assert_eq!(a.iter().position_max(), Some(1));
+ /// ```
+ fn position_max(self) -> Option<usize>
+ where Self: Sized, Self::Item: Ord
+ {
+ self.enumerate()
+ .max_by(|x, y| Ord::cmp(&x.1, &y.1))
+ .map(|x| x.0)
+ }
+
+ /// Return the position of the maximum element in the iterator, as
+ /// determined by the specified function.
+ ///
+ /// If several elements are equally maximum, the position of the
+ /// last of them is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a: [i32; 0] = [];
+ /// assert_eq!(a.iter().position_max_by_key(|x| x.abs()), None);
+ ///
+ /// let a = [-3_i32, 0, 1, 5, -10];
+ /// assert_eq!(a.iter().position_max_by_key(|x| x.abs()), Some(4));
+ ///
+ /// let a = [1_i32, 1, -1, -1];
+ /// assert_eq!(a.iter().position_max_by_key(|x| x.abs()), Some(3));
+ /// ```
+ fn position_max_by_key<K, F>(self, mut key: F) -> Option<usize>
+ where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K
+ {
+ self.enumerate()
+ .max_by(|x, y| Ord::cmp(&key(&x.1), &key(&y.1)))
+ .map(|x| x.0)
+ }
+
+ /// Return the position of the maximum element in the iterator, as
+ /// determined by the specified comparison function.
+ ///
+ /// If several elements are equally maximum, the position of the
+ /// last of them is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a: [i32; 0] = [];
+ /// assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), None);
+ ///
+ /// let a = [-3_i32, 0, 1, 5, -10];
+ /// assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), Some(3));
+ ///
+ /// let a = [1_i32, 1, -1, -1];
+ /// assert_eq!(a.iter().position_max_by(|x, y| x.cmp(y)), Some(1));
+ /// ```
+ fn position_max_by<F>(self, mut compare: F) -> Option<usize>
+ where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+ {
+ self.enumerate()
+ .max_by(|x, y| compare(&x.1, &y.1))
+ .map(|x| x.0)
+ }
+
+ /// Return the position of the minimum element in the iterator.
+ ///
+ /// If several elements are equally minimum, the position of the
+ /// first of them is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a: [i32; 0] = [];
+ /// assert_eq!(a.iter().position_min(), None);
+ ///
+ /// let a = [-3, 0, 1, 5, -10];
+ /// assert_eq!(a.iter().position_min(), Some(4));
+ ///
+ /// let a = [1, 1, -1, -1];
+ /// assert_eq!(a.iter().position_min(), Some(2));
+ /// ```
+ fn position_min(self) -> Option<usize>
+ where Self: Sized, Self::Item: Ord
+ {
+ self.enumerate()
+ .min_by(|x, y| Ord::cmp(&x.1, &y.1))
+ .map(|x| x.0)
+ }
+
+ /// Return the position of the minimum element in the iterator, as
+ /// determined by the specified function.
+ ///
+ /// If several elements are equally minimum, the position of the
+ /// first of them is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a: [i32; 0] = [];
+ /// assert_eq!(a.iter().position_min_by_key(|x| x.abs()), None);
+ ///
+ /// let a = [-3_i32, 0, 1, 5, -10];
+ /// assert_eq!(a.iter().position_min_by_key(|x| x.abs()), Some(1));
+ ///
+ /// let a = [1_i32, 1, -1, -1];
+ /// assert_eq!(a.iter().position_min_by_key(|x| x.abs()), Some(0));
+ /// ```
+ fn position_min_by_key<K, F>(self, mut key: F) -> Option<usize>
+ where Self: Sized, K: Ord, F: FnMut(&Self::Item) -> K
+ {
+ self.enumerate()
+ .min_by(|x, y| Ord::cmp(&key(&x.1), &key(&y.1)))
+ .map(|x| x.0)
+ }
+
+ /// Return the position of the minimum element in the iterator, as
+ /// determined by the specified comparison function.
+ ///
+ /// If several elements are equally minimum, the position of the
+ /// first of them is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let a: [i32; 0] = [];
+ /// assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), None);
+ ///
+ /// let a = [-3_i32, 0, 1, 5, -10];
+ /// assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), Some(4));
+ ///
+ /// let a = [1_i32, 1, -1, -1];
+ /// assert_eq!(a.iter().position_min_by(|x, y| x.cmp(y)), Some(2));
+ /// ```
+ fn position_min_by<F>(self, mut compare: F) -> Option<usize>
+ where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+ {
+ self.enumerate()
+ .min_by(|x, y| compare(&x.1, &y.1))
+ .map(|x| x.0)
+ }
+
+ /// Return the positions of the minimum and maximum elements in
+ /// the iterator.
+ ///
+ /// The return type [`MinMaxResult`] is an enum of three variants:
+ ///
+ /// - `NoElements` if the iterator is empty.
+ /// - `OneElement(xpos)` if the iterator has exactly one element.
+ /// - `MinMax(xpos, ypos)` is returned otherwise, where the
+ /// element at `xpos` ≤ the element at `ypos`. While the
+ /// referenced elements themselves may be equal, `xpos` cannot
+ /// be equal to `ypos`.
+ ///
+ /// On an iterator of length `n`, `position_minmax` does `1.5 * n`
+ /// comparisons, and so is faster than calling `position_min` and
+ /// `position_max` separately which does `2 * n` comparisons.
+ ///
+ /// For the minimum, if several elements are equally minimum, the
+ /// position of the first of them is returned. For the maximum, if
+ /// several elements are equally maximum, the position of the last
+ /// of them is returned.
+ ///
+ /// The elements can be floats but no particular result is
+ /// guaranteed if an element is NaN.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// use itertools::MinMaxResult::{NoElements, OneElement, MinMax};
+ ///
+ /// let a: [i32; 0] = [];
+ /// assert_eq!(a.iter().position_minmax(), NoElements);
+ ///
+ /// let a = [10];
+ /// assert_eq!(a.iter().position_minmax(), OneElement(0));
+ ///
+ /// let a = [-3, 0, 1, 5, -10];
+ /// assert_eq!(a.iter().position_minmax(), MinMax(4, 3));
+ ///
+ /// let a = [1, 1, -1, -1];
+ /// assert_eq!(a.iter().position_minmax(), MinMax(2, 1));
+ /// ```
+ fn position_minmax(self) -> MinMaxResult<usize>
+ where Self: Sized, Self::Item: PartialOrd
+ {
+ use crate::MinMaxResult::{NoElements, OneElement, MinMax};
+ match minmax::minmax_impl(self.enumerate(), |_| (), |x, y, _, _| x.1 < y.1) {
+ NoElements => NoElements,
+ OneElement(x) => OneElement(x.0),
+ MinMax(x, y) => MinMax(x.0, y.0),
+ }
+ }
+
+ /// Return the postions of the minimum and maximum elements of an
+ /// iterator, as determined by the specified function.
+ ///
+ /// The return value is a variant of [`MinMaxResult`] like for
+ /// [`position_minmax`].
+ ///
+ /// For the minimum, if several elements are equally minimum, the
+ /// position of the first of them is returned. For the maximum, if
+ /// several elements are equally maximum, the position of the last
+ /// of them is returned.
+ ///
+ /// The keys can be floats but no particular result is guaranteed
+ /// if a key is NaN.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// use itertools::MinMaxResult::{NoElements, OneElement, MinMax};
+ ///
+ /// let a: [i32; 0] = [];
+ /// assert_eq!(a.iter().position_minmax_by_key(|x| x.abs()), NoElements);
+ ///
+ /// let a = [10_i32];
+ /// assert_eq!(a.iter().position_minmax_by_key(|x| x.abs()), OneElement(0));
+ ///
+ /// let a = [-3_i32, 0, 1, 5, -10];
+ /// assert_eq!(a.iter().position_minmax_by_key(|x| x.abs()), MinMax(1, 4));
+ ///
+ /// let a = [1_i32, 1, -1, -1];
+ /// assert_eq!(a.iter().position_minmax_by_key(|x| x.abs()), MinMax(0, 3));
+ /// ```
+ ///
+ /// [`position_minmax`]: Self::position_minmax
+ fn position_minmax_by_key<K, F>(self, mut key: F) -> MinMaxResult<usize>
+ where Self: Sized, K: PartialOrd, F: FnMut(&Self::Item) -> K
+ {
+ use crate::MinMaxResult::{NoElements, OneElement, MinMax};
+ match self.enumerate().minmax_by_key(|e| key(&e.1)) {
+ NoElements => NoElements,
+ OneElement(x) => OneElement(x.0),
+ MinMax(x, y) => MinMax(x.0, y.0),
+ }
+ }
+
+ /// Return the postions of the minimum and maximum elements of an
+ /// iterator, as determined by the specified comparison function.
+ ///
+ /// The return value is a variant of [`MinMaxResult`] like for
+ /// [`position_minmax`].
+ ///
+ /// For the minimum, if several elements are equally minimum, the
+ /// position of the first of them is returned. For the maximum, if
+ /// several elements are equally maximum, the position of the last
+ /// of them is returned.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ /// use itertools::MinMaxResult::{NoElements, OneElement, MinMax};
+ ///
+ /// let a: [i32; 0] = [];
+ /// assert_eq!(a.iter().position_minmax_by(|x, y| x.cmp(y)), NoElements);
+ ///
+ /// let a = [10_i32];
+ /// assert_eq!(a.iter().position_minmax_by(|x, y| x.cmp(y)), OneElement(0));
+ ///
+ /// let a = [-3_i32, 0, 1, 5, -10];
+ /// assert_eq!(a.iter().position_minmax_by(|x, y| x.cmp(y)), MinMax(4, 3));
+ ///
+ /// let a = [1_i32, 1, -1, -1];
+ /// assert_eq!(a.iter().position_minmax_by(|x, y| x.cmp(y)), MinMax(2, 1));
+ /// ```
+ ///
+ /// [`position_minmax`]: Self::position_minmax
+ fn position_minmax_by<F>(self, mut compare: F) -> MinMaxResult<usize>
+ where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering
+ {
+ use crate::MinMaxResult::{NoElements, OneElement, MinMax};
+ match self.enumerate().minmax_by(|x, y| compare(&x.1, &y.1)) {
+ NoElements => NoElements,
+ OneElement(x) => OneElement(x.0),
+ MinMax(x, y) => MinMax(x.0, y.0),
+ }
+ }
+
+ /// If the iterator yields exactly one element, that element will be returned, otherwise
+ /// an error will be returned containing an iterator that has the same output as the input
+ /// iterator.
+ ///
+ /// This provides an additional layer of validation over just calling `Iterator::next()`.
+ /// If your assumption that there should only be one element yielded is false this provides
+ /// the opportunity to detect and handle that, preventing errors at a distance.
+ ///
+ /// # Examples
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// assert_eq!((0..10).filter(|&x| x == 2).exactly_one().unwrap(), 2);
+ /// assert!((0..10).filter(|&x| x > 1 && x < 4).exactly_one().unwrap_err().eq(2..4));
+ /// assert!((0..10).filter(|&x| x > 1 && x < 5).exactly_one().unwrap_err().eq(2..5));
+ /// assert!((0..10).filter(|&_| false).exactly_one().unwrap_err().eq(0..0));
+ /// ```
+ fn exactly_one(mut self) -> Result<Self::Item, ExactlyOneError<Self>>
+ where
+ Self: Sized,
+ {
+ match self.next() {
+ Some(first) => {
+ match self.next() {
+ Some(second) => {
+ Err(ExactlyOneError::new(Some(Either::Left([first, second])), self))
+ }
+ None => {
+ Ok(first)
+ }
+ }
+ }
+ None => Err(ExactlyOneError::new(None, self)),
+ }
+ }
+
+ /// If the iterator yields no elements, Ok(None) will be returned. If the iterator yields
+ /// exactly one element, that element will be returned, otherwise an error will be returned
+ /// containing an iterator that has the same output as the input iterator.
+ ///
+ /// This provides an additional layer of validation over just calling `Iterator::next()`.
+ /// If your assumption that there should be at most one element yielded is false this provides
+ /// the opportunity to detect and handle that, preventing errors at a distance.
+ ///
+ /// # Examples
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// assert_eq!((0..10).filter(|&x| x == 2).at_most_one().unwrap(), Some(2));
+ /// assert!((0..10).filter(|&x| x > 1 && x < 4).at_most_one().unwrap_err().eq(2..4));
+ /// assert!((0..10).filter(|&x| x > 1 && x < 5).at_most_one().unwrap_err().eq(2..5));
+ /// assert_eq!((0..10).filter(|&_| false).at_most_one().unwrap(), None);
+ /// ```
+ fn at_most_one(mut self) -> Result<Option<Self::Item>, ExactlyOneError<Self>>
+ where
+ Self: Sized,
+ {
+ match self.next() {
+ Some(first) => {
+ match self.next() {
+ Some(second) => {
+ Err(ExactlyOneError::new(Some(Either::Left([first, second])), self))
+ }
+ None => {
+ Ok(Some(first))
+ }
+ }
+ }
+ None => Ok(None),
+ }
+ }
+
+ /// An iterator adaptor that allows the user to peek at multiple `.next()`
+ /// values without advancing the base iterator.
+ ///
+ /// # Examples
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let mut iter = (0..10).multipeek();
+ /// assert_eq!(iter.peek(), Some(&0));
+ /// assert_eq!(iter.peek(), Some(&1));
+ /// assert_eq!(iter.peek(), Some(&2));
+ /// assert_eq!(iter.next(), Some(0));
+ /// assert_eq!(iter.peek(), Some(&1));
+ /// ```
+ #[cfg(feature = "use_alloc")]
+ fn multipeek(self) -> MultiPeek<Self>
+ where
+ Self: Sized,
+ {
+ multipeek_impl::multipeek(self)
+ }
+
+ /// Collect the items in this iterator and return a `HashMap` which
+ /// contains each item that appears in the iterator and the number
+ /// of times it appears.
+ ///
+ /// # Examples
+ /// ```
+ /// # use itertools::Itertools;
+ /// let counts = [1, 1, 1, 3, 3, 5].into_iter().counts();
+ /// assert_eq!(counts[&1], 3);
+ /// assert_eq!(counts[&3], 2);
+ /// assert_eq!(counts[&5], 1);
+ /// assert_eq!(counts.get(&0), None);
+ /// ```
+ #[cfg(feature = "use_std")]
+ fn counts(self) -> HashMap<Self::Item, usize>
+ where
+ Self: Sized,
+ Self::Item: Eq + Hash,
+ {
+ let mut counts = HashMap::new();
+ self.for_each(|item| *counts.entry(item).or_default() += 1);
+ counts
+ }
+
+ /// Collect the items in this iterator and return a `HashMap` which
+ /// contains each item that appears in the iterator and the number
+ /// of times it appears,
+ /// determining identity using a keying function.
+ ///
+ /// ```
+ /// # use itertools::Itertools;
+ /// struct Character {
+ /// first_name: &'static str,
+ /// last_name: &'static str,
+ /// }
+ ///
+ /// let characters =
+ /// vec![
+ /// Character { first_name: "Amy", last_name: "Pond" },
+ /// Character { first_name: "Amy", last_name: "Wong" },
+ /// Character { first_name: "Amy", last_name: "Santiago" },
+ /// Character { first_name: "James", last_name: "Bond" },
+ /// Character { first_name: "James", last_name: "Sullivan" },
+ /// Character { first_name: "James", last_name: "Norington" },
+ /// Character { first_name: "James", last_name: "Kirk" },
+ /// ];
+ ///
+ /// let first_name_frequency =
+ /// characters
+ /// .into_iter()
+ /// .counts_by(|c| c.first_name);
+ ///
+ /// assert_eq!(first_name_frequency["Amy"], 3);
+ /// assert_eq!(first_name_frequency["James"], 4);
+ /// assert_eq!(first_name_frequency.contains_key("Asha"), false);
+ /// ```
+ #[cfg(feature = "use_std")]
+ fn counts_by<K, F>(self, f: F) -> HashMap<K, usize>
+ where
+ Self: Sized,
+ K: Eq + Hash,
+ F: FnMut(Self::Item) -> K,
+ {
+ self.map(f).counts()
+ }
+
+ /// Converts an iterator of tuples into a tuple of containers.
+ ///
+ /// `unzip()` consumes an entire iterator of n-ary tuples, producing `n` collections, one for each
+ /// column.
+ ///
+ /// This function is, in some sense, the opposite of [`multizip`].
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let inputs = vec![(1, 2, 3), (4, 5, 6), (7, 8, 9)];
+ ///
+ /// let (a, b, c): (Vec<_>, Vec<_>, Vec<_>) = inputs
+ /// .into_iter()
+ /// .multiunzip();
+ ///
+ /// assert_eq!(a, vec![1, 4, 7]);
+ /// assert_eq!(b, vec![2, 5, 8]);
+ /// assert_eq!(c, vec![3, 6, 9]);
+ /// ```
+ fn multiunzip<FromI>(self) -> FromI
+ where
+ Self: Sized + MultiUnzip<FromI>,
+ {
+ MultiUnzip::multiunzip(self)
+ }
+}
+
+impl<T: ?Sized> Itertools for T where T: Iterator { }
+
+/// Return `true` if both iterables produce equal sequences
+/// (elements pairwise equal and sequences of the same length),
+/// `false` otherwise.
+///
+/// [`IntoIterator`] enabled version of [`Iterator::eq`].
+///
+/// ```
+/// assert!(itertools::equal(vec![1, 2, 3], 1..4));
+/// assert!(!itertools::equal(&[0, 0], &[0, 0, 0]));
+/// ```
+pub fn equal<I, J>(a: I, b: J) -> bool
+ where I: IntoIterator,
+ J: IntoIterator,
+ I::Item: PartialEq<J::Item>
+{
+ a.into_iter().eq(b)
+}
+
+/// Assert that two iterables produce equal sequences, with the same
+/// semantics as [`equal(a, b)`](equal).
+///
+/// **Panics** on assertion failure with a message that shows the
+/// two iteration elements.
+///
+/// ```ignore
+/// assert_equal("exceed".split('c'), "excess".split('c'));
+/// // ^PANIC: panicked at 'Failed assertion Some("eed") == Some("ess") for iteration 1',
+/// ```
+pub fn assert_equal<I, J>(a: I, b: J)
+ where I: IntoIterator,
+ J: IntoIterator,
+ I::Item: fmt::Debug + PartialEq<J::Item>,
+ J::Item: fmt::Debug,
+{
+ let mut ia = a.into_iter();
+ let mut ib = b.into_iter();
+ let mut i = 0;
+ loop {
+ match (ia.next(), ib.next()) {
+ (None, None) => return,
+ (a, b) => {
+ let equal = match (&a, &b) {
+ (&Some(ref a), &Some(ref b)) => a == b,
+ _ => false,
+ };
+ assert!(equal, "Failed assertion {a:?} == {b:?} for iteration {i}",
+ i=i, a=a, b=b);
+ i += 1;
+ }
+ }
+ }
+}
+
+/// Partition a sequence using predicate `pred` so that elements
+/// that map to `true` are placed before elements which map to `false`.
+///
+/// The order within the partitions is arbitrary.
+///
+/// Return the index of the split point.
+///
+/// ```
+/// use itertools::partition;
+///
+/// # // use repeated numbers to not promise any ordering
+/// let mut data = [7, 1, 1, 7, 1, 1, 7];
+/// let split_index = partition(&mut data, |elt| *elt >= 3);
+///
+/// assert_eq!(data, [7, 7, 7, 1, 1, 1, 1]);
+/// assert_eq!(split_index, 3);
+/// ```
+pub fn partition<'a, A: 'a, I, F>(iter: I, mut pred: F) -> usize
+ where I: IntoIterator<Item = &'a mut A>,
+ I::IntoIter: DoubleEndedIterator,
+ F: FnMut(&A) -> bool
+{
+ let mut split_index = 0;
+ let mut iter = iter.into_iter();
+ 'main: while let Some(front) = iter.next() {
+ if !pred(front) {
+ loop {
+ match iter.next_back() {
+ Some(back) => if pred(back) {
+ std::mem::swap(front, back);
+ break;
+ },
+ None => break 'main,
+ }
+ }
+ }
+ split_index += 1;
+ }
+ split_index
+}
+
+/// An enum used for controlling the execution of `fold_while`.
+///
+/// See [`.fold_while()`](Itertools::fold_while) for more information.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum FoldWhile<T> {
+ /// Continue folding with this value
+ Continue(T),
+ /// Fold is complete and will return this value
+ Done(T),
+}
+
+impl<T> FoldWhile<T> {
+ /// Return the value in the continue or done.
+ pub fn into_inner(self) -> T {
+ match self {
+ FoldWhile::Continue(x) | FoldWhile::Done(x) => x,
+ }
+ }
+
+ /// Return true if `self` is `Done`, false if it is `Continue`.
+ pub fn is_done(&self) -> bool {
+ match *self {
+ FoldWhile::Continue(_) => false,
+ FoldWhile::Done(_) => true,
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/merge_join.rs b/rust/hw/char/pl011/vendor/itertools/src/merge_join.rs
new file mode 100644
index 0000000000..84f7d03338
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/merge_join.rs
@@ -0,0 +1,220 @@
+use std::cmp::Ordering;
+use std::iter::Fuse;
+use std::fmt;
+
+use either::Either;
+
+use super::adaptors::{PutBack, put_back};
+use crate::either_or_both::EitherOrBoth;
+use crate::size_hint::{self, SizeHint};
+#[cfg(doc)]
+use crate::Itertools;
+
+/// Return an iterator adaptor that merge-joins items from the two base iterators in ascending order.
+///
+/// [`IntoIterator`] enabled version of [`Itertools::merge_join_by`].
+pub fn merge_join_by<I, J, F, T>(left: I, right: J, cmp_fn: F)
+ -> MergeJoinBy<I::IntoIter, J::IntoIter, F>
+ where I: IntoIterator,
+ J: IntoIterator,
+ F: FnMut(&I::Item, &J::Item) -> T,
+ T: OrderingOrBool<I::Item, J::Item>,
+{
+ MergeJoinBy {
+ left: put_back(left.into_iter().fuse()),
+ right: put_back(right.into_iter().fuse()),
+ cmp_fn,
+ }
+}
+
+/// An iterator adaptor that merge-joins items from the two base iterators in ascending order.
+///
+/// See [`.merge_join_by()`](crate::Itertools::merge_join_by) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct MergeJoinBy<I: Iterator, J: Iterator, F> {
+ left: PutBack<Fuse<I>>,
+ right: PutBack<Fuse<J>>,
+ cmp_fn: F,
+}
+
+pub trait OrderingOrBool<L, R> {
+ type MergeResult;
+ fn left(left: L) -> Self::MergeResult;
+ fn right(right: R) -> Self::MergeResult;
+ // "merge" never returns (Some(...), Some(...), ...) so Option<Either<I::Item, J::Item>>
+ // is appealing but it is always followed by two put_backs, so we think the compiler is
+ // smart enough to optimize it. Or we could move put_backs into "merge".
+ fn merge(self, left: L, right: R) -> (Option<L>, Option<R>, Self::MergeResult);
+ fn size_hint(left: SizeHint, right: SizeHint) -> SizeHint;
+}
+
+impl<L, R> OrderingOrBool<L, R> for Ordering {
+ type MergeResult = EitherOrBoth<L, R>;
+ fn left(left: L) -> Self::MergeResult {
+ EitherOrBoth::Left(left)
+ }
+ fn right(right: R) -> Self::MergeResult {
+ EitherOrBoth::Right(right)
+ }
+ fn merge(self, left: L, right: R) -> (Option<L>, Option<R>, Self::MergeResult) {
+ match self {
+ Ordering::Equal => (None, None, EitherOrBoth::Both(left, right)),
+ Ordering::Less => (None, Some(right), EitherOrBoth::Left(left)),
+ Ordering::Greater => (Some(left), None, EitherOrBoth::Right(right)),
+ }
+ }
+ fn size_hint(left: SizeHint, right: SizeHint) -> SizeHint {
+ let (a_lower, a_upper) = left;
+ let (b_lower, b_upper) = right;
+ let lower = ::std::cmp::max(a_lower, b_lower);
+ let upper = match (a_upper, b_upper) {
+ (Some(x), Some(y)) => x.checked_add(y),
+ _ => None,
+ };
+ (lower, upper)
+ }
+}
+
+impl<L, R> OrderingOrBool<L, R> for bool {
+ type MergeResult = Either<L, R>;
+ fn left(left: L) -> Self::MergeResult {
+ Either::Left(left)
+ }
+ fn right(right: R) -> Self::MergeResult {
+ Either::Right(right)
+ }
+ fn merge(self, left: L, right: R) -> (Option<L>, Option<R>, Self::MergeResult) {
+ if self {
+ (None, Some(right), Either::Left(left))
+ } else {
+ (Some(left), None, Either::Right(right))
+ }
+ }
+ fn size_hint(left: SizeHint, right: SizeHint) -> SizeHint {
+ // Not ExactSizeIterator because size may be larger than usize
+ size_hint::add(left, right)
+ }
+}
+
+impl<I, J, F> Clone for MergeJoinBy<I, J, F>
+ where I: Iterator,
+ J: Iterator,
+ PutBack<Fuse<I>>: Clone,
+ PutBack<Fuse<J>>: Clone,
+ F: Clone,
+{
+ clone_fields!(left, right, cmp_fn);
+}
+
+impl<I, J, F> fmt::Debug for MergeJoinBy<I, J, F>
+ where I: Iterator + fmt::Debug,
+ I::Item: fmt::Debug,
+ J: Iterator + fmt::Debug,
+ J::Item: fmt::Debug,
+{
+ debug_fmt_fields!(MergeJoinBy, left, right);
+}
+
+impl<I, J, F, T> Iterator for MergeJoinBy<I, J, F>
+ where I: Iterator,
+ J: Iterator,
+ F: FnMut(&I::Item, &J::Item) -> T,
+ T: OrderingOrBool<I::Item, J::Item>,
+{
+ type Item = T::MergeResult;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match (self.left.next(), self.right.next()) {
+ (None, None) => None,
+ (Some(left), None) => Some(T::left(left)),
+ (None, Some(right)) => Some(T::right(right)),
+ (Some(left), Some(right)) => {
+ let (left, right, next) = (self.cmp_fn)(&left, &right).merge(left, right);
+ if let Some(left) = left {
+ self.left.put_back(left);
+ }
+ if let Some(right) = right {
+ self.right.put_back(right);
+ }
+ Some(next)
+ }
+ }
+ }
+
+ fn size_hint(&self) -> SizeHint {
+ T::size_hint(self.left.size_hint(), self.right.size_hint())
+ }
+
+ fn count(mut self) -> usize {
+ let mut count = 0;
+ loop {
+ match (self.left.next(), self.right.next()) {
+ (None, None) => break count,
+ (Some(_left), None) => break count + 1 + self.left.into_parts().1.count(),
+ (None, Some(_right)) => break count + 1 + self.right.into_parts().1.count(),
+ (Some(left), Some(right)) => {
+ count += 1;
+ let (left, right, _) = (self.cmp_fn)(&left, &right).merge(left, right);
+ if let Some(left) = left {
+ self.left.put_back(left);
+ }
+ if let Some(right) = right {
+ self.right.put_back(right);
+ }
+ }
+ }
+ }
+ }
+
+ fn last(mut self) -> Option<Self::Item> {
+ let mut previous_element = None;
+ loop {
+ match (self.left.next(), self.right.next()) {
+ (None, None) => break previous_element,
+ (Some(left), None) => {
+ break Some(T::left(
+ self.left.into_parts().1.last().unwrap_or(left),
+ ))
+ }
+ (None, Some(right)) => {
+ break Some(T::right(
+ self.right.into_parts().1.last().unwrap_or(right),
+ ))
+ }
+ (Some(left), Some(right)) => {
+ let (left, right, elem) = (self.cmp_fn)(&left, &right).merge(left, right);
+ if let Some(left) = left {
+ self.left.put_back(left);
+ }
+ if let Some(right) = right {
+ self.right.put_back(right);
+ }
+ previous_element = Some(elem);
+ }
+ }
+ }
+ }
+
+ fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
+ loop {
+ if n == 0 {
+ break self.next();
+ }
+ n -= 1;
+ match (self.left.next(), self.right.next()) {
+ (None, None) => break None,
+ (Some(_left), None) => break self.left.nth(n).map(T::left),
+ (None, Some(_right)) => break self.right.nth(n).map(T::right),
+ (Some(left), Some(right)) => {
+ let (left, right, _) = (self.cmp_fn)(&left, &right).merge(left, right);
+ if let Some(left) = left {
+ self.left.put_back(left);
+ }
+ if let Some(right) = right {
+ self.right.put_back(right);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/minmax.rs b/rust/hw/char/pl011/vendor/itertools/src/minmax.rs
new file mode 100644
index 0000000000..52b2f115dd
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/minmax.rs
@@ -0,0 +1,115 @@
+
+/// `MinMaxResult` is an enum returned by `minmax`.
+///
+/// See [`.minmax()`](crate::Itertools::minmax) for more detail.
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum MinMaxResult<T> {
+ /// Empty iterator
+ NoElements,
+
+ /// Iterator with one element, so the minimum and maximum are the same
+ OneElement(T),
+
+ /// More than one element in the iterator, the first element is not larger
+ /// than the second
+ MinMax(T, T)
+}
+
+impl<T: Clone> MinMaxResult<T> {
+ /// `into_option` creates an `Option` of type `(T, T)`. The returned `Option`
+ /// has variant `None` if and only if the `MinMaxResult` has variant
+ /// `NoElements`. Otherwise `Some((x, y))` is returned where `x <= y`.
+ /// If the `MinMaxResult` has variant `OneElement(x)`, performing this
+ /// operation will make one clone of `x`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use itertools::MinMaxResult::{self, NoElements, OneElement, MinMax};
+ ///
+ /// let r: MinMaxResult<i32> = NoElements;
+ /// assert_eq!(r.into_option(), None);
+ ///
+ /// let r = OneElement(1);
+ /// assert_eq!(r.into_option(), Some((1, 1)));
+ ///
+ /// let r = MinMax(1, 2);
+ /// assert_eq!(r.into_option(), Some((1, 2)));
+ /// ```
+ pub fn into_option(self) -> Option<(T,T)> {
+ match self {
+ MinMaxResult::NoElements => None,
+ MinMaxResult::OneElement(x) => Some((x.clone(), x)),
+ MinMaxResult::MinMax(x, y) => Some((x, y))
+ }
+ }
+}
+
+/// Implementation guts for `minmax` and `minmax_by_key`.
+pub fn minmax_impl<I, K, F, L>(mut it: I, mut key_for: F,
+ mut lt: L) -> MinMaxResult<I::Item>
+ where I: Iterator,
+ F: FnMut(&I::Item) -> K,
+ L: FnMut(&I::Item, &I::Item, &K, &K) -> bool,
+{
+ let (mut min, mut max, mut min_key, mut max_key) = match it.next() {
+ None => return MinMaxResult::NoElements,
+ Some(x) => {
+ match it.next() {
+ None => return MinMaxResult::OneElement(x),
+ Some(y) => {
+ let xk = key_for(&x);
+ let yk = key_for(&y);
+ if !lt(&y, &x, &yk, &xk) {(x, y, xk, yk)} else {(y, x, yk, xk)}
+ }
+ }
+ }
+ };
+
+ loop {
+ // `first` and `second` are the two next elements we want to look
+ // at. We first compare `first` and `second` (#1). The smaller one
+ // is then compared to current minimum (#2). The larger one is
+ // compared to current maximum (#3). This way we do 3 comparisons
+ // for 2 elements.
+ let first = match it.next() {
+ None => break,
+ Some(x) => x
+ };
+ let second = match it.next() {
+ None => {
+ let first_key = key_for(&first);
+ if lt(&first, &min, &first_key, &min_key) {
+ min = first;
+ } else if !lt(&first, &max, &first_key, &max_key) {
+ max = first;
+ }
+ break;
+ }
+ Some(x) => x
+ };
+ let first_key = key_for(&first);
+ let second_key = key_for(&second);
+ if !lt(&second, &first, &second_key, &first_key) {
+ if lt(&first, &min, &first_key, &min_key) {
+ min = first;
+ min_key = first_key;
+ }
+ if !lt(&second, &max, &second_key, &max_key) {
+ max = second;
+ max_key = second_key;
+ }
+ } else {
+ if lt(&second, &min, &second_key, &min_key) {
+ min = second;
+ min_key = second_key;
+ }
+ if !lt(&first, &max, &first_key, &max_key) {
+ max = first;
+ max_key = first_key;
+ }
+ }
+ }
+
+ MinMaxResult::MinMax(min, max)
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/multipeek_impl.rs b/rust/hw/char/pl011/vendor/itertools/src/multipeek_impl.rs
new file mode 100644
index 0000000000..8b49c695eb
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/multipeek_impl.rs
@@ -0,0 +1,101 @@
+use std::iter::Fuse;
+use alloc::collections::VecDeque;
+use crate::size_hint;
+use crate::PeekingNext;
+#[cfg(doc)]
+use crate::Itertools;
+
+/// See [`multipeek()`] for more information.
+#[derive(Clone, Debug)]
+pub struct MultiPeek<I>
+ where I: Iterator
+{
+ iter: Fuse<I>,
+ buf: VecDeque<I::Item>,
+ index: usize,
+}
+
+/// An iterator adaptor that allows the user to peek at multiple `.next()`
+/// values without advancing the base iterator.
+///
+/// [`IntoIterator`] enabled version of [`Itertools::multipeek`].
+pub fn multipeek<I>(iterable: I) -> MultiPeek<I::IntoIter>
+ where I: IntoIterator
+{
+ MultiPeek {
+ iter: iterable.into_iter().fuse(),
+ buf: VecDeque::new(),
+ index: 0,
+ }
+}
+
+impl<I> MultiPeek<I>
+ where I: Iterator
+{
+ /// Reset the peeking “cursor”
+ pub fn reset_peek(&mut self) {
+ self.index = 0;
+ }
+}
+
+impl<I: Iterator> MultiPeek<I> {
+ /// Works exactly like `.next()` with the only difference that it doesn't
+ /// advance itself. `.peek()` can be called multiple times, to peek
+ /// further ahead.
+ /// When `.next()` is called, reset the peeking “cursor”.
+ pub fn peek(&mut self) -> Option<&I::Item> {
+ let ret = if self.index < self.buf.len() {
+ Some(&self.buf[self.index])
+ } else {
+ match self.iter.next() {
+ Some(x) => {
+ self.buf.push_back(x);
+ Some(&self.buf[self.index])
+ }
+ None => return None,
+ }
+ };
+
+ self.index += 1;
+ ret
+ }
+}
+
+impl<I> PeekingNext for MultiPeek<I>
+ where I: Iterator,
+{
+ fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+ where F: FnOnce(&Self::Item) -> bool
+ {
+ if self.buf.is_empty() {
+ if let Some(r) = self.peek() {
+ if !accept(r) { return None }
+ }
+ } else if let Some(r) = self.buf.get(0) {
+ if !accept(r) { return None }
+ }
+ self.next()
+ }
+}
+
+impl<I> Iterator for MultiPeek<I>
+ where I: Iterator
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.index = 0;
+ self.buf.pop_front().or_else(|| self.iter.next())
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ size_hint::add_scalar(self.iter.size_hint(), self.buf.len())
+ }
+}
+
+// Same size
+impl<I> ExactSizeIterator for MultiPeek<I>
+ where I: ExactSizeIterator
+{}
+
+
diff --git a/rust/hw/char/pl011/vendor/itertools/src/pad_tail.rs b/rust/hw/char/pl011/vendor/itertools/src/pad_tail.rs
new file mode 100644
index 0000000000..248a432436
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/pad_tail.rs
@@ -0,0 +1,96 @@
+use std::iter::{Fuse, FusedIterator};
+use crate::size_hint;
+
+/// An iterator adaptor that pads a sequence to a minimum length by filling
+/// missing elements using a closure.
+///
+/// Iterator element type is `I::Item`.
+///
+/// See [`.pad_using()`](crate::Itertools::pad_using) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct PadUsing<I, F> {
+ iter: Fuse<I>,
+ min: usize,
+ pos: usize,
+ filler: F,
+}
+
+impl<I, F> std::fmt::Debug for PadUsing<I, F>
+where
+ I: std::fmt::Debug,
+{
+ debug_fmt_fields!(PadUsing, iter, min, pos);
+}
+
+/// Create a new `PadUsing` iterator.
+pub fn pad_using<I, F>(iter: I, min: usize, filler: F) -> PadUsing<I, F>
+ where I: Iterator,
+ F: FnMut(usize) -> I::Item
+{
+ PadUsing {
+ iter: iter.fuse(),
+ min,
+ pos: 0,
+ filler,
+ }
+}
+
+impl<I, F> Iterator for PadUsing<I, F>
+ where I: Iterator,
+ F: FnMut(usize) -> I::Item
+{
+ type Item = I::Item;
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.iter.next() {
+ None => {
+ if self.pos < self.min {
+ let e = Some((self.filler)(self.pos));
+ self.pos += 1;
+ e
+ } else {
+ None
+ }
+ },
+ e => {
+ self.pos += 1;
+ e
+ }
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let tail = self.min.saturating_sub(self.pos);
+ size_hint::max(self.iter.size_hint(), (tail, Some(tail)))
+ }
+}
+
+impl<I, F> DoubleEndedIterator for PadUsing<I, F>
+ where I: DoubleEndedIterator + ExactSizeIterator,
+ F: FnMut(usize) -> I::Item
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ if self.min == 0 {
+ self.iter.next_back()
+ } else if self.iter.len() >= self.min {
+ self.min -= 1;
+ self.iter.next_back()
+ } else {
+ self.min -= 1;
+ Some((self.filler)(self.min))
+ }
+ }
+}
+
+impl<I, F> ExactSizeIterator for PadUsing<I, F>
+ where I: ExactSizeIterator,
+ F: FnMut(usize) -> I::Item
+{}
+
+
+impl<I, F> FusedIterator for PadUsing<I, F>
+ where I: FusedIterator,
+ F: FnMut(usize) -> I::Item
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/peek_nth.rs b/rust/hw/char/pl011/vendor/itertools/src/peek_nth.rs
new file mode 100644
index 0000000000..bcca45838e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/peek_nth.rs
@@ -0,0 +1,102 @@
+use crate::size_hint;
+use crate::PeekingNext;
+use alloc::collections::VecDeque;
+use std::iter::Fuse;
+
+/// See [`peek_nth()`] for more information.
+#[derive(Clone, Debug)]
+pub struct PeekNth<I>
+where
+ I: Iterator,
+{
+ iter: Fuse<I>,
+ buf: VecDeque<I::Item>,
+}
+
+/// A drop-in replacement for [`std::iter::Peekable`] which adds a `peek_nth`
+/// method allowing the user to `peek` at a value several iterations forward
+/// without advancing the base iterator.
+///
+/// This differs from `multipeek` in that subsequent calls to `peek` or
+/// `peek_nth` will always return the same value until `next` is called
+/// (making `reset_peek` unnecessary).
+pub fn peek_nth<I>(iterable: I) -> PeekNth<I::IntoIter>
+where
+ I: IntoIterator,
+{
+ PeekNth {
+ iter: iterable.into_iter().fuse(),
+ buf: VecDeque::new(),
+ }
+}
+
+impl<I> PeekNth<I>
+where
+ I: Iterator,
+{
+ /// Works exactly like the `peek` method in `std::iter::Peekable`
+ pub fn peek(&mut self) -> Option<&I::Item> {
+ self.peek_nth(0)
+ }
+
+ /// Returns a reference to the `nth` value without advancing the iterator.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```rust
+ /// use itertools::peek_nth;
+ ///
+ /// let xs = vec![1,2,3];
+ /// let mut iter = peek_nth(xs.iter());
+ ///
+ /// assert_eq!(iter.peek_nth(0), Some(&&1));
+ /// assert_eq!(iter.next(), Some(&1));
+ ///
+ /// // The iterator does not advance even if we call `peek_nth` multiple times
+ /// assert_eq!(iter.peek_nth(0), Some(&&2));
+ /// assert_eq!(iter.peek_nth(1), Some(&&3));
+ /// assert_eq!(iter.next(), Some(&2));
+ ///
+ /// // Calling `peek_nth` past the end of the iterator will return `None`
+ /// assert_eq!(iter.peek_nth(1), None);
+ /// ```
+ pub fn peek_nth(&mut self, n: usize) -> Option<&I::Item> {
+ let unbuffered_items = (n + 1).saturating_sub(self.buf.len());
+
+ self.buf.extend(self.iter.by_ref().take(unbuffered_items));
+
+ self.buf.get(n)
+ }
+}
+
+impl<I> Iterator for PeekNth<I>
+where
+ I: Iterator,
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.buf.pop_front().or_else(|| self.iter.next())
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ size_hint::add_scalar(self.iter.size_hint(), self.buf.len())
+ }
+}
+
+impl<I> ExactSizeIterator for PeekNth<I> where I: ExactSizeIterator {}
+
+impl<I> PeekingNext for PeekNth<I>
+where
+ I: Iterator,
+{
+ fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+ where
+ F: FnOnce(&Self::Item) -> bool,
+ {
+ self.peek().filter(|item| accept(item))?;
+ self.next()
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/peeking_take_while.rs b/rust/hw/char/pl011/vendor/itertools/src/peeking_take_while.rs
new file mode 100644
index 0000000000..3a37228122
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/peeking_take_while.rs
@@ -0,0 +1,177 @@
+use std::iter::Peekable;
+use crate::PutBack;
+#[cfg(feature = "use_alloc")]
+use crate::PutBackN;
+
+/// An iterator that allows peeking at an element before deciding to accept it.
+///
+/// See [`.peeking_take_while()`](crate::Itertools::peeking_take_while)
+/// for more information.
+///
+/// This is implemented by peeking adaptors like peekable and put back,
+/// but also by a few iterators that can be peeked natively, like the slice’s
+/// by reference iterator (`std::slice::Iter`).
+pub trait PeekingNext : Iterator {
+ /// Pass a reference to the next iterator element to the closure `accept`;
+ /// if `accept` returns true, return it as the next element,
+ /// else None.
+ fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+ where Self: Sized,
+ F: FnOnce(&Self::Item) -> bool;
+}
+
+impl<'a, I> PeekingNext for &'a mut I
+ where I: PeekingNext,
+{
+ fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+ where F: FnOnce(&Self::Item) -> bool
+ {
+ (*self).peeking_next(accept)
+ }
+}
+
+impl<I> PeekingNext for Peekable<I>
+ where I: Iterator,
+{
+ fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+ where F: FnOnce(&Self::Item) -> bool
+ {
+ if let Some(r) = self.peek() {
+ if !accept(r) {
+ return None;
+ }
+ }
+ self.next()
+ }
+}
+
+impl<I> PeekingNext for PutBack<I>
+ where I: Iterator,
+{
+ fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+ where F: FnOnce(&Self::Item) -> bool
+ {
+ if let Some(r) = self.next() {
+ if !accept(&r) {
+ self.put_back(r);
+ return None;
+ }
+ Some(r)
+ } else {
+ None
+ }
+ }
+}
+
+#[cfg(feature = "use_alloc")]
+impl<I> PeekingNext for PutBackN<I>
+ where I: Iterator,
+{
+ fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+ where F: FnOnce(&Self::Item) -> bool
+ {
+ if let Some(r) = self.next() {
+ if !accept(&r) {
+ self.put_back(r);
+ return None;
+ }
+ Some(r)
+ } else {
+ None
+ }
+ }
+}
+
+/// An iterator adaptor that takes items while a closure returns `true`.
+///
+/// See [`.peeking_take_while()`](crate::Itertools::peeking_take_while)
+/// for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct PeekingTakeWhile<'a, I: 'a, F>
+ where I: Iterator,
+{
+ iter: &'a mut I,
+ f: F,
+}
+
+impl<'a, I: 'a, F> std::fmt::Debug for PeekingTakeWhile<'a, I, F>
+where
+ I: Iterator + std::fmt::Debug,
+{
+ debug_fmt_fields!(PeekingTakeWhile, iter);
+}
+
+/// Create a `PeekingTakeWhile`
+pub fn peeking_take_while<I, F>(iter: &mut I, f: F) -> PeekingTakeWhile<I, F>
+ where I: Iterator,
+{
+ PeekingTakeWhile {
+ iter,
+ f,
+ }
+}
+
+impl<'a, I, F> Iterator for PeekingTakeWhile<'a, I, F>
+ where I: PeekingNext,
+ F: FnMut(&I::Item) -> bool,
+
+{
+ type Item = I::Item;
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.peeking_next(&mut self.f)
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (0, self.iter.size_hint().1)
+ }
+}
+
+impl<'a, I, F> PeekingNext for PeekingTakeWhile<'a, I, F>
+ where I: PeekingNext,
+ F: FnMut(&I::Item) -> bool,
+{
+ fn peeking_next<G>(&mut self, g: G) -> Option<Self::Item>
+ where G: FnOnce(&Self::Item) -> bool,
+ {
+ let f = &mut self.f;
+ self.iter.peeking_next(|r| f(r) && g(r))
+ }
+}
+
+// Some iterators are so lightweight we can simply clone them to save their
+// state and use that for peeking.
+macro_rules! peeking_next_by_clone {
+ ([$($typarm:tt)*] $type_:ty) => {
+ impl<$($typarm)*> PeekingNext for $type_ {
+ fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
+ where F: FnOnce(&Self::Item) -> bool
+ {
+ let saved_state = self.clone();
+ if let Some(r) = self.next() {
+ if !accept(&r) {
+ *self = saved_state;
+ } else {
+ return Some(r)
+ }
+ }
+ None
+ }
+ }
+ }
+}
+
+peeking_next_by_clone! { ['a, T] ::std::slice::Iter<'a, T> }
+peeking_next_by_clone! { ['a] ::std::str::Chars<'a> }
+peeking_next_by_clone! { ['a] ::std::str::CharIndices<'a> }
+peeking_next_by_clone! { ['a] ::std::str::Bytes<'a> }
+peeking_next_by_clone! { ['a, T] ::std::option::Iter<'a, T> }
+peeking_next_by_clone! { ['a, T] ::std::result::Iter<'a, T> }
+peeking_next_by_clone! { [T] ::std::iter::Empty<T> }
+#[cfg(feature = "use_alloc")]
+peeking_next_by_clone! { ['a, T] alloc::collections::linked_list::Iter<'a, T> }
+#[cfg(feature = "use_alloc")]
+peeking_next_by_clone! { ['a, T] alloc::collections::vec_deque::Iter<'a, T> }
+
+// cloning a Rev has no extra overhead; peekable and put backs are never DEI.
+peeking_next_by_clone! { [I: Clone + PeekingNext + DoubleEndedIterator]
+ ::std::iter::Rev<I> }
diff --git a/rust/hw/char/pl011/vendor/itertools/src/permutations.rs b/rust/hw/char/pl011/vendor/itertools/src/permutations.rs
new file mode 100644
index 0000000000..d03b852626
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/permutations.rs
@@ -0,0 +1,277 @@
+use alloc::vec::Vec;
+use std::fmt;
+use std::iter::once;
+
+use super::lazy_buffer::LazyBuffer;
+
+/// An iterator adaptor that iterates through all the `k`-permutations of the
+/// elements from an iterator.
+///
+/// See [`.permutations()`](crate::Itertools::permutations) for
+/// more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Permutations<I: Iterator> {
+ vals: LazyBuffer<I>,
+ state: PermutationState,
+}
+
+impl<I> Clone for Permutations<I>
+ where I: Clone + Iterator,
+ I::Item: Clone,
+{
+ clone_fields!(vals, state);
+}
+
+#[derive(Clone, Debug)]
+enum PermutationState {
+ StartUnknownLen {
+ k: usize,
+ },
+ OngoingUnknownLen {
+ k: usize,
+ min_n: usize,
+ },
+ Complete(CompleteState),
+ Empty,
+}
+
+#[derive(Clone, Debug)]
+enum CompleteState {
+ Start {
+ n: usize,
+ k: usize,
+ },
+ Ongoing {
+ indices: Vec<usize>,
+ cycles: Vec<usize>,
+ }
+}
+
+enum CompleteStateRemaining {
+ Known(usize),
+ Overflow,
+}
+
+impl<I> fmt::Debug for Permutations<I>
+ where I: Iterator + fmt::Debug,
+ I::Item: fmt::Debug,
+{
+ debug_fmt_fields!(Permutations, vals, state);
+}
+
+pub fn permutations<I: Iterator>(iter: I, k: usize) -> Permutations<I> {
+ let mut vals = LazyBuffer::new(iter);
+
+ if k == 0 {
+ // Special case, yields single empty vec; `n` is irrelevant
+ let state = PermutationState::Complete(CompleteState::Start { n: 0, k: 0 });
+
+ return Permutations {
+ vals,
+ state
+ };
+ }
+
+ let mut enough_vals = true;
+
+ while vals.len() < k {
+ if !vals.get_next() {
+ enough_vals = false;
+ break;
+ }
+ }
+
+ let state = if enough_vals {
+ PermutationState::StartUnknownLen { k }
+ } else {
+ PermutationState::Empty
+ };
+
+ Permutations {
+ vals,
+ state
+ }
+}
+
+impl<I> Iterator for Permutations<I>
+where
+ I: Iterator,
+ I::Item: Clone
+{
+ type Item = Vec<I::Item>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.advance();
+
+ let &mut Permutations { ref vals, ref state } = self;
+
+ match *state {
+ PermutationState::StartUnknownLen { .. } => panic!("unexpected iterator state"),
+ PermutationState::OngoingUnknownLen { k, min_n } => {
+ let latest_idx = min_n - 1;
+ let indices = (0..(k - 1)).chain(once(latest_idx));
+
+ Some(indices.map(|i| vals[i].clone()).collect())
+ }
+ PermutationState::Complete(CompleteState::Ongoing { ref indices, ref cycles }) => {
+ let k = cycles.len();
+ Some(indices[0..k].iter().map(|&i| vals[i].clone()).collect())
+ },
+ PermutationState::Complete(CompleteState::Start { .. }) | PermutationState::Empty => None
+ }
+ }
+
+ fn count(self) -> usize {
+ fn from_complete(complete_state: CompleteState) -> usize {
+ match complete_state.remaining() {
+ CompleteStateRemaining::Known(count) => count,
+ CompleteStateRemaining::Overflow => {
+ panic!("Iterator count greater than usize::MAX");
+ }
+ }
+ }
+
+ let Permutations { vals, state } = self;
+ match state {
+ PermutationState::StartUnknownLen { k } => {
+ let n = vals.len() + vals.it.count();
+ let complete_state = CompleteState::Start { n, k };
+
+ from_complete(complete_state)
+ }
+ PermutationState::OngoingUnknownLen { k, min_n } => {
+ let prev_iteration_count = min_n - k + 1;
+ let n = vals.len() + vals.it.count();
+ let complete_state = CompleteState::Start { n, k };
+
+ from_complete(complete_state) - prev_iteration_count
+ },
+ PermutationState::Complete(state) => from_complete(state),
+ PermutationState::Empty => 0
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ match self.state {
+ PermutationState::StartUnknownLen { .. } |
+ PermutationState::OngoingUnknownLen { .. } => (0, None), // TODO can we improve this lower bound?
+ PermutationState::Complete(ref state) => match state.remaining() {
+ CompleteStateRemaining::Known(count) => (count, Some(count)),
+ CompleteStateRemaining::Overflow => (::std::usize::MAX, None)
+ }
+ PermutationState::Empty => (0, Some(0))
+ }
+ }
+}
+
+impl<I> Permutations<I>
+where
+ I: Iterator,
+ I::Item: Clone
+{
+ fn advance(&mut self) {
+ let &mut Permutations { ref mut vals, ref mut state } = self;
+
+ *state = match *state {
+ PermutationState::StartUnknownLen { k } => {
+ PermutationState::OngoingUnknownLen { k, min_n: k }
+ }
+ PermutationState::OngoingUnknownLen { k, min_n } => {
+ if vals.get_next() {
+ PermutationState::OngoingUnknownLen { k, min_n: min_n + 1 }
+ } else {
+ let n = min_n;
+ let prev_iteration_count = n - k + 1;
+ let mut complete_state = CompleteState::Start { n, k };
+
+ // Advance the complete-state iterator to the correct point
+ for _ in 0..(prev_iteration_count + 1) {
+ complete_state.advance();
+ }
+
+ PermutationState::Complete(complete_state)
+ }
+ }
+ PermutationState::Complete(ref mut state) => {
+ state.advance();
+
+ return;
+ }
+ PermutationState::Empty => { return; }
+ };
+ }
+}
+
+impl CompleteState {
+ fn advance(&mut self) {
+ *self = match *self {
+ CompleteState::Start { n, k } => {
+ let indices = (0..n).collect();
+ let cycles = ((n - k)..n).rev().collect();
+
+ CompleteState::Ongoing {
+ cycles,
+ indices
+ }
+ },
+ CompleteState::Ongoing { ref mut indices, ref mut cycles } => {
+ let n = indices.len();
+ let k = cycles.len();
+
+ for i in (0..k).rev() {
+ if cycles[i] == 0 {
+ cycles[i] = n - i - 1;
+
+ let to_push = indices.remove(i);
+ indices.push(to_push);
+ } else {
+ let swap_index = n - cycles[i];
+ indices.swap(i, swap_index);
+
+ cycles[i] -= 1;
+ return;
+ }
+ }
+
+ CompleteState::Start { n, k }
+ }
+ }
+ }
+
+ fn remaining(&self) -> CompleteStateRemaining {
+ use self::CompleteStateRemaining::{Known, Overflow};
+
+ match *self {
+ CompleteState::Start { n, k } => {
+ if n < k {
+ return Known(0);
+ }
+
+ let count: Option<usize> = (n - k + 1..n + 1).fold(Some(1), |acc, i| {
+ acc.and_then(|acc| acc.checked_mul(i))
+ });
+
+ match count {
+ Some(count) => Known(count),
+ None => Overflow
+ }
+ }
+ CompleteState::Ongoing { ref indices, ref cycles } => {
+ let mut count: usize = 0;
+
+ for (i, &c) in cycles.iter().enumerate() {
+ let radix = indices.len() - i;
+ let next_count = count.checked_mul(radix)
+ .and_then(|count| count.checked_add(c));
+
+ count = match next_count {
+ Some(count) => count,
+ None => { return Overflow; }
+ };
+ }
+
+ Known(count)
+ }
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/powerset.rs b/rust/hw/char/pl011/vendor/itertools/src/powerset.rs
new file mode 100644
index 0000000000..4d7685b12a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/powerset.rs
@@ -0,0 +1,90 @@
+use std::fmt;
+use std::iter::FusedIterator;
+use std::usize;
+use alloc::vec::Vec;
+
+use super::combinations::{Combinations, combinations};
+use super::size_hint;
+
+/// An iterator to iterate through the powerset of the elements from an iterator.
+///
+/// See [`.powerset()`](crate::Itertools::powerset) for more
+/// information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Powerset<I: Iterator> {
+ combs: Combinations<I>,
+ // Iterator `position` (equal to count of yielded elements).
+ pos: usize,
+}
+
+impl<I> Clone for Powerset<I>
+ where I: Clone + Iterator,
+ I::Item: Clone,
+{
+ clone_fields!(combs, pos);
+}
+
+impl<I> fmt::Debug for Powerset<I>
+ where I: Iterator + fmt::Debug,
+ I::Item: fmt::Debug,
+{
+ debug_fmt_fields!(Powerset, combs, pos);
+}
+
+/// Create a new `Powerset` from a clonable iterator.
+pub fn powerset<I>(src: I) -> Powerset<I>
+ where I: Iterator,
+ I::Item: Clone,
+{
+ Powerset {
+ combs: combinations(src, 0),
+ pos: 0,
+ }
+}
+
+impl<I> Iterator for Powerset<I>
+ where
+ I: Iterator,
+ I::Item: Clone,
+{
+ type Item = Vec<I::Item>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if let Some(elt) = self.combs.next() {
+ self.pos = self.pos.saturating_add(1);
+ Some(elt)
+ } else if self.combs.k() < self.combs.n()
+ || self.combs.k() == 0
+ {
+ self.combs.reset(self.combs.k() + 1);
+ self.combs.next().map(|elt| {
+ self.pos = self.pos.saturating_add(1);
+ elt
+ })
+ } else {
+ None
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ // Total bounds for source iterator.
+ let src_total = size_hint::add_scalar(self.combs.src().size_hint(), self.combs.n());
+
+ // Total bounds for self ( length(powerset(set) == 2 ^ length(set) )
+ let self_total = size_hint::pow_scalar_base(2, src_total);
+
+ if self.pos < usize::MAX {
+ // Subtract count of elements already yielded from total.
+ size_hint::sub_scalar(self_total, self.pos)
+ } else {
+ // Fallback: self.pos is saturated and no longer reliable.
+ (0, self_total.1)
+ }
+ }
+}
+
+impl<I> FusedIterator for Powerset<I>
+ where
+ I: Iterator,
+ I::Item: Clone,
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/process_results_impl.rs b/rust/hw/char/pl011/vendor/itertools/src/process_results_impl.rs
new file mode 100644
index 0000000000..713db45514
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/process_results_impl.rs
@@ -0,0 +1,68 @@
+#[cfg(doc)]
+use crate::Itertools;
+
+/// An iterator that produces only the `T` values as long as the
+/// inner iterator produces `Ok(T)`.
+///
+/// Used by [`process_results`](crate::process_results), see its docs
+/// for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Debug)]
+pub struct ProcessResults<'a, I, E: 'a> {
+ error: &'a mut Result<(), E>,
+ iter: I,
+}
+
+impl<'a, I, T, E> Iterator for ProcessResults<'a, I, E>
+ where I: Iterator<Item = Result<T, E>>
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.iter.next() {
+ Some(Ok(x)) => Some(x),
+ Some(Err(e)) => {
+ *self.error = Err(e);
+ None
+ }
+ None => None,
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (0, self.iter.size_hint().1)
+ }
+
+ fn fold<B, F>(mut self, init: B, mut f: F) -> B
+ where
+ Self: Sized,
+ F: FnMut(B, Self::Item) -> B,
+ {
+ let error = self.error;
+ self.iter
+ .try_fold(init, |acc, opt| match opt {
+ Ok(x) => Ok(f(acc, x)),
+ Err(e) => {
+ *error = Err(e);
+ Err(acc)
+ }
+ })
+ .unwrap_or_else(|e| e)
+ }
+}
+
+/// “Lift” a function of the values of an iterator so that it can process
+/// an iterator of `Result` values instead.
+///
+/// [`IntoIterator`] enabled version of [`Itertools::process_results`].
+pub fn process_results<I, F, T, E, R>(iterable: I, processor: F) -> Result<R, E>
+ where I: IntoIterator<Item = Result<T, E>>,
+ F: FnOnce(ProcessResults<I::IntoIter, E>) -> R
+{
+ let iter = iterable.into_iter();
+ let mut error = Ok(());
+
+ let result = processor(ProcessResults { error: &mut error, iter });
+
+ error.map(|_| result)
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/put_back_n_impl.rs b/rust/hw/char/pl011/vendor/itertools/src/put_back_n_impl.rs
new file mode 100644
index 0000000000..60ea8e6495
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/put_back_n_impl.rs
@@ -0,0 +1,61 @@
+use alloc::vec::Vec;
+
+use crate::size_hint;
+
+/// An iterator adaptor that allows putting multiple
+/// items in front of the iterator.
+///
+/// Iterator element type is `I::Item`.
+#[derive(Debug, Clone)]
+pub struct PutBackN<I: Iterator> {
+ top: Vec<I::Item>,
+ iter: I,
+}
+
+/// Create an iterator where you can put back multiple values to the front
+/// of the iteration.
+///
+/// Iterator element type is `I::Item`.
+pub fn put_back_n<I>(iterable: I) -> PutBackN<I::IntoIter>
+ where I: IntoIterator
+{
+ PutBackN {
+ top: Vec::new(),
+ iter: iterable.into_iter(),
+ }
+}
+
+impl<I: Iterator> PutBackN<I> {
+ /// Puts x in front of the iterator.
+ /// The values are yielded in order of the most recently put back
+ /// values first.
+ ///
+ /// ```rust
+ /// use itertools::put_back_n;
+ ///
+ /// let mut it = put_back_n(1..5);
+ /// it.next();
+ /// it.put_back(1);
+ /// it.put_back(0);
+ ///
+ /// assert!(itertools::equal(it, 0..5));
+ /// ```
+ #[inline]
+ pub fn put_back(&mut self, x: I::Item) {
+ self.top.push(x);
+ }
+}
+
+impl<I: Iterator> Iterator for PutBackN<I> {
+ type Item = I::Item;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.top.pop().or_else(|| self.iter.next())
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ size_hint::add_scalar(self.iter.size_hint(), self.top.len())
+ }
+}
+
diff --git a/rust/hw/char/pl011/vendor/itertools/src/rciter_impl.rs b/rust/hw/char/pl011/vendor/itertools/src/rciter_impl.rs
new file mode 100644
index 0000000000..7298350a88
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/rciter_impl.rs
@@ -0,0 +1,99 @@
+
+use std::iter::{FusedIterator, IntoIterator};
+use alloc::rc::Rc;
+use std::cell::RefCell;
+
+/// A wrapper for `Rc<RefCell<I>>`, that implements the `Iterator` trait.
+#[derive(Debug)]
+pub struct RcIter<I> {
+ /// The boxed iterator.
+ pub rciter: Rc<RefCell<I>>,
+}
+
+/// Return an iterator inside a `Rc<RefCell<_>>` wrapper.
+///
+/// The returned `RcIter` can be cloned, and each clone will refer back to the
+/// same original iterator.
+///
+/// `RcIter` allows doing interesting things like using `.zip()` on an iterator with
+/// itself, at the cost of runtime borrow checking which may have a performance
+/// penalty.
+///
+/// Iterator element type is `Self::Item`.
+///
+/// ```
+/// use itertools::rciter;
+/// use itertools::zip;
+///
+/// // In this example a range iterator is created and we iterate it using
+/// // three separate handles (two of them given to zip).
+/// // We also use the IntoIterator implementation for `&RcIter`.
+///
+/// let mut iter = rciter(0..9);
+/// let mut z = zip(&iter, &iter);
+///
+/// assert_eq!(z.next(), Some((0, 1)));
+/// assert_eq!(z.next(), Some((2, 3)));
+/// assert_eq!(z.next(), Some((4, 5)));
+/// assert_eq!(iter.next(), Some(6));
+/// assert_eq!(z.next(), Some((7, 8)));
+/// assert_eq!(z.next(), None);
+/// ```
+///
+/// **Panics** in iterator methods if a borrow error is encountered in the
+/// iterator methods. It can only happen if the `RcIter` is reentered in
+/// `.next()`, i.e. if it somehow participates in an “iterator knot”
+/// where it is an adaptor of itself.
+pub fn rciter<I>(iterable: I) -> RcIter<I::IntoIter>
+ where I: IntoIterator
+{
+ RcIter { rciter: Rc::new(RefCell::new(iterable.into_iter())) }
+}
+
+impl<I> Clone for RcIter<I> {
+ clone_fields!(rciter);
+}
+
+impl<A, I> Iterator for RcIter<I>
+ where I: Iterator<Item = A>
+{
+ type Item = A;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.rciter.borrow_mut().next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ // To work sanely with other API that assume they own an iterator,
+ // so it can't change in other places, we can't guarantee as much
+ // in our size_hint. Other clones may drain values under our feet.
+ (0, self.rciter.borrow().size_hint().1)
+ }
+}
+
+impl<I> DoubleEndedIterator for RcIter<I>
+ where I: DoubleEndedIterator
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.rciter.borrow_mut().next_back()
+ }
+}
+
+/// Return an iterator from `&RcIter<I>` (by simply cloning it).
+impl<'a, I> IntoIterator for &'a RcIter<I>
+ where I: Iterator
+{
+ type Item = I::Item;
+ type IntoIter = RcIter<I>;
+
+ fn into_iter(self) -> RcIter<I> {
+ self.clone()
+ }
+}
+
+
+impl<A, I> FusedIterator for RcIter<I>
+ where I: FusedIterator<Item = A>
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/repeatn.rs b/rust/hw/char/pl011/vendor/itertools/src/repeatn.rs
new file mode 100644
index 0000000000..e025f6f6a5
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/repeatn.rs
@@ -0,0 +1,59 @@
+use std::iter::FusedIterator;
+
+/// An iterator that produces *n* repetitions of an element.
+///
+/// See [`repeat_n()`](crate::repeat_n) for more information.
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+#[derive(Clone, Debug)]
+pub struct RepeatN<A> {
+ elt: Option<A>,
+ n: usize,
+}
+
+/// Create an iterator that produces `n` repetitions of `element`.
+pub fn repeat_n<A>(element: A, n: usize) -> RepeatN<A>
+ where A: Clone,
+{
+ if n == 0 {
+ RepeatN { elt: None, n, }
+ } else {
+ RepeatN { elt: Some(element), n, }
+ }
+}
+
+impl<A> Iterator for RepeatN<A>
+ where A: Clone
+{
+ type Item = A;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.n > 1 {
+ self.n -= 1;
+ self.elt.as_ref().cloned()
+ } else {
+ self.n = 0;
+ self.elt.take()
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.n, Some(self.n))
+ }
+}
+
+impl<A> DoubleEndedIterator for RepeatN<A>
+ where A: Clone
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.next()
+ }
+}
+
+impl<A> ExactSizeIterator for RepeatN<A>
+ where A: Clone
+{}
+
+impl<A> FusedIterator for RepeatN<A>
+ where A: Clone
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/size_hint.rs b/rust/hw/char/pl011/vendor/itertools/src/size_hint.rs
new file mode 100644
index 0000000000..71ea1412b5
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/size_hint.rs
@@ -0,0 +1,119 @@
+//! Arithmetic on `Iterator.size_hint()` values.
+//!
+
+use std::usize;
+use std::cmp;
+use std::u32;
+
+/// `SizeHint` is the return type of `Iterator::size_hint()`.
+pub type SizeHint = (usize, Option<usize>);
+
+/// Add `SizeHint` correctly.
+#[inline]
+pub fn add(a: SizeHint, b: SizeHint) -> SizeHint {
+ let min = a.0.saturating_add(b.0);
+ let max = match (a.1, b.1) {
+ (Some(x), Some(y)) => x.checked_add(y),
+ _ => None,
+ };
+
+ (min, max)
+}
+
+/// Add `x` correctly to a `SizeHint`.
+#[inline]
+pub fn add_scalar(sh: SizeHint, x: usize) -> SizeHint {
+ let (mut low, mut hi) = sh;
+ low = low.saturating_add(x);
+ hi = hi.and_then(|elt| elt.checked_add(x));
+ (low, hi)
+}
+
+/// Subtract `x` correctly from a `SizeHint`.
+#[inline]
+#[allow(dead_code)]
+pub fn sub_scalar(sh: SizeHint, x: usize) -> SizeHint {
+ let (mut low, mut hi) = sh;
+ low = low.saturating_sub(x);
+ hi = hi.map(|elt| elt.saturating_sub(x));
+ (low, hi)
+}
+
+
+/// Multiply `SizeHint` correctly
+///
+/// ```ignore
+/// use std::usize;
+/// use itertools::size_hint;
+///
+/// assert_eq!(size_hint::mul((3, Some(4)), (3, Some(4))),
+/// (9, Some(16)));
+///
+/// assert_eq!(size_hint::mul((3, Some(4)), (usize::MAX, None)),
+/// (usize::MAX, None));
+///
+/// assert_eq!(size_hint::mul((3, None), (0, Some(0))),
+/// (0, Some(0)));
+/// ```
+#[inline]
+pub fn mul(a: SizeHint, b: SizeHint) -> SizeHint {
+ let low = a.0.saturating_mul(b.0);
+ let hi = match (a.1, b.1) {
+ (Some(x), Some(y)) => x.checked_mul(y),
+ (Some(0), None) | (None, Some(0)) => Some(0),
+ _ => None,
+ };
+ (low, hi)
+}
+
+/// Multiply `x` correctly with a `SizeHint`.
+#[inline]
+pub fn mul_scalar(sh: SizeHint, x: usize) -> SizeHint {
+ let (mut low, mut hi) = sh;
+ low = low.saturating_mul(x);
+ hi = hi.and_then(|elt| elt.checked_mul(x));
+ (low, hi)
+}
+
+/// Raise `base` correctly by a `SizeHint` exponent.
+#[inline]
+pub fn pow_scalar_base(base: usize, exp: SizeHint) -> SizeHint {
+ let exp_low = cmp::min(exp.0, u32::MAX as usize) as u32;
+ let low = base.saturating_pow(exp_low);
+
+ let hi = exp.1.and_then(|exp| {
+ let exp_hi = cmp::min(exp, u32::MAX as usize) as u32;
+ base.checked_pow(exp_hi)
+ });
+
+ (low, hi)
+}
+
+/// Return the maximum
+#[inline]
+pub fn max(a: SizeHint, b: SizeHint) -> SizeHint {
+ let (a_lower, a_upper) = a;
+ let (b_lower, b_upper) = b;
+
+ let lower = cmp::max(a_lower, b_lower);
+
+ let upper = match (a_upper, b_upper) {
+ (Some(x), Some(y)) => Some(cmp::max(x, y)),
+ _ => None,
+ };
+
+ (lower, upper)
+}
+
+/// Return the minimum
+#[inline]
+pub fn min(a: SizeHint, b: SizeHint) -> SizeHint {
+ let (a_lower, a_upper) = a;
+ let (b_lower, b_upper) = b;
+ let lower = cmp::min(a_lower, b_lower);
+ let upper = match (a_upper, b_upper) {
+ (Some(u1), Some(u2)) => Some(cmp::min(u1, u2)),
+ _ => a_upper.or(b_upper),
+ };
+ (lower, upper)
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/sources.rs b/rust/hw/char/pl011/vendor/itertools/src/sources.rs
new file mode 100644
index 0000000000..3877ce3c8b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/sources.rs
@@ -0,0 +1,183 @@
+//! Iterators that are sources (produce elements from parameters,
+//! not from another iterator).
+#![allow(deprecated)]
+
+use std::fmt;
+use std::mem;
+
+/// See [`repeat_call`](crate::repeat_call) for more information.
+#[derive(Clone)]
+#[deprecated(note="Use std repeat_with() instead", since="0.8.0")]
+pub struct RepeatCall<F> {
+ f: F,
+}
+
+impl<F> fmt::Debug for RepeatCall<F>
+{
+ debug_fmt_fields!(RepeatCall, );
+}
+
+/// An iterator source that produces elements indefinitely by calling
+/// a given closure.
+///
+/// Iterator element type is the return type of the closure.
+///
+/// ```
+/// use itertools::repeat_call;
+/// use itertools::Itertools;
+/// use std::collections::BinaryHeap;
+///
+/// let mut heap = BinaryHeap::from(vec![2, 5, 3, 7, 8]);
+///
+/// // extract each element in sorted order
+/// for element in repeat_call(|| heap.pop()).while_some() {
+/// print!("{}", element);
+/// }
+///
+/// itertools::assert_equal(
+/// repeat_call(|| 1).take(5),
+/// vec![1, 1, 1, 1, 1]
+/// );
+/// ```
+#[deprecated(note="Use std repeat_with() instead", since="0.8.0")]
+pub fn repeat_call<F, A>(function: F) -> RepeatCall<F>
+ where F: FnMut() -> A
+{
+ RepeatCall { f: function }
+}
+
+impl<A, F> Iterator for RepeatCall<F>
+ where F: FnMut() -> A
+{
+ type Item = A;
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ Some((self.f)())
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (usize::max_value(), None)
+ }
+}
+
+/// Creates a new unfold source with the specified closure as the "iterator
+/// function" and an initial state to eventually pass to the closure
+///
+/// `unfold` is a general iterator builder: it has a mutable state value,
+/// and a closure with access to the state that produces the next value.
+///
+/// This more or less equivalent to a regular struct with an [`Iterator`]
+/// implementation, and is useful for one-off iterators.
+///
+/// ```
+/// // an iterator that yields sequential Fibonacci numbers,
+/// // and stops at the maximum representable value.
+///
+/// use itertools::unfold;
+///
+/// let mut fibonacci = unfold((1u32, 1u32), |(x1, x2)| {
+/// // Attempt to get the next Fibonacci number
+/// let next = x1.saturating_add(*x2);
+///
+/// // Shift left: ret <- x1 <- x2 <- next
+/// let ret = *x1;
+/// *x1 = *x2;
+/// *x2 = next;
+///
+/// // If addition has saturated at the maximum, we are finished
+/// if ret == *x1 && ret > 1 {
+/// None
+/// } else {
+/// Some(ret)
+/// }
+/// });
+///
+/// itertools::assert_equal(fibonacci.by_ref().take(8),
+/// vec![1, 1, 2, 3, 5, 8, 13, 21]);
+/// assert_eq!(fibonacci.last(), Some(2_971_215_073))
+/// ```
+pub fn unfold<A, St, F>(initial_state: St, f: F) -> Unfold<St, F>
+ where F: FnMut(&mut St) -> Option<A>
+{
+ Unfold {
+ f,
+ state: initial_state,
+ }
+}
+
+impl<St, F> fmt::Debug for Unfold<St, F>
+ where St: fmt::Debug,
+{
+ debug_fmt_fields!(Unfold, state);
+}
+
+/// See [`unfold`](crate::unfold) for more information.
+#[derive(Clone)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+pub struct Unfold<St, F> {
+ f: F,
+ /// Internal state that will be passed to the closure on the next iteration
+ pub state: St,
+}
+
+impl<A, St, F> Iterator for Unfold<St, F>
+ where F: FnMut(&mut St) -> Option<A>
+{
+ type Item = A;
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ (self.f)(&mut self.state)
+ }
+}
+
+/// An iterator that infinitely applies function to value and yields results.
+///
+/// This `struct` is created by the [`iterate()`](crate::iterate) function.
+/// See its documentation for more.
+#[derive(Clone)]
+#[must_use = "iterators are lazy and do nothing unless consumed"]
+pub struct Iterate<St, F> {
+ state: St,
+ f: F,
+}
+
+impl<St, F> fmt::Debug for Iterate<St, F>
+ where St: fmt::Debug,
+{
+ debug_fmt_fields!(Iterate, state);
+}
+
+impl<St, F> Iterator for Iterate<St, F>
+ where F: FnMut(&St) -> St
+{
+ type Item = St;
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ let next_state = (self.f)(&self.state);
+ Some(mem::replace(&mut self.state, next_state))
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (usize::max_value(), None)
+ }
+}
+
+/// Creates a new iterator that infinitely applies function to value and yields results.
+///
+/// ```
+/// use itertools::iterate;
+///
+/// itertools::assert_equal(iterate(1, |&i| i * 3).take(5), vec![1, 3, 9, 27, 81]);
+/// ```
+pub fn iterate<St, F>(initial_value: St, f: F) -> Iterate<St, F>
+ where F: FnMut(&St) -> St
+{
+ Iterate {
+ state: initial_value,
+ f,
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/take_while_inclusive.rs b/rust/hw/char/pl011/vendor/itertools/src/take_while_inclusive.rs
new file mode 100644
index 0000000000..e2a7479e0b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/take_while_inclusive.rs
@@ -0,0 +1,68 @@
+use core::iter::FusedIterator;
+use std::fmt;
+
+/// An iterator adaptor that consumes elements while the given predicate is
+/// `true`, including the element for which the predicate first returned
+/// `false`.
+///
+/// See [`.take_while_inclusive()`](crate::Itertools::take_while_inclusive)
+/// for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct TakeWhileInclusive<'a, I: 'a, F> {
+ iter: &'a mut I,
+ predicate: F,
+ done: bool,
+}
+
+impl<'a, I, F> TakeWhileInclusive<'a, I, F>
+where
+ I: Iterator,
+ F: FnMut(&I::Item) -> bool,
+{
+ /// Create a new [`TakeWhileInclusive`] from an iterator and a predicate.
+ pub fn new(iter: &'a mut I, predicate: F) -> Self {
+ Self { iter, predicate, done: false}
+ }
+}
+
+impl<'a, I, F> fmt::Debug for TakeWhileInclusive<'a, I, F>
+ where I: Iterator + fmt::Debug,
+{
+ debug_fmt_fields!(TakeWhileInclusive, iter);
+}
+
+impl<'a, I, F> Iterator for TakeWhileInclusive<'a, I, F>
+where
+ I: Iterator,
+ F: FnMut(&I::Item) -> bool
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.done {
+ None
+ } else {
+ self.iter.next().map(|item| {
+ if !(self.predicate)(&item) {
+ self.done = true;
+ }
+ item
+ })
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ if self.done {
+ (0, Some(0))
+ } else {
+ (0, self.iter.size_hint().1)
+ }
+ }
+}
+
+impl<I, F> FusedIterator for TakeWhileInclusive<'_, I, F>
+where
+ I: Iterator,
+ F: FnMut(&I::Item) -> bool
+{
+}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/itertools/src/tee.rs b/rust/hw/char/pl011/vendor/itertools/src/tee.rs
new file mode 100644
index 0000000000..ea4752906f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/tee.rs
@@ -0,0 +1,78 @@
+use super::size_hint;
+
+use std::cell::RefCell;
+use alloc::collections::VecDeque;
+use alloc::rc::Rc;
+
+/// Common buffer object for the two tee halves
+#[derive(Debug)]
+struct TeeBuffer<A, I> {
+ backlog: VecDeque<A>,
+ iter: I,
+ /// The owner field indicates which id should read from the backlog
+ owner: bool,
+}
+
+/// One half of an iterator pair where both return the same elements.
+///
+/// See [`.tee()`](crate::Itertools::tee) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Debug)]
+pub struct Tee<I>
+ where I: Iterator
+{
+ rcbuffer: Rc<RefCell<TeeBuffer<I::Item, I>>>,
+ id: bool,
+}
+
+pub fn new<I>(iter: I) -> (Tee<I>, Tee<I>)
+ where I: Iterator
+{
+ let buffer = TeeBuffer{backlog: VecDeque::new(), iter, owner: false};
+ let t1 = Tee{rcbuffer: Rc::new(RefCell::new(buffer)), id: true};
+ let t2 = Tee{rcbuffer: t1.rcbuffer.clone(), id: false};
+ (t1, t2)
+}
+
+impl<I> Iterator for Tee<I>
+ where I: Iterator,
+ I::Item: Clone
+{
+ type Item = I::Item;
+ fn next(&mut self) -> Option<Self::Item> {
+ // .borrow_mut may fail here -- but only if the user has tied some kind of weird
+ // knot where the iterator refers back to itself.
+ let mut buffer = self.rcbuffer.borrow_mut();
+ if buffer.owner == self.id {
+ match buffer.backlog.pop_front() {
+ None => {}
+ some_elt => return some_elt,
+ }
+ }
+ match buffer.iter.next() {
+ None => None,
+ Some(elt) => {
+ buffer.backlog.push_back(elt.clone());
+ buffer.owner = !self.id;
+ Some(elt)
+ }
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let buffer = self.rcbuffer.borrow();
+ let sh = buffer.iter.size_hint();
+
+ if buffer.owner == self.id {
+ let log_len = buffer.backlog.len();
+ size_hint::add_scalar(sh, log_len)
+ } else {
+ sh
+ }
+ }
+}
+
+impl<I> ExactSizeIterator for Tee<I>
+ where I: ExactSizeIterator,
+ I::Item: Clone
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/tuple_impl.rs b/rust/hw/char/pl011/vendor/itertools/src/tuple_impl.rs
new file mode 100644
index 0000000000..fdf0865856
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/tuple_impl.rs
@@ -0,0 +1,331 @@
+//! Some iterator that produces tuples
+
+use std::iter::Fuse;
+use std::iter::FusedIterator;
+use std::iter::Take;
+use std::iter::Cycle;
+use std::marker::PhantomData;
+
+// `HomogeneousTuple` is a public facade for `TupleCollect`, allowing
+// tuple-related methods to be used by clients in generic contexts, while
+// hiding the implementation details of `TupleCollect`.
+// See https://github.com/rust-itertools/itertools/issues/387
+
+/// Implemented for homogeneous tuples of size up to 12.
+pub trait HomogeneousTuple
+ : TupleCollect
+{}
+
+impl<T: TupleCollect> HomogeneousTuple for T {}
+
+/// An iterator over a incomplete tuple.
+///
+/// See [`.tuples()`](crate::Itertools::tuples) and
+/// [`Tuples::into_buffer()`].
+#[derive(Clone, Debug)]
+pub struct TupleBuffer<T>
+ where T: HomogeneousTuple
+{
+ cur: usize,
+ buf: T::Buffer,
+}
+
+impl<T> TupleBuffer<T>
+ where T: HomogeneousTuple
+{
+ fn new(buf: T::Buffer) -> Self {
+ TupleBuffer {
+ cur: 0,
+ buf,
+ }
+ }
+}
+
+impl<T> Iterator for TupleBuffer<T>
+ where T: HomogeneousTuple
+{
+ type Item = T::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let s = self.buf.as_mut();
+ if let Some(ref mut item) = s.get_mut(self.cur) {
+ self.cur += 1;
+ item.take()
+ } else {
+ None
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let buffer = &self.buf.as_ref()[self.cur..];
+ let len = if buffer.is_empty() {
+ 0
+ } else {
+ buffer.iter()
+ .position(|x| x.is_none())
+ .unwrap_or_else(|| buffer.len())
+ };
+ (len, Some(len))
+ }
+}
+
+impl<T> ExactSizeIterator for TupleBuffer<T>
+ where T: HomogeneousTuple
+{
+}
+
+/// An iterator that groups the items in tuples of a specific size.
+///
+/// See [`.tuples()`](crate::Itertools::tuples) for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Tuples<I, T>
+ where I: Iterator<Item = T::Item>,
+ T: HomogeneousTuple
+{
+ iter: Fuse<I>,
+ buf: T::Buffer,
+}
+
+/// Create a new tuples iterator.
+pub fn tuples<I, T>(iter: I) -> Tuples<I, T>
+ where I: Iterator<Item = T::Item>,
+ T: HomogeneousTuple
+{
+ Tuples {
+ iter: iter.fuse(),
+ buf: Default::default(),
+ }
+}
+
+impl<I, T> Iterator for Tuples<I, T>
+ where I: Iterator<Item = T::Item>,
+ T: HomogeneousTuple
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ T::collect_from_iter(&mut self.iter, &mut self.buf)
+ }
+}
+
+impl<I, T> Tuples<I, T>
+ where I: Iterator<Item = T::Item>,
+ T: HomogeneousTuple
+{
+ /// Return a buffer with the produced items that was not enough to be grouped in a tuple.
+ ///
+ /// ```
+ /// use itertools::Itertools;
+ ///
+ /// let mut iter = (0..5).tuples();
+ /// assert_eq!(Some((0, 1, 2)), iter.next());
+ /// assert_eq!(None, iter.next());
+ /// itertools::assert_equal(vec![3, 4], iter.into_buffer());
+ /// ```
+ pub fn into_buffer(self) -> TupleBuffer<T> {
+ TupleBuffer::new(self.buf)
+ }
+}
+
+
+/// An iterator over all contiguous windows that produces tuples of a specific size.
+///
+/// See [`.tuple_windows()`](crate::Itertools::tuple_windows) for more
+/// information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Clone, Debug)]
+pub struct TupleWindows<I, T>
+ where I: Iterator<Item = T::Item>,
+ T: HomogeneousTuple
+{
+ iter: I,
+ last: Option<T>,
+}
+
+/// Create a new tuple windows iterator.
+pub fn tuple_windows<I, T>(mut iter: I) -> TupleWindows<I, T>
+ where I: Iterator<Item = T::Item>,
+ T: HomogeneousTuple,
+ T::Item: Clone
+{
+ use std::iter::once;
+
+ let mut last = None;
+ if T::num_items() != 1 {
+ // put in a duplicate item in front of the tuple; this simplifies
+ // .next() function.
+ if let Some(item) = iter.next() {
+ let iter = once(item.clone()).chain(once(item)).chain(&mut iter);
+ last = T::collect_from_iter_no_buf(iter);
+ }
+ }
+
+ TupleWindows {
+ iter,
+ last,
+ }
+}
+
+impl<I, T> Iterator for TupleWindows<I, T>
+ where I: Iterator<Item = T::Item>,
+ T: HomogeneousTuple + Clone,
+ T::Item: Clone
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if T::num_items() == 1 {
+ return T::collect_from_iter_no_buf(&mut self.iter)
+ }
+ if let Some(ref mut last) = self.last {
+ if let Some(new) = self.iter.next() {
+ last.left_shift_push(new);
+ return Some(last.clone());
+ }
+ }
+ None
+ }
+}
+
+impl<I, T> FusedIterator for TupleWindows<I, T>
+ where I: FusedIterator<Item = T::Item>,
+ T: HomogeneousTuple + Clone,
+ T::Item: Clone
+{}
+
+/// An iterator over all windows, wrapping back to the first elements when the
+/// window would otherwise exceed the length of the iterator, producing tuples
+/// of a specific size.
+///
+/// See [`.circular_tuple_windows()`](crate::Itertools::circular_tuple_windows) for more
+/// information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Debug, Clone)]
+pub struct CircularTupleWindows<I, T: Clone>
+ where I: Iterator<Item = T::Item> + Clone,
+ T: TupleCollect + Clone
+{
+ iter: Take<TupleWindows<Cycle<I>, T>>,
+ phantom_data: PhantomData<T>
+}
+
+pub fn circular_tuple_windows<I, T>(iter: I) -> CircularTupleWindows<I, T>
+ where I: Iterator<Item = T::Item> + Clone + ExactSizeIterator,
+ T: TupleCollect + Clone,
+ T::Item: Clone
+{
+ let len = iter.len();
+ let iter = tuple_windows(iter.cycle()).take(len);
+
+ CircularTupleWindows {
+ iter,
+ phantom_data: PhantomData{}
+ }
+}
+
+impl<I, T> Iterator for CircularTupleWindows<I, T>
+ where I: Iterator<Item = T::Item> + Clone,
+ T: TupleCollect + Clone,
+ T::Item: Clone
+{
+ type Item = T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next()
+ }
+}
+
+pub trait TupleCollect: Sized {
+ type Item;
+ type Buffer: Default + AsRef<[Option<Self::Item>]> + AsMut<[Option<Self::Item>]>;
+
+ fn collect_from_iter<I>(iter: I, buf: &mut Self::Buffer) -> Option<Self>
+ where I: IntoIterator<Item = Self::Item>;
+
+ fn collect_from_iter_no_buf<I>(iter: I) -> Option<Self>
+ where I: IntoIterator<Item = Self::Item>;
+
+ fn num_items() -> usize;
+
+ fn left_shift_push(&mut self, item: Self::Item);
+}
+
+macro_rules! count_ident{
+ () => {0};
+ ($i0:ident, $($i:ident,)*) => {1 + count_ident!($($i,)*)};
+}
+macro_rules! rev_for_each_ident{
+ ($m:ident, ) => {};
+ ($m:ident, $i0:ident, $($i:ident,)*) => {
+ rev_for_each_ident!($m, $($i,)*);
+ $m!($i0);
+ };
+}
+
+macro_rules! impl_tuple_collect {
+ ($dummy:ident,) => {}; // stop
+ ($dummy:ident, $($Y:ident,)*) => (
+ impl_tuple_collect!($($Y,)*);
+ impl<A> TupleCollect for ($(ignore_ident!($Y, A),)*) {
+ type Item = A;
+ type Buffer = [Option<A>; count_ident!($($Y,)*) - 1];
+
+ #[allow(unused_assignments, unused_mut)]
+ fn collect_from_iter<I>(iter: I, buf: &mut Self::Buffer) -> Option<Self>
+ where I: IntoIterator<Item = A>
+ {
+ let mut iter = iter.into_iter();
+ $(
+ let mut $Y = None;
+ )*
+
+ loop {
+ $(
+ $Y = iter.next();
+ if $Y.is_none() {
+ break
+ }
+ )*
+ return Some(($($Y.unwrap()),*,))
+ }
+
+ let mut i = 0;
+ let mut s = buf.as_mut();
+ $(
+ if i < s.len() {
+ s[i] = $Y;
+ i += 1;
+ }
+ )*
+ return None;
+ }
+
+ fn collect_from_iter_no_buf<I>(iter: I) -> Option<Self>
+ where I: IntoIterator<Item = A>
+ {
+ let mut iter = iter.into_iter();
+
+ Some(($(
+ { let $Y = iter.next()?; $Y },
+ )*))
+ }
+
+ fn num_items() -> usize {
+ count_ident!($($Y,)*)
+ }
+
+ fn left_shift_push(&mut self, mut item: A) {
+ use std::mem::replace;
+
+ let &mut ($(ref mut $Y),*,) = self;
+ macro_rules! replace_item{($i:ident) => {
+ item = replace($i, item);
+ }}
+ rev_for_each_ident!(replace_item, $($Y,)*);
+ drop(item);
+ }
+ }
+ )
+}
+impl_tuple_collect!(dummy, a, b, c, d, e, f, g, h, i, j, k, l,);
diff --git a/rust/hw/char/pl011/vendor/itertools/src/unique_impl.rs b/rust/hw/char/pl011/vendor/itertools/src/unique_impl.rs
new file mode 100644
index 0000000000..4e81e78ec0
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/unique_impl.rs
@@ -0,0 +1,179 @@
+use std::collections::HashMap;
+use std::collections::hash_map::Entry;
+use std::hash::Hash;
+use std::fmt;
+use std::iter::FusedIterator;
+
+/// An iterator adapter to filter out duplicate elements.
+///
+/// See [`.unique_by()`](crate::Itertools::unique) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct UniqueBy<I: Iterator, V, F> {
+ iter: I,
+ // Use a Hashmap for the Entry API in order to prevent hashing twice.
+ // This can maybe be replaced with a HashSet once `get_or_insert_with`
+ // or a proper Entry API for Hashset is stable and meets this msrv
+ used: HashMap<V, ()>,
+ f: F,
+}
+
+impl<I, V, F> fmt::Debug for UniqueBy<I, V, F>
+ where I: Iterator + fmt::Debug,
+ V: fmt::Debug + Hash + Eq,
+{
+ debug_fmt_fields!(UniqueBy, iter, used);
+}
+
+/// Create a new `UniqueBy` iterator.
+pub fn unique_by<I, V, F>(iter: I, f: F) -> UniqueBy<I, V, F>
+ where V: Eq + Hash,
+ F: FnMut(&I::Item) -> V,
+ I: Iterator,
+{
+ UniqueBy {
+ iter,
+ used: HashMap::new(),
+ f,
+ }
+}
+
+// count the number of new unique keys in iterable (`used` is the set already seen)
+fn count_new_keys<I, K>(mut used: HashMap<K, ()>, iterable: I) -> usize
+ where I: IntoIterator<Item=K>,
+ K: Hash + Eq,
+{
+ let iter = iterable.into_iter();
+ let current_used = used.len();
+ used.extend(iter.map(|key| (key, ())));
+ used.len() - current_used
+}
+
+impl<I, V, F> Iterator for UniqueBy<I, V, F>
+ where I: Iterator,
+ V: Eq + Hash,
+ F: FnMut(&I::Item) -> V
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ while let Some(v) = self.iter.next() {
+ let key = (self.f)(&v);
+ if self.used.insert(key, ()).is_none() {
+ return Some(v);
+ }
+ }
+ None
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (low, hi) = self.iter.size_hint();
+ ((low > 0 && self.used.is_empty()) as usize, hi)
+ }
+
+ fn count(self) -> usize {
+ let mut key_f = self.f;
+ count_new_keys(self.used, self.iter.map(move |elt| key_f(&elt)))
+ }
+}
+
+impl<I, V, F> DoubleEndedIterator for UniqueBy<I, V, F>
+ where I: DoubleEndedIterator,
+ V: Eq + Hash,
+ F: FnMut(&I::Item) -> V
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ while let Some(v) = self.iter.next_back() {
+ let key = (self.f)(&v);
+ if self.used.insert(key, ()).is_none() {
+ return Some(v);
+ }
+ }
+ None
+ }
+}
+
+impl<I, V, F> FusedIterator for UniqueBy<I, V, F>
+ where I: FusedIterator,
+ V: Eq + Hash,
+ F: FnMut(&I::Item) -> V
+{}
+
+impl<I> Iterator for Unique<I>
+ where I: Iterator,
+ I::Item: Eq + Hash + Clone
+{
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ while let Some(v) = self.iter.iter.next() {
+ if let Entry::Vacant(entry) = self.iter.used.entry(v) {
+ let elt = entry.key().clone();
+ entry.insert(());
+ return Some(elt);
+ }
+ }
+ None
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (low, hi) = self.iter.iter.size_hint();
+ ((low > 0 && self.iter.used.is_empty()) as usize, hi)
+ }
+
+ fn count(self) -> usize {
+ count_new_keys(self.iter.used, self.iter.iter)
+ }
+}
+
+impl<I> DoubleEndedIterator for Unique<I>
+ where I: DoubleEndedIterator,
+ I::Item: Eq + Hash + Clone
+{
+ fn next_back(&mut self) -> Option<Self::Item> {
+ while let Some(v) = self.iter.iter.next_back() {
+ if let Entry::Vacant(entry) = self.iter.used.entry(v) {
+ let elt = entry.key().clone();
+ entry.insert(());
+ return Some(elt);
+ }
+ }
+ None
+ }
+}
+
+impl<I> FusedIterator for Unique<I>
+ where I: FusedIterator,
+ I::Item: Eq + Hash + Clone
+{}
+
+/// An iterator adapter to filter out duplicate elements.
+///
+/// See [`.unique()`](crate::Itertools::unique) for more information.
+#[derive(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Unique<I: Iterator> {
+ iter: UniqueBy<I, I::Item, ()>,
+}
+
+impl<I> fmt::Debug for Unique<I>
+ where I: Iterator + fmt::Debug,
+ I::Item: Hash + Eq + fmt::Debug,
+{
+ debug_fmt_fields!(Unique, iter);
+}
+
+pub fn unique<I>(iter: I) -> Unique<I>
+ where I: Iterator,
+ I::Item: Eq + Hash,
+{
+ Unique {
+ iter: UniqueBy {
+ iter,
+ used: HashMap::new(),
+ f: (),
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/unziptuple.rs b/rust/hw/char/pl011/vendor/itertools/src/unziptuple.rs
new file mode 100644
index 0000000000..7af29ec4ab
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/unziptuple.rs
@@ -0,0 +1,80 @@
+/// Converts an iterator of tuples into a tuple of containers.
+///
+/// `unzip()` consumes an entire iterator of n-ary tuples, producing `n` collections, one for each
+/// column.
+///
+/// This function is, in some sense, the opposite of [`multizip`].
+///
+/// ```
+/// use itertools::multiunzip;
+///
+/// let inputs = vec![(1, 2, 3), (4, 5, 6), (7, 8, 9)];
+///
+/// let (a, b, c): (Vec<_>, Vec<_>, Vec<_>) = multiunzip(inputs);
+///
+/// assert_eq!(a, vec![1, 4, 7]);
+/// assert_eq!(b, vec![2, 5, 8]);
+/// assert_eq!(c, vec![3, 6, 9]);
+/// ```
+///
+/// [`multizip`]: crate::multizip
+pub fn multiunzip<FromI, I>(i: I) -> FromI
+where
+ I: IntoIterator,
+ I::IntoIter: MultiUnzip<FromI>,
+{
+ i.into_iter().multiunzip()
+}
+
+/// An iterator that can be unzipped into multiple collections.
+///
+/// See [`.multiunzip()`](crate::Itertools::multiunzip) for more information.
+pub trait MultiUnzip<FromI>: Iterator {
+ /// Unzip this iterator into multiple collections.
+ fn multiunzip(self) -> FromI;
+}
+
+macro_rules! impl_unzip_iter {
+ ($($T:ident => $FromT:ident),*) => (
+ #[allow(non_snake_case)]
+ impl<IT: Iterator<Item = ($($T,)*)>, $($T, $FromT: Default + Extend<$T>),* > MultiUnzip<($($FromT,)*)> for IT {
+ fn multiunzip(self) -> ($($FromT,)*) {
+ // This implementation mirrors the logic of Iterator::unzip resp. Extend for (A, B) as close as possible.
+ // Unfortunately a lot of the used api there is still unstable (https://github.com/rust-lang/rust/issues/72631).
+ //
+ // Iterator::unzip: https://doc.rust-lang.org/src/core/iter/traits/iterator.rs.html#2825-2865
+ // Extend for (A, B): https://doc.rust-lang.org/src/core/iter/traits/collect.rs.html#370-411
+
+ let mut res = ($($FromT::default(),)*);
+ let ($($FromT,)*) = &mut res;
+
+ // Still unstable #72631
+ // let (lower_bound, _) = self.size_hint();
+ // if lower_bound > 0 {
+ // $($FromT.extend_reserve(lower_bound);)*
+ // }
+
+ self.fold((), |(), ($($T,)*)| {
+ // Still unstable #72631
+ // $( $FromT.extend_one($T); )*
+ $( $FromT.extend(std::iter::once($T)); )*
+ });
+ res
+ }
+ }
+ );
+}
+
+impl_unzip_iter!();
+impl_unzip_iter!(A => FromA);
+impl_unzip_iter!(A => FromA, B => FromB);
+impl_unzip_iter!(A => FromA, B => FromB, C => FromC);
+impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD);
+impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE);
+impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF);
+impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF, G => FromG);
+impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF, G => FromG, H => FromH);
+impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF, G => FromG, H => FromH, I => FromI);
+impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF, G => FromG, H => FromH, I => FromI, J => FromJ);
+impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF, G => FromG, H => FromH, I => FromI, J => FromJ, K => FromK);
+impl_unzip_iter!(A => FromA, B => FromB, C => FromC, D => FromD, E => FromE, F => FromF, G => FromG, H => FromH, I => FromI, J => FromJ, K => FromK, L => FromL);
diff --git a/rust/hw/char/pl011/vendor/itertools/src/with_position.rs b/rust/hw/char/pl011/vendor/itertools/src/with_position.rs
new file mode 100644
index 0000000000..dda9b25dc3
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/with_position.rs
@@ -0,0 +1,88 @@
+use std::iter::{Fuse,Peekable, FusedIterator};
+
+/// An iterator adaptor that wraps each element in an [`Position`].
+///
+/// Iterator element type is `(Position, I::Item)`.
+///
+/// See [`.with_position()`](crate::Itertools::with_position) for more information.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct WithPosition<I>
+ where I: Iterator,
+{
+ handled_first: bool,
+ peekable: Peekable<Fuse<I>>,
+}
+
+impl<I> Clone for WithPosition<I>
+ where I: Clone + Iterator,
+ I::Item: Clone,
+{
+ clone_fields!(handled_first, peekable);
+}
+
+/// Create a new `WithPosition` iterator.
+pub fn with_position<I>(iter: I) -> WithPosition<I>
+ where I: Iterator,
+{
+ WithPosition {
+ handled_first: false,
+ peekable: iter.fuse().peekable(),
+ }
+}
+
+/// The first component of the value yielded by `WithPosition`.
+/// Indicates the position of this element in the iterator results.
+///
+/// See [`.with_position()`](crate::Itertools::with_position) for more information.
+#[derive(Copy, Clone, Debug, PartialEq)]
+pub enum Position {
+ /// This is the first element.
+ First,
+ /// This is neither the first nor the last element.
+ Middle,
+ /// This is the last element.
+ Last,
+ /// This is the only element.
+ Only,
+}
+
+impl<I: Iterator> Iterator for WithPosition<I> {
+ type Item = (Position, I::Item);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.peekable.next() {
+ Some(item) => {
+ if !self.handled_first {
+ // Haven't seen the first item yet, and there is one to give.
+ self.handled_first = true;
+ // Peek to see if this is also the last item,
+ // in which case tag it as `Only`.
+ match self.peekable.peek() {
+ Some(_) => Some((Position::First, item)),
+ None => Some((Position::Only, item)),
+ }
+ } else {
+ // Have seen the first item, and there's something left.
+ // Peek to see if this is the last item.
+ match self.peekable.peek() {
+ Some(_) => Some((Position::Middle, item)),
+ None => Some((Position::Last, item)),
+ }
+ }
+ }
+ // Iterator is finished.
+ None => None,
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.peekable.size_hint()
+ }
+}
+
+impl<I> ExactSizeIterator for WithPosition<I>
+ where I: ExactSizeIterator,
+{ }
+
+impl<I: Iterator> FusedIterator for WithPosition<I>
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/zip_eq_impl.rs b/rust/hw/char/pl011/vendor/itertools/src/zip_eq_impl.rs
new file mode 100644
index 0000000000..a079b326a4
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/zip_eq_impl.rs
@@ -0,0 +1,60 @@
+use super::size_hint;
+
+/// An iterator which iterates two other iterators simultaneously
+///
+/// See [`.zip_eq()`](crate::Itertools::zip_eq) for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct ZipEq<I, J> {
+ a: I,
+ b: J,
+}
+
+/// Iterate `i` and `j` in lock step.
+///
+/// **Panics** if the iterators are not of the same length.
+///
+/// [`IntoIterator`] enabled version of [`Itertools::zip_eq`](crate::Itertools::zip_eq).
+///
+/// ```
+/// use itertools::zip_eq;
+///
+/// let data = [1, 2, 3, 4, 5];
+/// for (a, b) in zip_eq(&data[..data.len() - 1], &data[1..]) {
+/// /* loop body */
+/// }
+/// ```
+pub fn zip_eq<I, J>(i: I, j: J) -> ZipEq<I::IntoIter, J::IntoIter>
+ where I: IntoIterator,
+ J: IntoIterator
+{
+ ZipEq {
+ a: i.into_iter(),
+ b: j.into_iter(),
+ }
+}
+
+impl<I, J> Iterator for ZipEq<I, J>
+ where I: Iterator,
+ J: Iterator
+{
+ type Item = (I::Item, J::Item);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match (self.a.next(), self.b.next()) {
+ (None, None) => None,
+ (Some(a), Some(b)) => Some((a, b)),
+ (None, Some(_)) | (Some(_), None) =>
+ panic!("itertools: .zip_eq() reached end of one iterator before the other")
+ }
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ size_hint::min(self.a.size_hint(), self.b.size_hint())
+ }
+}
+
+impl<I, J> ExactSizeIterator for ZipEq<I, J>
+ where I: ExactSizeIterator,
+ J: ExactSizeIterator
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/zip_longest.rs b/rust/hw/char/pl011/vendor/itertools/src/zip_longest.rs
new file mode 100644
index 0000000000..cb9a7bacb2
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/zip_longest.rs
@@ -0,0 +1,83 @@
+use std::cmp::Ordering::{Equal, Greater, Less};
+use super::size_hint;
+use std::iter::{Fuse, FusedIterator};
+
+use crate::either_or_both::EitherOrBoth;
+
+// ZipLongest originally written by SimonSapin,
+// and dedicated to itertools https://github.com/rust-lang/rust/pull/19283
+
+/// An iterator which iterates two other iterators simultaneously
+///
+/// This iterator is *fused*.
+///
+/// See [`.zip_longest()`](crate::Itertools::zip_longest) for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct ZipLongest<T, U> {
+ a: Fuse<T>,
+ b: Fuse<U>,
+}
+
+/// Create a new `ZipLongest` iterator.
+pub fn zip_longest<T, U>(a: T, b: U) -> ZipLongest<T, U>
+ where T: Iterator,
+ U: Iterator
+{
+ ZipLongest {
+ a: a.fuse(),
+ b: b.fuse(),
+ }
+}
+
+impl<T, U> Iterator for ZipLongest<T, U>
+ where T: Iterator,
+ U: Iterator
+{
+ type Item = EitherOrBoth<T::Item, U::Item>;
+
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ match (self.a.next(), self.b.next()) {
+ (None, None) => None,
+ (Some(a), None) => Some(EitherOrBoth::Left(a)),
+ (None, Some(b)) => Some(EitherOrBoth::Right(b)),
+ (Some(a), Some(b)) => Some(EitherOrBoth::Both(a, b)),
+ }
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ size_hint::max(self.a.size_hint(), self.b.size_hint())
+ }
+}
+
+impl<T, U> DoubleEndedIterator for ZipLongest<T, U>
+ where T: DoubleEndedIterator + ExactSizeIterator,
+ U: DoubleEndedIterator + ExactSizeIterator
+{
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ match self.a.len().cmp(&self.b.len()) {
+ Equal => match (self.a.next_back(), self.b.next_back()) {
+ (None, None) => None,
+ (Some(a), Some(b)) => Some(EitherOrBoth::Both(a, b)),
+ // These can only happen if .len() is inconsistent with .next_back()
+ (Some(a), None) => Some(EitherOrBoth::Left(a)),
+ (None, Some(b)) => Some(EitherOrBoth::Right(b)),
+ },
+ Greater => self.a.next_back().map(EitherOrBoth::Left),
+ Less => self.b.next_back().map(EitherOrBoth::Right),
+ }
+ }
+}
+
+impl<T, U> ExactSizeIterator for ZipLongest<T, U>
+ where T: ExactSizeIterator,
+ U: ExactSizeIterator
+{}
+
+impl<T, U> FusedIterator for ZipLongest<T, U>
+ where T: Iterator,
+ U: Iterator
+{}
diff --git a/rust/hw/char/pl011/vendor/itertools/src/ziptuple.rs b/rust/hw/char/pl011/vendor/itertools/src/ziptuple.rs
new file mode 100644
index 0000000000..6d3a584c49
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/src/ziptuple.rs
@@ -0,0 +1,138 @@
+use super::size_hint;
+
+/// See [`multizip`] for more information.
+#[derive(Clone, Debug)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+pub struct Zip<T> {
+ t: T,
+}
+
+/// An iterator that generalizes *.zip()* and allows running multiple iterators in lockstep.
+///
+/// The iterator `Zip<(I, J, ..., M)>` is formed from a tuple of iterators (or values that
+/// implement [`IntoIterator`]) and yields elements
+/// until any of the subiterators yields `None`.
+///
+/// The iterator element type is a tuple like like `(A, B, ..., E)` where `A` to `E` are the
+/// element types of the subiterator.
+///
+/// **Note:** The result of this macro is a value of a named type (`Zip<(I, J,
+/// ..)>` of each component iterator `I, J, ...`) if each component iterator is
+/// nameable.
+///
+/// Prefer [`izip!()`] over `multizip` for the performance benefits of using the
+/// standard library `.zip()`. Prefer `multizip` if a nameable type is needed.
+///
+/// ```
+/// use itertools::multizip;
+///
+/// // iterate over three sequences side-by-side
+/// let mut results = [0, 0, 0, 0];
+/// let inputs = [3, 7, 9, 6];
+///
+/// for (r, index, input) in multizip((&mut results, 0..10, &inputs)) {
+/// *r = index * 10 + input;
+/// }
+///
+/// assert_eq!(results, [0 + 3, 10 + 7, 29, 36]);
+/// ```
+/// [`izip!()`]: crate::izip
+pub fn multizip<T, U>(t: U) -> Zip<T>
+ where Zip<T>: From<U>,
+ Zip<T>: Iterator,
+{
+ Zip::from(t)
+}
+
+macro_rules! impl_zip_iter {
+ ($($B:ident),*) => (
+ #[allow(non_snake_case)]
+ impl<$($B: IntoIterator),*> From<($($B,)*)> for Zip<($($B::IntoIter,)*)> {
+ fn from(t: ($($B,)*)) -> Self {
+ let ($($B,)*) = t;
+ Zip { t: ($($B.into_iter(),)*) }
+ }
+ }
+
+ #[allow(non_snake_case)]
+ #[allow(unused_assignments)]
+ impl<$($B),*> Iterator for Zip<($($B,)*)>
+ where
+ $(
+ $B: Iterator,
+ )*
+ {
+ type Item = ($($B::Item,)*);
+
+ fn next(&mut self) -> Option<Self::Item>
+ {
+ let ($(ref mut $B,)*) = self.t;
+
+ // NOTE: Just like iter::Zip, we check the iterators
+ // for None in order. We may finish unevenly (some
+ // iterators gave n + 1 elements, some only n).
+ $(
+ let $B = match $B.next() {
+ None => return None,
+ Some(elt) => elt
+ };
+ )*
+ Some(($($B,)*))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>)
+ {
+ let sh = (::std::usize::MAX, None);
+ let ($(ref $B,)*) = self.t;
+ $(
+ let sh = size_hint::min($B.size_hint(), sh);
+ )*
+ sh
+ }
+ }
+
+ #[allow(non_snake_case)]
+ impl<$($B),*> ExactSizeIterator for Zip<($($B,)*)> where
+ $(
+ $B: ExactSizeIterator,
+ )*
+ { }
+
+ #[allow(non_snake_case)]
+ impl<$($B),*> DoubleEndedIterator for Zip<($($B,)*)> where
+ $(
+ $B: DoubleEndedIterator + ExactSizeIterator,
+ )*
+ {
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ let ($(ref mut $B,)*) = self.t;
+ let size = *[$( $B.len(), )*].iter().min().unwrap();
+
+ $(
+ if $B.len() != size {
+ for _ in 0..$B.len() - size { $B.next_back(); }
+ }
+ )*
+
+ match ($($B.next_back(),)*) {
+ ($(Some($B),)*) => Some(($($B,)*)),
+ _ => None,
+ }
+ }
+ }
+ );
+}
+
+impl_zip_iter!(A);
+impl_zip_iter!(A, B);
+impl_zip_iter!(A, B, C);
+impl_zip_iter!(A, B, C, D);
+impl_zip_iter!(A, B, C, D, E);
+impl_zip_iter!(A, B, C, D, E, F);
+impl_zip_iter!(A, B, C, D, E, F, G);
+impl_zip_iter!(A, B, C, D, E, F, G, H);
+impl_zip_iter!(A, B, C, D, E, F, G, H, I);
+impl_zip_iter!(A, B, C, D, E, F, G, H, I, J);
+impl_zip_iter!(A, B, C, D, E, F, G, H, I, J, K);
+impl_zip_iter!(A, B, C, D, E, F, G, H, I, J, K, L);
diff --git a/rust/hw/char/pl011/vendor/itertools/tests/adaptors_no_collect.rs b/rust/hw/char/pl011/vendor/itertools/tests/adaptors_no_collect.rs
new file mode 100644
index 0000000000..103db23f1e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/tests/adaptors_no_collect.rs
@@ -0,0 +1,46 @@
+use itertools::Itertools;
+
+struct PanickingCounter {
+ curr: usize,
+ max: usize,
+}
+
+impl Iterator for PanickingCounter {
+ type Item = ();
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.curr += 1;
+
+ assert_ne!(
+ self.curr, self.max,
+ "Input iterator reached maximum of {} suggesting collection by adaptor",
+ self.max
+ );
+
+ Some(())
+ }
+}
+
+fn no_collect_test<A, T>(to_adaptor: T)
+ where A: Iterator, T: Fn(PanickingCounter) -> A
+{
+ let counter = PanickingCounter { curr: 0, max: 10_000 };
+ let adaptor = to_adaptor(counter);
+
+ for _ in adaptor.take(5) {}
+}
+
+#[test]
+fn permutations_no_collect() {
+ no_collect_test(|iter| iter.permutations(5))
+}
+
+#[test]
+fn combinations_no_collect() {
+ no_collect_test(|iter| iter.combinations(5))
+}
+
+#[test]
+fn combinations_with_replacement_no_collect() {
+ no_collect_test(|iter| iter.combinations_with_replacement(5))
+}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/itertools/tests/flatten_ok.rs b/rust/hw/char/pl011/vendor/itertools/tests/flatten_ok.rs
new file mode 100644
index 0000000000..bf835b5d70
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/tests/flatten_ok.rs
@@ -0,0 +1,76 @@
+use itertools::{assert_equal, Itertools};
+use std::{ops::Range, vec::IntoIter};
+
+fn mix_data() -> IntoIter<Result<Range<i32>, bool>> {
+ vec![Ok(0..2), Err(false), Ok(2..4), Err(true), Ok(4..6)].into_iter()
+}
+
+fn ok_data() -> IntoIter<Result<Range<i32>, bool>> {
+ vec![Ok(0..2), Ok(2..4), Ok(4..6)].into_iter()
+}
+
+#[test]
+fn flatten_ok_mixed_expected_forward() {
+ assert_equal(
+ mix_data().flatten_ok(),
+ vec![
+ Ok(0),
+ Ok(1),
+ Err(false),
+ Ok(2),
+ Ok(3),
+ Err(true),
+ Ok(4),
+ Ok(5),
+ ],
+ );
+}
+
+#[test]
+fn flatten_ok_mixed_expected_reverse() {
+ assert_equal(
+ mix_data().flatten_ok().rev(),
+ vec![
+ Ok(5),
+ Ok(4),
+ Err(true),
+ Ok(3),
+ Ok(2),
+ Err(false),
+ Ok(1),
+ Ok(0),
+ ],
+ );
+}
+
+#[test]
+fn flatten_ok_collect_mixed_forward() {
+ assert_eq!(
+ mix_data().flatten_ok().collect::<Result<Vec<_>, _>>(),
+ Err(false)
+ );
+}
+
+#[test]
+fn flatten_ok_collect_mixed_reverse() {
+ assert_eq!(
+ mix_data().flatten_ok().rev().collect::<Result<Vec<_>, _>>(),
+ Err(true)
+ );
+}
+
+#[test]
+fn flatten_ok_collect_ok_forward() {
+ assert_eq!(
+ ok_data().flatten_ok().collect::<Result<Vec<_>, _>>(),
+ Ok((0..6).collect())
+ );
+}
+
+#[test]
+fn flatten_ok_collect_ok_reverse() {
+ assert_eq!(
+ ok_data().flatten_ok().rev().collect::<Result<Vec<_>, _>>(),
+ Ok((0..6).rev().collect())
+ );
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/tests/macros_hygiene.rs b/rust/hw/char/pl011/vendor/itertools/tests/macros_hygiene.rs
new file mode 100644
index 0000000000..d1111245d6
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/tests/macros_hygiene.rs
@@ -0,0 +1,13 @@
+#[test]
+fn iproduct_hygiene() {
+ let _ = itertools::iproduct!(0..6);
+ let _ = itertools::iproduct!(0..6, 0..9);
+ let _ = itertools::iproduct!(0..6, 0..9, 0..12);
+}
+
+#[test]
+fn izip_hygiene() {
+ let _ = itertools::izip!(0..6);
+ let _ = itertools::izip!(0..6, 0..9);
+ let _ = itertools::izip!(0..6, 0..9, 0..12);
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/tests/merge_join.rs b/rust/hw/char/pl011/vendor/itertools/tests/merge_join.rs
new file mode 100644
index 0000000000..3280b7d4ec
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/tests/merge_join.rs
@@ -0,0 +1,108 @@
+use itertools::EitherOrBoth;
+use itertools::free::merge_join_by;
+
+#[test]
+fn empty() {
+ let left: Vec<u32> = vec![];
+ let right: Vec<u32> = vec![];
+ let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![];
+ let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+ .collect::<Vec<_>>();
+ assert_eq!(expected_result, actual_result);
+}
+
+#[test]
+fn left_only() {
+ let left: Vec<u32> = vec![1,2,3];
+ let right: Vec<u32> = vec![];
+ let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
+ EitherOrBoth::Left(1),
+ EitherOrBoth::Left(2),
+ EitherOrBoth::Left(3)
+ ];
+ let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+ .collect::<Vec<_>>();
+ assert_eq!(expected_result, actual_result);
+}
+
+#[test]
+fn right_only() {
+ let left: Vec<u32> = vec![];
+ let right: Vec<u32> = vec![1,2,3];
+ let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
+ EitherOrBoth::Right(1),
+ EitherOrBoth::Right(2),
+ EitherOrBoth::Right(3)
+ ];
+ let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+ .collect::<Vec<_>>();
+ assert_eq!(expected_result, actual_result);
+}
+
+#[test]
+fn first_left_then_right() {
+ let left: Vec<u32> = vec![1,2,3];
+ let right: Vec<u32> = vec![4,5,6];
+ let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
+ EitherOrBoth::Left(1),
+ EitherOrBoth::Left(2),
+ EitherOrBoth::Left(3),
+ EitherOrBoth::Right(4),
+ EitherOrBoth::Right(5),
+ EitherOrBoth::Right(6)
+ ];
+ let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+ .collect::<Vec<_>>();
+ assert_eq!(expected_result, actual_result);
+}
+
+#[test]
+fn first_right_then_left() {
+ let left: Vec<u32> = vec![4,5,6];
+ let right: Vec<u32> = vec![1,2,3];
+ let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
+ EitherOrBoth::Right(1),
+ EitherOrBoth::Right(2),
+ EitherOrBoth::Right(3),
+ EitherOrBoth::Left(4),
+ EitherOrBoth::Left(5),
+ EitherOrBoth::Left(6)
+ ];
+ let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+ .collect::<Vec<_>>();
+ assert_eq!(expected_result, actual_result);
+}
+
+#[test]
+fn interspersed_left_and_right() {
+ let left: Vec<u32> = vec![1,3,5];
+ let right: Vec<u32> = vec![2,4,6];
+ let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
+ EitherOrBoth::Left(1),
+ EitherOrBoth::Right(2),
+ EitherOrBoth::Left(3),
+ EitherOrBoth::Right(4),
+ EitherOrBoth::Left(5),
+ EitherOrBoth::Right(6)
+ ];
+ let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+ .collect::<Vec<_>>();
+ assert_eq!(expected_result, actual_result);
+}
+
+#[test]
+fn overlapping_left_and_right() {
+ let left: Vec<u32> = vec![1,3,4,6];
+ let right: Vec<u32> = vec![2,3,4,5];
+ let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
+ EitherOrBoth::Left(1),
+ EitherOrBoth::Right(2),
+ EitherOrBoth::Both(3, 3),
+ EitherOrBoth::Both(4, 4),
+ EitherOrBoth::Right(5),
+ EitherOrBoth::Left(6)
+ ];
+ let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
+ .collect::<Vec<_>>();
+ assert_eq!(expected_result, actual_result);
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/tests/peeking_take_while.rs b/rust/hw/char/pl011/vendor/itertools/tests/peeking_take_while.rs
new file mode 100644
index 0000000000..5be97271dd
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/tests/peeking_take_while.rs
@@ -0,0 +1,69 @@
+use itertools::Itertools;
+use itertools::{put_back, put_back_n};
+
+#[test]
+fn peeking_take_while_peekable() {
+ let mut r = (0..10).peekable();
+ r.peeking_take_while(|x| *x <= 3).count();
+ assert_eq!(r.next(), Some(4));
+}
+
+#[test]
+fn peeking_take_while_put_back() {
+ let mut r = put_back(0..10);
+ r.peeking_take_while(|x| *x <= 3).count();
+ assert_eq!(r.next(), Some(4));
+ r.peeking_take_while(|_| true).count();
+ assert_eq!(r.next(), None);
+}
+
+#[test]
+fn peeking_take_while_put_back_n() {
+ let mut r = put_back_n(6..10);
+ for elt in (0..6).rev() {
+ r.put_back(elt);
+ }
+ r.peeking_take_while(|x| *x <= 3).count();
+ assert_eq!(r.next(), Some(4));
+ r.peeking_take_while(|_| true).count();
+ assert_eq!(r.next(), None);
+}
+
+#[test]
+fn peeking_take_while_slice_iter() {
+ let v = [1, 2, 3, 4, 5, 6];
+ let mut r = v.iter();
+ r.peeking_take_while(|x| **x <= 3).count();
+ assert_eq!(r.next(), Some(&4));
+ r.peeking_take_while(|_| true).count();
+ assert_eq!(r.next(), None);
+}
+
+#[test]
+fn peeking_take_while_slice_iter_rev() {
+ let v = [1, 2, 3, 4, 5, 6];
+ let mut r = v.iter().rev();
+ r.peeking_take_while(|x| **x >= 3).count();
+ assert_eq!(r.next(), Some(&2));
+ r.peeking_take_while(|_| true).count();
+ assert_eq!(r.next(), None);
+}
+
+#[test]
+fn peeking_take_while_nested() {
+ let mut xs = (0..10).peekable();
+ let ys: Vec<_> = xs
+ .peeking_take_while(|x| *x < 6)
+ .peeking_take_while(|x| *x != 3)
+ .collect();
+ assert_eq!(ys, vec![0, 1, 2]);
+ assert_eq!(xs.next(), Some(3));
+
+ let mut xs = (4..10).peekable();
+ let ys: Vec<_> = xs
+ .peeking_take_while(|x| *x != 3)
+ .peeking_take_while(|x| *x < 6)
+ .collect();
+ assert_eq!(ys, vec![4, 5]);
+ assert_eq!(xs.next(), Some(6));
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/tests/quick.rs b/rust/hw/char/pl011/vendor/itertools/tests/quick.rs
new file mode 100644
index 0000000000..c19af6c1ea
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/tests/quick.rs
@@ -0,0 +1,1849 @@
+//! The purpose of these tests is to cover corner cases of iterators
+//! and adaptors.
+//!
+//! In particular we test the tedious size_hint and exact size correctness.
+
+use quickcheck as qc;
+use std::default::Default;
+use std::num::Wrapping;
+use std::ops::Range;
+use std::cmp::{max, min, Ordering};
+use std::collections::{HashMap, HashSet};
+use itertools::Itertools;
+use itertools::{
+ multizip,
+ EitherOrBoth,
+ iproduct,
+ izip,
+};
+use itertools::free::{
+ cloned,
+ enumerate,
+ multipeek,
+ peek_nth,
+ put_back,
+ put_back_n,
+ rciter,
+ zip,
+ zip_eq,
+};
+
+use rand::Rng;
+use rand::seq::SliceRandom;
+use quickcheck::TestResult;
+
+/// Trait for size hint modifier types
+trait HintKind: Copy + Send + qc::Arbitrary {
+ fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>);
+}
+
+/// Exact size hint variant that leaves hints unchanged
+#[derive(Clone, Copy, Debug)]
+struct Exact {}
+
+impl HintKind for Exact {
+ fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
+ org_hint
+ }
+}
+
+impl qc::Arbitrary for Exact {
+ fn arbitrary<G: qc::Gen>(_: &mut G) -> Self {
+ Exact {}
+ }
+}
+
+/// Inexact size hint variant to simulate imprecise (but valid) size hints
+///
+/// Will always decrease the lower bound and increase the upper bound
+/// of the size hint by set amounts.
+#[derive(Clone, Copy, Debug)]
+struct Inexact {
+ underestimate: usize,
+ overestimate: usize,
+}
+
+impl HintKind for Inexact {
+ fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
+ let (org_lower, org_upper) = org_hint;
+ (org_lower.saturating_sub(self.underestimate),
+ org_upper.and_then(move |x| x.checked_add(self.overestimate)))
+ }
+}
+
+impl qc::Arbitrary for Inexact {
+ fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
+ let ue_value = usize::arbitrary(g);
+ let oe_value = usize::arbitrary(g);
+ // Compensate for quickcheck using extreme values too rarely
+ let ue_choices = &[0, ue_value, usize::max_value()];
+ let oe_choices = &[0, oe_value, usize::max_value()];
+ Inexact {
+ underestimate: *ue_choices.choose(g).unwrap(),
+ overestimate: *oe_choices.choose(g).unwrap(),
+ }
+ }
+
+ fn shrink(&self) -> Box<dyn Iterator<Item=Self>> {
+ let underestimate_value = self.underestimate;
+ let overestimate_value = self.overestimate;
+ Box::new(
+ underestimate_value.shrink().flat_map(move |ue_value|
+ overestimate_value.shrink().map(move |oe_value|
+ Inexact {
+ underestimate: ue_value,
+ overestimate: oe_value,
+ }
+ )
+ )
+ )
+ }
+}
+
+/// Our base iterator that we can impl Arbitrary for
+///
+/// By default we'll return inexact bounds estimates for size_hint
+/// to make tests harder to pass.
+///
+/// NOTE: Iter is tricky and is not fused, to help catch bugs.
+/// At the end it will return None once, then return Some(0),
+/// then return None again.
+#[derive(Clone, Debug)]
+struct Iter<T, SK: HintKind = Inexact> {
+ iterator: Range<T>,
+ // fuse/done flag
+ fuse_flag: i32,
+ hint_kind: SK,
+}
+
+impl<T, HK> Iter<T, HK> where HK: HintKind
+{
+ fn new(it: Range<T>, hint_kind: HK) -> Self {
+ Iter {
+ iterator: it,
+ fuse_flag: 0,
+ hint_kind,
+ }
+ }
+}
+
+impl<T, HK> Iterator for Iter<T, HK>
+ where Range<T>: Iterator,
+ <Range<T> as Iterator>::Item: Default,
+ HK: HintKind,
+{
+ type Item = <Range<T> as Iterator>::Item;
+
+ fn next(&mut self) -> Option<Self::Item>
+ {
+ let elt = self.iterator.next();
+ if elt.is_none() {
+ self.fuse_flag += 1;
+ // check fuse flag
+ if self.fuse_flag == 2 {
+ return Some(Default::default())
+ }
+ }
+ elt
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>)
+ {
+ let org_hint = self.iterator.size_hint();
+ self.hint_kind.loosen_bounds(org_hint)
+ }
+}
+
+impl<T, HK> DoubleEndedIterator for Iter<T, HK>
+ where Range<T>: DoubleEndedIterator,
+ <Range<T> as Iterator>::Item: Default,
+ HK: HintKind
+{
+ fn next_back(&mut self) -> Option<Self::Item> { self.iterator.next_back() }
+}
+
+impl<T> ExactSizeIterator for Iter<T, Exact> where Range<T>: ExactSizeIterator,
+ <Range<T> as Iterator>::Item: Default,
+{ }
+
+impl<T, HK> qc::Arbitrary for Iter<T, HK>
+ where T: qc::Arbitrary,
+ HK: HintKind,
+{
+ fn arbitrary<G: qc::Gen>(g: &mut G) -> Self
+ {
+ Iter::new(T::arbitrary(g)..T::arbitrary(g), HK::arbitrary(g))
+ }
+
+ fn shrink(&self) -> Box<dyn Iterator<Item=Iter<T, HK>>>
+ {
+ let r = self.iterator.clone();
+ let hint_kind = self.hint_kind;
+ Box::new(
+ r.start.shrink().flat_map(move |a|
+ r.end.shrink().map(move |b|
+ Iter::new(a.clone()..b, hint_kind)
+ )
+ )
+ )
+ }
+}
+
+/// A meta-iterator which yields `Iter<i32>`s whose start/endpoints are
+/// increased or decreased linearly on each iteration.
+#[derive(Clone, Debug)]
+struct ShiftRange<HK = Inexact> {
+ range_start: i32,
+ range_end: i32,
+ start_step: i32,
+ end_step: i32,
+ iter_count: u32,
+ hint_kind: HK,
+}
+
+impl<HK> Iterator for ShiftRange<HK> where HK: HintKind {
+ type Item = Iter<i32, HK>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.iter_count == 0 {
+ return None;
+ }
+
+ let iter = Iter::new(self.range_start..self.range_end, self.hint_kind);
+
+ self.range_start += self.start_step;
+ self.range_end += self.end_step;
+ self.iter_count -= 1;
+
+ Some(iter)
+ }
+}
+
+impl ExactSizeIterator for ShiftRange<Exact> { }
+
+impl<HK> qc::Arbitrary for ShiftRange<HK>
+ where HK: HintKind
+{
+ fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
+ const MAX_STARTING_RANGE_DIFF: i32 = 32;
+ const MAX_STEP_MODULO: i32 = 8;
+ const MAX_ITER_COUNT: u32 = 3;
+
+ let range_start = qc::Arbitrary::arbitrary(g);
+ let range_end = range_start + g.gen_range(0, MAX_STARTING_RANGE_DIFF + 1);
+ let start_step = g.gen_range(-MAX_STEP_MODULO, MAX_STEP_MODULO + 1);
+ let end_step = g.gen_range(-MAX_STEP_MODULO, MAX_STEP_MODULO + 1);
+ let iter_count = g.gen_range(0, MAX_ITER_COUNT + 1);
+ let hint_kind = qc::Arbitrary::arbitrary(g);
+
+ ShiftRange {
+ range_start,
+ range_end,
+ start_step,
+ end_step,
+ iter_count,
+ hint_kind,
+ }
+ }
+}
+
+fn correct_count<I, F>(get_it: F) -> bool
+where
+ I: Iterator,
+ F: Fn() -> I
+{
+ let mut counts = vec![get_it().count()];
+
+ 'outer: loop {
+ let mut it = get_it();
+
+ for _ in 0..(counts.len() - 1) {
+ #[allow(clippy::manual_assert)]
+ if it.next().is_none() {
+ panic!("Iterator shouldn't be finished, may not be deterministic");
+ }
+ }
+
+ if it.next().is_none() {
+ break 'outer;
+ }
+
+ counts.push(it.count());
+ }
+
+ let total_actual_count = counts.len() - 1;
+
+ for (i, returned_count) in counts.into_iter().enumerate() {
+ let actual_count = total_actual_count - i;
+ if actual_count != returned_count {
+ println!("Total iterations: {} True count: {} returned count: {}", i, actual_count, returned_count);
+
+ return false;
+ }
+ }
+
+ true
+}
+
+fn correct_size_hint<I: Iterator>(mut it: I) -> bool {
+ // record size hint at each iteration
+ let initial_hint = it.size_hint();
+ let mut hints = Vec::with_capacity(initial_hint.0 + 1);
+ hints.push(initial_hint);
+ while let Some(_) = it.next() {
+ hints.push(it.size_hint())
+ }
+
+ let mut true_count = hints.len(); // start off +1 too much
+
+ // check all the size hints
+ for &(low, hi) in &hints {
+ true_count -= 1;
+ if low > true_count ||
+ (hi.is_some() && hi.unwrap() < true_count)
+ {
+ println!("True size: {:?}, size hint: {:?}", true_count, (low, hi));
+ //println!("All hints: {:?}", hints);
+ return false
+ }
+ }
+ true
+}
+
+fn exact_size<I: ExactSizeIterator>(mut it: I) -> bool {
+ // check every iteration
+ let (mut low, mut hi) = it.size_hint();
+ if Some(low) != hi { return false; }
+ while let Some(_) = it.next() {
+ let (xlow, xhi) = it.size_hint();
+ if low != xlow + 1 { return false; }
+ low = xlow;
+ hi = xhi;
+ if Some(low) != hi { return false; }
+ }
+ let (low, hi) = it.size_hint();
+ low == 0 && hi == Some(0)
+}
+
+// Exact size for this case, without ExactSizeIterator
+fn exact_size_for_this<I: Iterator>(mut it: I) -> bool {
+ // check every iteration
+ let (mut low, mut hi) = it.size_hint();
+ if Some(low) != hi { return false; }
+ while let Some(_) = it.next() {
+ let (xlow, xhi) = it.size_hint();
+ if low != xlow + 1 { return false; }
+ low = xlow;
+ hi = xhi;
+ if Some(low) != hi { return false; }
+ }
+ let (low, hi) = it.size_hint();
+ low == 0 && hi == Some(0)
+}
+
+/*
+ * NOTE: Range<i8> is broken!
+ * (all signed ranges are)
+#[quickcheck]
+fn size_range_i8(a: Iter<i8>) -> bool {
+ exact_size(a)
+}
+
+#[quickcheck]
+fn size_range_i16(a: Iter<i16>) -> bool {
+ exact_size(a)
+}
+
+#[quickcheck]
+fn size_range_u8(a: Iter<u8>) -> bool {
+ exact_size(a)
+}
+ */
+
+macro_rules! quickcheck {
+ // accept several property function definitions
+ // The property functions can use pattern matching and `mut` as usual
+ // in the function arguments, but the functions can not be generic.
+ {$($(#$attr:tt)* fn $fn_name:ident($($arg:tt)*) -> $ret:ty { $($code:tt)* })*} => (
+ $(
+ #[test]
+ $(#$attr)*
+ fn $fn_name() {
+ fn prop($($arg)*) -> $ret {
+ $($code)*
+ }
+ ::quickcheck::quickcheck(quickcheck!(@fn prop [] $($arg)*));
+ }
+ )*
+ );
+ // parse argument list (with patterns allowed) into prop as fn(_, _) -> _
+ (@fn $f:ident [$($t:tt)*]) => {
+ $f as fn($($t),*) -> _
+ };
+ (@fn $f:ident [$($p:tt)*] : $($tail:tt)*) => {
+ quickcheck!(@fn $f [$($p)* _] $($tail)*)
+ };
+ (@fn $f:ident [$($p:tt)*] $t:tt $($tail:tt)*) => {
+ quickcheck!(@fn $f [$($p)*] $($tail)*)
+ };
+}
+
+quickcheck! {
+
+ fn size_product(a: Iter<u16>, b: Iter<u16>) -> bool {
+ correct_size_hint(a.cartesian_product(b))
+ }
+ fn size_product3(a: Iter<u16>, b: Iter<u16>, c: Iter<u16>) -> bool {
+ correct_size_hint(iproduct!(a, b, c))
+ }
+
+ fn correct_cartesian_product3(a: Iter<u16>, b: Iter<u16>, c: Iter<u16>,
+ take_manual: usize) -> ()
+ {
+ // test correctness of iproduct through regular iteration (take)
+ // and through fold.
+ let ac = a.clone();
+ let br = &b.clone();
+ let cr = &c.clone();
+ let answer: Vec<_> = ac.flat_map(move |ea| br.clone().flat_map(move |eb| cr.clone().map(move |ec| (ea, eb, ec)))).collect();
+ let mut product_iter = iproduct!(a, b, c);
+ let mut actual = Vec::new();
+
+ actual.extend((&mut product_iter).take(take_manual));
+ if actual.len() == take_manual {
+ product_iter.fold((), |(), elt| actual.push(elt));
+ }
+ assert_eq!(answer, actual);
+ }
+
+ fn size_multi_product(a: ShiftRange) -> bool {
+ correct_size_hint(a.multi_cartesian_product())
+ }
+ fn correct_multi_product3(a: ShiftRange, take_manual: usize) -> () {
+ // Fix no. of iterators at 3
+ let a = ShiftRange { iter_count: 3, ..a };
+
+ // test correctness of MultiProduct through regular iteration (take)
+ // and through fold.
+ let mut iters = a.clone();
+ let i0 = iters.next().unwrap();
+ let i1r = &iters.next().unwrap();
+ let i2r = &iters.next().unwrap();
+ let answer: Vec<_> = i0.flat_map(move |ei0| i1r.clone().flat_map(move |ei1| i2r.clone().map(move |ei2| vec![ei0, ei1, ei2]))).collect();
+ let mut multi_product = a.clone().multi_cartesian_product();
+ let mut actual = Vec::new();
+
+ actual.extend((&mut multi_product).take(take_manual));
+ if actual.len() == take_manual {
+ multi_product.fold((), |(), elt| actual.push(elt));
+ }
+ assert_eq!(answer, actual);
+
+ assert_eq!(answer.into_iter().last(), a.multi_cartesian_product().last());
+ }
+
+ #[allow(deprecated)]
+ fn size_step(a: Iter<i16, Exact>, s: usize) -> bool {
+ let mut s = s;
+ if s == 0 {
+ s += 1; // never zero
+ }
+ let filt = a.clone().dedup();
+ correct_size_hint(filt.step(s)) &&
+ exact_size(a.step(s))
+ }
+
+ #[allow(deprecated)]
+ fn equal_step(a: Iter<i16>, s: usize) -> bool {
+ let mut s = s;
+ if s == 0 {
+ s += 1; // never zero
+ }
+ let mut i = 0;
+ itertools::equal(a.clone().step(s), a.filter(|_| {
+ let keep = i % s == 0;
+ i += 1;
+ keep
+ }))
+ }
+
+ #[allow(deprecated)]
+ fn equal_step_vec(a: Vec<i16>, s: usize) -> bool {
+ let mut s = s;
+ if s == 0 {
+ s += 1; // never zero
+ }
+ let mut i = 0;
+ itertools::equal(a.iter().step(s), a.iter().filter(|_| {
+ let keep = i % s == 0;
+ i += 1;
+ keep
+ }))
+ }
+
+ fn size_multipeek(a: Iter<u16, Exact>, s: u8) -> bool {
+ let mut it = multipeek(a);
+ // peek a few times
+ for _ in 0..s {
+ it.peek();
+ }
+ exact_size(it)
+ }
+
+ fn size_peek_nth(a: Iter<u16, Exact>, s: u8) -> bool {
+ let mut it = peek_nth(a);
+ // peek a few times
+ for n in 0..s {
+ it.peek_nth(n as usize);
+ }
+ exact_size(it)
+ }
+
+ fn equal_merge(mut a: Vec<i16>, mut b: Vec<i16>) -> bool {
+ a.sort();
+ b.sort();
+ let mut merged = a.clone();
+ merged.extend(b.iter().cloned());
+ merged.sort();
+ itertools::equal(&merged, a.iter().merge(&b))
+ }
+ fn size_merge(a: Iter<u16>, b: Iter<u16>) -> bool {
+ correct_size_hint(a.merge(b))
+ }
+ fn size_zip(a: Iter<i16, Exact>, b: Iter<i16, Exact>, c: Iter<i16, Exact>) -> bool {
+ let filt = a.clone().dedup();
+ correct_size_hint(multizip((filt, b.clone(), c.clone()))) &&
+ exact_size(multizip((a, b, c)))
+ }
+ fn size_zip_rc(a: Iter<i16>, b: Iter<i16>) -> bool {
+ let rc = rciter(a);
+ correct_size_hint(multizip((&rc, &rc, b)))
+ }
+
+ fn size_zip_macro(a: Iter<i16, Exact>, b: Iter<i16, Exact>, c: Iter<i16, Exact>) -> bool {
+ let filt = a.clone().dedup();
+ correct_size_hint(izip!(filt, b.clone(), c.clone())) &&
+ exact_size(izip!(a, b, c))
+ }
+ fn equal_kmerge(mut a: Vec<i16>, mut b: Vec<i16>, mut c: Vec<i16>) -> bool {
+ use itertools::free::kmerge;
+ a.sort();
+ b.sort();
+ c.sort();
+ let mut merged = a.clone();
+ merged.extend(b.iter().cloned());
+ merged.extend(c.iter().cloned());
+ merged.sort();
+ itertools::equal(merged.into_iter(), kmerge(vec![a, b, c]))
+ }
+
+ // Any number of input iterators
+ fn equal_kmerge_2(mut inputs: Vec<Vec<i16>>) -> bool {
+ use itertools::free::kmerge;
+ // sort the inputs
+ for input in &mut inputs {
+ input.sort();
+ }
+ let mut merged = inputs.concat();
+ merged.sort();
+ itertools::equal(merged.into_iter(), kmerge(inputs))
+ }
+
+ // Any number of input iterators
+ fn equal_kmerge_by_ge(mut inputs: Vec<Vec<i16>>) -> bool {
+ // sort the inputs
+ for input in &mut inputs {
+ input.sort();
+ input.reverse();
+ }
+ let mut merged = inputs.concat();
+ merged.sort();
+ merged.reverse();
+ itertools::equal(merged.into_iter(),
+ inputs.into_iter().kmerge_by(|x, y| x >= y))
+ }
+
+ // Any number of input iterators
+ fn equal_kmerge_by_lt(mut inputs: Vec<Vec<i16>>) -> bool {
+ // sort the inputs
+ for input in &mut inputs {
+ input.sort();
+ }
+ let mut merged = inputs.concat();
+ merged.sort();
+ itertools::equal(merged.into_iter(),
+ inputs.into_iter().kmerge_by(|x, y| x < y))
+ }
+
+ // Any number of input iterators
+ fn equal_kmerge_by_le(mut inputs: Vec<Vec<i16>>) -> bool {
+ // sort the inputs
+ for input in &mut inputs {
+ input.sort();
+ }
+ let mut merged = inputs.concat();
+ merged.sort();
+ itertools::equal(merged.into_iter(),
+ inputs.into_iter().kmerge_by(|x, y| x <= y))
+ }
+ fn size_kmerge(a: Iter<i16>, b: Iter<i16>, c: Iter<i16>) -> bool {
+ use itertools::free::kmerge;
+ correct_size_hint(kmerge(vec![a, b, c]))
+ }
+ fn equal_zip_eq(a: Vec<i32>, b: Vec<i32>) -> bool {
+ let len = std::cmp::min(a.len(), b.len());
+ let a = &a[..len];
+ let b = &b[..len];
+ itertools::equal(zip_eq(a, b), zip(a, b))
+ }
+ fn size_zip_longest(a: Iter<i16, Exact>, b: Iter<i16, Exact>) -> bool {
+ let filt = a.clone().dedup();
+ let filt2 = b.clone().dedup();
+ correct_size_hint(filt.zip_longest(b.clone())) &&
+ correct_size_hint(a.clone().zip_longest(filt2)) &&
+ exact_size(a.zip_longest(b))
+ }
+ fn size_2_zip_longest(a: Iter<i16>, b: Iter<i16>) -> bool {
+ let it = a.clone().zip_longest(b.clone());
+ let jt = a.clone().zip_longest(b.clone());
+ itertools::equal(a,
+ it.filter_map(|elt| match elt {
+ EitherOrBoth::Both(x, _) => Some(x),
+ EitherOrBoth::Left(x) => Some(x),
+ _ => None,
+ }
+ ))
+ &&
+ itertools::equal(b,
+ jt.filter_map(|elt| match elt {
+ EitherOrBoth::Both(_, y) => Some(y),
+ EitherOrBoth::Right(y) => Some(y),
+ _ => None,
+ }
+ ))
+ }
+ fn size_interleave(a: Iter<i16>, b: Iter<i16>) -> bool {
+ correct_size_hint(a.interleave(b))
+ }
+ fn exact_interleave(a: Iter<i16, Exact>, b: Iter<i16, Exact>) -> bool {
+ exact_size_for_this(a.interleave(b))
+ }
+ fn size_interleave_shortest(a: Iter<i16>, b: Iter<i16>) -> bool {
+ correct_size_hint(a.interleave_shortest(b))
+ }
+ fn exact_interleave_shortest(a: Vec<()>, b: Vec<()>) -> bool {
+ exact_size_for_this(a.iter().interleave_shortest(&b))
+ }
+ fn size_intersperse(a: Iter<i16>, x: i16) -> bool {
+ correct_size_hint(a.intersperse(x))
+ }
+ fn equal_intersperse(a: Vec<i32>, x: i32) -> bool {
+ let mut inter = false;
+ let mut i = 0;
+ for elt in a.iter().cloned().intersperse(x) {
+ if inter {
+ if elt != x { return false }
+ } else {
+ if elt != a[i] { return false }
+ i += 1;
+ }
+ inter = !inter;
+ }
+ true
+ }
+
+ fn equal_combinations_2(a: Vec<u8>) -> bool {
+ let mut v = Vec::new();
+ for (i, x) in enumerate(&a) {
+ for y in &a[i + 1..] {
+ v.push((x, y));
+ }
+ }
+ itertools::equal(a.iter().tuple_combinations::<(_, _)>(), v)
+ }
+
+ fn collect_tuple_matches_size(a: Iter<i16>) -> bool {
+ let size = a.clone().count();
+ a.collect_tuple::<(_, _, _)>().is_some() == (size == 3)
+ }
+
+ fn correct_permutations(vals: HashSet<i32>, k: usize) -> () {
+ // Test permutations only on iterators of distinct integers, to prevent
+ // false positives.
+
+ const MAX_N: usize = 5;
+
+ let n = min(vals.len(), MAX_N);
+ let vals: HashSet<i32> = vals.into_iter().take(n).collect();
+
+ let perms = vals.iter().permutations(k);
+
+ let mut actual = HashSet::new();
+
+ for perm in perms {
+ assert_eq!(perm.len(), k);
+
+ let all_items_valid = perm.iter().all(|p| vals.contains(p));
+ assert!(all_items_valid, "perm contains value not from input: {:?}", perm);
+
+ // Check that all perm items are distinct
+ let distinct_len = {
+ let perm_set: HashSet<_> = perm.iter().collect();
+ perm_set.len()
+ };
+ assert_eq!(perm.len(), distinct_len);
+
+ // Check that the perm is new
+ assert!(actual.insert(perm.clone()), "perm already encountered: {:?}", perm);
+ }
+ }
+
+ fn permutations_lexic_order(a: usize, b: usize) -> () {
+ let a = a % 6;
+ let b = b % 6;
+
+ let n = max(a, b);
+ let k = min (a, b);
+
+ let expected_first: Vec<usize> = (0..k).collect();
+ let expected_last: Vec<usize> = ((n - k)..n).rev().collect();
+
+ let mut perms = (0..n).permutations(k);
+
+ let mut curr_perm = match perms.next() {
+ Some(p) => p,
+ None => { return; }
+ };
+
+ assert_eq!(expected_first, curr_perm);
+
+ for next_perm in perms {
+ assert!(
+ next_perm > curr_perm,
+ "next perm isn't greater-than current; next_perm={:?} curr_perm={:?} n={}",
+ next_perm, curr_perm, n
+ );
+
+ curr_perm = next_perm;
+ }
+
+ assert_eq!(expected_last, curr_perm);
+
+ }
+
+ fn permutations_count(n: usize, k: usize) -> bool {
+ let n = n % 6;
+
+ correct_count(|| (0..n).permutations(k))
+ }
+
+ fn permutations_size(a: Iter<i32>, k: usize) -> bool {
+ correct_size_hint(a.take(5).permutations(k))
+ }
+
+ fn permutations_k0_yields_once(n: usize) -> () {
+ let k = 0;
+ let expected: Vec<Vec<usize>> = vec![vec![]];
+ let actual = (0..n).permutations(k).collect_vec();
+
+ assert_eq!(expected, actual);
+ }
+}
+
+quickcheck! {
+ fn dedup_via_coalesce(a: Vec<i32>) -> bool {
+ let mut b = a.clone();
+ b.dedup();
+ itertools::equal(
+ &b,
+ a
+ .iter()
+ .coalesce(|x, y| {
+ if x==y {
+ Ok(x)
+ } else {
+ Err((x, y))
+ }
+ })
+ .fold(vec![], |mut v, n| {
+ v.push(n);
+ v
+ })
+ )
+ }
+}
+
+quickcheck! {
+ fn equal_dedup(a: Vec<i32>) -> bool {
+ let mut b = a.clone();
+ b.dedup();
+ itertools::equal(&b, a.iter().dedup())
+ }
+}
+
+quickcheck! {
+ fn equal_dedup_by(a: Vec<(i32, i32)>) -> bool {
+ let mut b = a.clone();
+ b.dedup_by(|x, y| x.0==y.0);
+ itertools::equal(&b, a.iter().dedup_by(|x, y| x.0==y.0))
+ }
+}
+
+quickcheck! {
+ fn size_dedup(a: Vec<i32>) -> bool {
+ correct_size_hint(a.iter().dedup())
+ }
+}
+
+quickcheck! {
+ fn size_dedup_by(a: Vec<(i32, i32)>) -> bool {
+ correct_size_hint(a.iter().dedup_by(|x, y| x.0==y.0))
+ }
+}
+
+quickcheck! {
+ fn exact_repeatn((n, x): (usize, i32)) -> bool {
+ let it = itertools::repeat_n(x, n);
+ exact_size(it)
+ }
+}
+
+quickcheck! {
+ fn size_put_back(a: Vec<u8>, x: Option<u8>) -> bool {
+ let mut it = put_back(a.into_iter());
+ match x {
+ Some(t) => it.put_back(t),
+ None => {}
+ }
+ correct_size_hint(it)
+ }
+}
+
+quickcheck! {
+ fn size_put_backn(a: Vec<u8>, b: Vec<u8>) -> bool {
+ let mut it = put_back_n(a.into_iter());
+ for elt in b {
+ it.put_back(elt)
+ }
+ correct_size_hint(it)
+ }
+}
+
+quickcheck! {
+ fn merge_join_by_ordering_vs_bool(a: Vec<u8>, b: Vec<u8>) -> bool {
+ use either::Either;
+ use itertools::free::merge_join_by;
+ let mut has_equal = false;
+ let it_ord = merge_join_by(a.clone(), b.clone(), Ord::cmp).flat_map(|v| match v {
+ EitherOrBoth::Both(l, r) => {
+ has_equal = true;
+ vec![Either::Left(l), Either::Right(r)]
+ }
+ EitherOrBoth::Left(l) => vec![Either::Left(l)],
+ EitherOrBoth::Right(r) => vec![Either::Right(r)],
+ });
+ let it_bool = merge_join_by(a, b, PartialOrd::le);
+ itertools::equal(it_ord, it_bool) || has_equal
+ }
+ fn merge_join_by_bool_unwrapped_is_merge_by(a: Vec<u8>, b: Vec<u8>) -> bool {
+ use either::Either;
+ use itertools::free::merge_join_by;
+ let it = a.clone().into_iter().merge_by(b.clone(), PartialOrd::ge);
+ let it_join = merge_join_by(a, b, PartialOrd::ge).map(Either::into_inner);
+ itertools::equal(it, it_join)
+ }
+}
+
+quickcheck! {
+ fn size_tee(a: Vec<u8>) -> bool {
+ let (mut t1, mut t2) = a.iter().tee();
+ t1.next();
+ t1.next();
+ t2.next();
+ exact_size(t1) && exact_size(t2)
+ }
+}
+
+quickcheck! {
+ fn size_tee_2(a: Vec<u8>) -> bool {
+ let (mut t1, mut t2) = a.iter().dedup().tee();
+ t1.next();
+ t1.next();
+ t2.next();
+ correct_size_hint(t1) && correct_size_hint(t2)
+ }
+}
+
+quickcheck! {
+ fn size_take_while_ref(a: Vec<u8>, stop: u8) -> bool {
+ correct_size_hint(a.iter().take_while_ref(|x| **x != stop))
+ }
+}
+
+quickcheck! {
+ fn equal_partition(a: Vec<i32>) -> bool {
+ let mut a = a;
+ let mut ap = a.clone();
+ let split_index = itertools::partition(&mut ap, |x| *x >= 0);
+ let parted = (0..split_index).all(|i| ap[i] >= 0) &&
+ (split_index..a.len()).all(|i| ap[i] < 0);
+
+ a.sort();
+ ap.sort();
+ parted && (a == ap)
+ }
+}
+
+quickcheck! {
+ fn size_combinations(it: Iter<i16>) -> bool {
+ correct_size_hint(it.tuple_combinations::<(_, _)>())
+ }
+}
+
+quickcheck! {
+ fn equal_combinations(it: Iter<i16>) -> bool {
+ let values = it.clone().collect_vec();
+ let mut cmb = it.tuple_combinations();
+ for i in 0..values.len() {
+ for j in i+1..values.len() {
+ let pair = (values[i], values[j]);
+ if pair != cmb.next().unwrap() {
+ return false;
+ }
+ }
+ }
+ cmb.next() == None
+ }
+}
+
+quickcheck! {
+ fn size_pad_tail(it: Iter<i8>, pad: u8) -> bool {
+ correct_size_hint(it.clone().pad_using(pad as usize, |_| 0)) &&
+ correct_size_hint(it.dropping(1).rev().pad_using(pad as usize, |_| 0))
+ }
+}
+
+quickcheck! {
+ fn size_pad_tail2(it: Iter<i8, Exact>, pad: u8) -> bool {
+ exact_size(it.pad_using(pad as usize, |_| 0))
+ }
+}
+
+quickcheck! {
+ fn size_powerset(it: Iter<u8, Exact>) -> bool {
+ // Powerset cardinality gets large very quickly, limit input to keep test fast.
+ correct_size_hint(it.take(12).powerset())
+ }
+}
+
+quickcheck! {
+ fn size_duplicates(it: Iter<i8>) -> bool {
+ correct_size_hint(it.duplicates())
+ }
+}
+
+quickcheck! {
+ fn size_unique(it: Iter<i8>) -> bool {
+ correct_size_hint(it.unique())
+ }
+
+ fn count_unique(it: Vec<i8>, take_first: u8) -> () {
+ let answer = {
+ let mut v = it.clone();
+ v.sort(); v.dedup();
+ v.len()
+ };
+ let mut iter = cloned(&it).unique();
+ let first_count = (&mut iter).take(take_first as usize).count();
+ let rest_count = iter.count();
+ assert_eq!(answer, first_count + rest_count);
+ }
+}
+
+quickcheck! {
+ fn fuzz_group_by_lazy_1(it: Iter<u8>) -> bool {
+ let jt = it.clone();
+ let groups = it.group_by(|k| *k);
+ itertools::equal(jt, groups.into_iter().flat_map(|(_, x)| x))
+ }
+}
+
+quickcheck! {
+ fn fuzz_group_by_lazy_2(data: Vec<u8>) -> bool {
+ let groups = data.iter().group_by(|k| *k / 10);
+ let res = itertools::equal(data.iter(), groups.into_iter().flat_map(|(_, x)| x));
+ res
+ }
+}
+
+quickcheck! {
+ fn fuzz_group_by_lazy_3(data: Vec<u8>) -> bool {
+ let grouper = data.iter().group_by(|k| *k / 10);
+ let groups = grouper.into_iter().collect_vec();
+ let res = itertools::equal(data.iter(), groups.into_iter().flat_map(|(_, x)| x));
+ res
+ }
+}
+
+quickcheck! {
+ fn fuzz_group_by_lazy_duo(data: Vec<u8>, order: Vec<(bool, bool)>) -> bool {
+ let grouper = data.iter().group_by(|k| *k / 3);
+ let mut groups1 = grouper.into_iter();
+ let mut groups2 = grouper.into_iter();
+ let mut elts = Vec::<&u8>::new();
+ let mut old_groups = Vec::new();
+
+ let tup1 = |(_, b)| b;
+ for &(ord, consume_now) in &order {
+ let iter = &mut [&mut groups1, &mut groups2][ord as usize];
+ match iter.next() {
+ Some((_, gr)) => if consume_now {
+ for og in old_groups.drain(..) {
+ elts.extend(og);
+ }
+ elts.extend(gr);
+ } else {
+ old_groups.push(gr);
+ },
+ None => break,
+ }
+ }
+ for og in old_groups.drain(..) {
+ elts.extend(og);
+ }
+ for gr in groups1.map(&tup1) { elts.extend(gr); }
+ for gr in groups2.map(&tup1) { elts.extend(gr); }
+ itertools::assert_equal(&data, elts);
+ true
+ }
+}
+
+quickcheck! {
+ fn chunk_clone_equal(a: Vec<u8>, size: u8) -> () {
+ let mut size = size;
+ if size == 0 {
+ size += 1;
+ }
+ let it = a.chunks(size as usize);
+ itertools::assert_equal(it.clone(), it);
+ }
+}
+
+quickcheck! {
+ fn equal_chunks_lazy(a: Vec<u8>, size: u8) -> bool {
+ let mut size = size;
+ if size == 0 {
+ size += 1;
+ }
+ let chunks = a.iter().chunks(size as usize);
+ let it = a.chunks(size as usize);
+ for (a, b) in chunks.into_iter().zip(it) {
+ if !itertools::equal(a, b) {
+ return false;
+ }
+ }
+ true
+ }
+}
+
+// tuple iterators
+quickcheck! {
+ fn equal_circular_tuple_windows_1(a: Vec<u8>) -> bool {
+ let x = a.iter().map(|e| (e,) );
+ let y = a.iter().circular_tuple_windows::<(_,)>();
+ itertools::assert_equal(x,y);
+ true
+ }
+
+ fn equal_circular_tuple_windows_2(a: Vec<u8>) -> bool {
+ let x = (0..a.len()).map(|start_idx| (
+ &a[start_idx],
+ &a[(start_idx + 1) % a.len()],
+ ));
+ let y = a.iter().circular_tuple_windows::<(_, _)>();
+ itertools::assert_equal(x,y);
+ true
+ }
+
+ fn equal_circular_tuple_windows_3(a: Vec<u8>) -> bool {
+ let x = (0..a.len()).map(|start_idx| (
+ &a[start_idx],
+ &a[(start_idx + 1) % a.len()],
+ &a[(start_idx + 2) % a.len()],
+ ));
+ let y = a.iter().circular_tuple_windows::<(_, _, _)>();
+ itertools::assert_equal(x,y);
+ true
+ }
+
+ fn equal_circular_tuple_windows_4(a: Vec<u8>) -> bool {
+ let x = (0..a.len()).map(|start_idx| (
+ &a[start_idx],
+ &a[(start_idx + 1) % a.len()],
+ &a[(start_idx + 2) % a.len()],
+ &a[(start_idx + 3) % a.len()],
+ ));
+ let y = a.iter().circular_tuple_windows::<(_, _, _, _)>();
+ itertools::assert_equal(x,y);
+ true
+ }
+
+ fn equal_cloned_circular_tuple_windows(a: Vec<u8>) -> bool {
+ let x = a.iter().circular_tuple_windows::<(_, _, _, _)>();
+ let y = x.clone();
+ itertools::assert_equal(x,y);
+ true
+ }
+
+ fn equal_cloned_circular_tuple_windows_noninitial(a: Vec<u8>) -> bool {
+ let mut x = a.iter().circular_tuple_windows::<(_, _, _, _)>();
+ let _ = x.next();
+ let y = x.clone();
+ itertools::assert_equal(x,y);
+ true
+ }
+
+ fn equal_cloned_circular_tuple_windows_complete(a: Vec<u8>) -> bool {
+ let mut x = a.iter().circular_tuple_windows::<(_, _, _, _)>();
+ for _ in x.by_ref() {}
+ let y = x.clone();
+ itertools::assert_equal(x,y);
+ true
+ }
+
+ fn equal_tuple_windows_1(a: Vec<u8>) -> bool {
+ let x = a.windows(1).map(|s| (&s[0], ));
+ let y = a.iter().tuple_windows::<(_,)>();
+ itertools::equal(x, y)
+ }
+
+ fn equal_tuple_windows_2(a: Vec<u8>) -> bool {
+ let x = a.windows(2).map(|s| (&s[0], &s[1]));
+ let y = a.iter().tuple_windows::<(_, _)>();
+ itertools::equal(x, y)
+ }
+
+ fn equal_tuple_windows_3(a: Vec<u8>) -> bool {
+ let x = a.windows(3).map(|s| (&s[0], &s[1], &s[2]));
+ let y = a.iter().tuple_windows::<(_, _, _)>();
+ itertools::equal(x, y)
+ }
+
+ fn equal_tuple_windows_4(a: Vec<u8>) -> bool {
+ let x = a.windows(4).map(|s| (&s[0], &s[1], &s[2], &s[3]));
+ let y = a.iter().tuple_windows::<(_, _, _, _)>();
+ itertools::equal(x, y)
+ }
+
+ fn equal_tuples_1(a: Vec<u8>) -> bool {
+ let x = a.chunks(1).map(|s| (&s[0], ));
+ let y = a.iter().tuples::<(_,)>();
+ itertools::equal(x, y)
+ }
+
+ fn equal_tuples_2(a: Vec<u8>) -> bool {
+ let x = a.chunks(2).filter(|s| s.len() == 2).map(|s| (&s[0], &s[1]));
+ let y = a.iter().tuples::<(_, _)>();
+ itertools::equal(x, y)
+ }
+
+ fn equal_tuples_3(a: Vec<u8>) -> bool {
+ let x = a.chunks(3).filter(|s| s.len() == 3).map(|s| (&s[0], &s[1], &s[2]));
+ let y = a.iter().tuples::<(_, _, _)>();
+ itertools::equal(x, y)
+ }
+
+ fn equal_tuples_4(a: Vec<u8>) -> bool {
+ let x = a.chunks(4).filter(|s| s.len() == 4).map(|s| (&s[0], &s[1], &s[2], &s[3]));
+ let y = a.iter().tuples::<(_, _, _, _)>();
+ itertools::equal(x, y)
+ }
+
+ fn exact_tuple_buffer(a: Vec<u8>) -> bool {
+ let mut iter = a.iter().tuples::<(_, _, _, _)>();
+ (&mut iter).last();
+ let buffer = iter.into_buffer();
+ assert_eq!(buffer.len(), a.len() % 4);
+ exact_size(buffer)
+ }
+}
+
+// with_position
+quickcheck! {
+ fn with_position_exact_size_1(a: Vec<u8>) -> bool {
+ exact_size_for_this(a.iter().with_position())
+ }
+ fn with_position_exact_size_2(a: Iter<u8, Exact>) -> bool {
+ exact_size_for_this(a.with_position())
+ }
+}
+
+quickcheck! {
+ fn correct_group_map_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+ let count = a.len();
+ let lookup = a.into_iter().map(|i| (i % modulo, i)).into_group_map();
+
+ assert_eq!(lookup.values().flat_map(|vals| vals.iter()).count(), count);
+
+ for (&key, vals) in lookup.iter() {
+ assert!(vals.iter().all(|&val| val % modulo == key));
+ }
+ }
+}
+
+/// A peculiar type: Equality compares both tuple items, but ordering only the
+/// first item. This is so we can check the stability property easily.
+#[derive(Clone, Debug, PartialEq, Eq)]
+struct Val(u32, u32);
+
+impl PartialOrd<Val> for Val {
+ fn partial_cmp(&self, other: &Val) -> Option<Ordering> {
+ self.0.partial_cmp(&other.0)
+ }
+}
+
+impl Ord for Val {
+ fn cmp(&self, other: &Val) -> Ordering {
+ self.0.cmp(&other.0)
+ }
+}
+
+impl qc::Arbitrary for Val {
+ fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
+ let (x, y) = <(u32, u32)>::arbitrary(g);
+ Val(x, y)
+ }
+ fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
+ Box::new((self.0, self.1).shrink().map(|(x, y)| Val(x, y)))
+ }
+}
+
+quickcheck! {
+ fn minmax(a: Vec<Val>) -> bool {
+ use itertools::MinMaxResult;
+
+
+ let minmax = a.iter().minmax();
+ let expected = match a.len() {
+ 0 => MinMaxResult::NoElements,
+ 1 => MinMaxResult::OneElement(&a[0]),
+ _ => MinMaxResult::MinMax(a.iter().min().unwrap(),
+ a.iter().max().unwrap()),
+ };
+ minmax == expected
+ }
+}
+
+quickcheck! {
+ fn minmax_f64(a: Vec<f64>) -> TestResult {
+ use itertools::MinMaxResult;
+
+ if a.iter().any(|x| x.is_nan()) {
+ return TestResult::discard();
+ }
+
+ let min = cloned(&a).fold1(f64::min);
+ let max = cloned(&a).fold1(f64::max);
+
+ let minmax = cloned(&a).minmax();
+ let expected = match a.len() {
+ 0 => MinMaxResult::NoElements,
+ 1 => MinMaxResult::OneElement(min.unwrap()),
+ _ => MinMaxResult::MinMax(min.unwrap(), max.unwrap()),
+ };
+ TestResult::from_bool(minmax == expected)
+ }
+}
+
+quickcheck! {
+ #[allow(deprecated)]
+ fn tree_fold1_f64(mut a: Vec<f64>) -> TestResult {
+ fn collapse_adjacent<F>(x: Vec<f64>, mut f: F) -> Vec<f64>
+ where F: FnMut(f64, f64) -> f64
+ {
+ let mut out = Vec::new();
+ for i in (0..x.len()).step(2) {
+ if i == x.len()-1 {
+ out.push(x[i])
+ } else {
+ out.push(f(x[i], x[i+1]));
+ }
+ }
+ out
+ }
+
+ if a.iter().any(|x| x.is_nan()) {
+ return TestResult::discard();
+ }
+
+ let actual = a.iter().cloned().tree_fold1(f64::atan2);
+
+ while a.len() > 1 {
+ a = collapse_adjacent(a, f64::atan2);
+ }
+ let expected = a.pop();
+
+ TestResult::from_bool(actual == expected)
+ }
+}
+
+quickcheck! {
+ fn exactly_one_i32(a: Vec<i32>) -> TestResult {
+ let ret = a.iter().cloned().exactly_one();
+ match a.len() {
+ 1 => TestResult::from_bool(ret.unwrap() == a[0]),
+ _ => TestResult::from_bool(ret.unwrap_err().eq(a.iter().cloned())),
+ }
+ }
+}
+
+quickcheck! {
+ fn at_most_one_i32(a: Vec<i32>) -> TestResult {
+ let ret = a.iter().cloned().at_most_one();
+ match a.len() {
+ 0 => TestResult::from_bool(ret.unwrap() == None),
+ 1 => TestResult::from_bool(ret.unwrap() == Some(a[0])),
+ _ => TestResult::from_bool(ret.unwrap_err().eq(a.iter().cloned())),
+ }
+ }
+}
+
+quickcheck! {
+ fn consistent_grouping_map_with_by(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+
+ let lookup_grouping_map = a.iter().copied().map(|i| (i % modulo, i)).into_grouping_map().collect::<Vec<_>>();
+ let lookup_grouping_map_by = a.iter().copied().into_grouping_map_by(|i| i % modulo).collect::<Vec<_>>();
+
+ assert_eq!(lookup_grouping_map, lookup_grouping_map_by);
+ }
+
+ fn correct_grouping_map_by_aggregate_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo < 2 { 2 } else { modulo } as u64; // Avoid `% 0`
+ let lookup = a.iter()
+ .map(|&b| b as u64) // Avoid overflows
+ .into_grouping_map_by(|i| i % modulo)
+ .aggregate(|acc, &key, val| {
+ assert!(val % modulo == key);
+ if val % (modulo - 1) == 0 {
+ None
+ } else {
+ Some(acc.unwrap_or(0) + val)
+ }
+ });
+
+ let group_map_lookup = a.iter()
+ .map(|&b| b as u64)
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .filter_map(|(key, vals)| {
+ vals.into_iter().fold(None, |acc, val| {
+ if val % (modulo - 1) == 0 {
+ None
+ } else {
+ Some(acc.unwrap_or(0) + val)
+ }
+ }).map(|new_val| (key, new_val))
+ })
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for m in 0..modulo {
+ assert_eq!(
+ lookup.get(&m).copied(),
+ a.iter()
+ .map(|&b| b as u64)
+ .filter(|&val| val % modulo == m)
+ .fold(None, |acc, val| {
+ if val % (modulo - 1) == 0 {
+ None
+ } else {
+ Some(acc.unwrap_or(0) + val)
+ }
+ })
+ );
+ }
+ }
+
+ fn correct_grouping_map_by_fold_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo } as u64; // Avoid `% 0`
+ let lookup = a.iter().map(|&b| b as u64) // Avoid overflows
+ .into_grouping_map_by(|i| i % modulo)
+ .fold(0u64, |acc, &key, val| {
+ assert!(val % modulo == key);
+ acc + val
+ });
+
+ let group_map_lookup = a.iter()
+ .map(|&b| b as u64)
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().sum()))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &sum) in lookup.iter() {
+ assert_eq!(sum, a.iter().map(|&b| b as u64).filter(|&val| val % modulo == key).sum::<u64>());
+ }
+ }
+
+ fn correct_grouping_map_by_fold_first_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo } as u64; // Avoid `% 0`
+ let lookup = a.iter().map(|&b| b as u64) // Avoid overflows
+ .into_grouping_map_by(|i| i % modulo)
+ .fold_first(|acc, &key, val| {
+ assert!(val % modulo == key);
+ acc + val
+ });
+
+ // TODO: Swap `fold1` with stdlib's `fold_first` when it's stabilized
+ let group_map_lookup = a.iter()
+ .map(|&b| b as u64)
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().fold1(|acc, val| acc + val).unwrap()))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &sum) in lookup.iter() {
+ assert_eq!(sum, a.iter().map(|&b| b as u64).filter(|&val| val % modulo == key).sum::<u64>());
+ }
+ }
+
+ fn correct_grouping_map_by_collect_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+ let lookup_grouping_map = a.iter().copied().into_grouping_map_by(|i| i % modulo).collect::<Vec<_>>();
+ let lookup_group_map = a.iter().copied().map(|i| (i % modulo, i)).into_group_map();
+
+ assert_eq!(lookup_grouping_map, lookup_group_map);
+ }
+
+ fn correct_grouping_map_by_max_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+ let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).max();
+
+ let group_map_lookup = a.iter().copied()
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().max().unwrap()))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &max) in lookup.iter() {
+ assert_eq!(Some(max), a.iter().copied().filter(|&val| val % modulo == key).max());
+ }
+ }
+
+ fn correct_grouping_map_by_max_by_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+ let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).max_by(|_, v1, v2| v1.cmp(v2));
+
+ let group_map_lookup = a.iter().copied()
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().max_by(|v1, v2| v1.cmp(v2)).unwrap()))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &max) in lookup.iter() {
+ assert_eq!(Some(max), a.iter().copied().filter(|&val| val % modulo == key).max_by(|v1, v2| v1.cmp(v2)));
+ }
+ }
+
+ fn correct_grouping_map_by_max_by_key_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+ let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).max_by_key(|_, &val| val);
+
+ let group_map_lookup = a.iter().copied()
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().max_by_key(|&val| val).unwrap()))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &max) in lookup.iter() {
+ assert_eq!(Some(max), a.iter().copied().filter(|&val| val % modulo == key).max_by_key(|&val| val));
+ }
+ }
+
+ fn correct_grouping_map_by_min_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+ let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).min();
+
+ let group_map_lookup = a.iter().copied()
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().min().unwrap()))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &min) in lookup.iter() {
+ assert_eq!(Some(min), a.iter().copied().filter(|&val| val % modulo == key).min());
+ }
+ }
+
+ fn correct_grouping_map_by_min_by_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+ let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).min_by(|_, v1, v2| v1.cmp(v2));
+
+ let group_map_lookup = a.iter().copied()
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().min_by(|v1, v2| v1.cmp(v2)).unwrap()))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &min) in lookup.iter() {
+ assert_eq!(Some(min), a.iter().copied().filter(|&val| val % modulo == key).min_by(|v1, v2| v1.cmp(v2)));
+ }
+ }
+
+ fn correct_grouping_map_by_min_by_key_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+ let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).min_by_key(|_, &val| val);
+
+ let group_map_lookup = a.iter().copied()
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().min_by_key(|&val| val).unwrap()))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &min) in lookup.iter() {
+ assert_eq!(Some(min), a.iter().copied().filter(|&val| val % modulo == key).min_by_key(|&val| val));
+ }
+ }
+
+ fn correct_grouping_map_by_minmax_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+ let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).minmax();
+
+ let group_map_lookup = a.iter().copied()
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().minmax()))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &minmax) in lookup.iter() {
+ assert_eq!(minmax, a.iter().copied().filter(|&val| val % modulo == key).minmax());
+ }
+ }
+
+ fn correct_grouping_map_by_minmax_by_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+ let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).minmax_by(|_, v1, v2| v1.cmp(v2));
+
+ let group_map_lookup = a.iter().copied()
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().minmax_by(|v1, v2| v1.cmp(v2))))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &minmax) in lookup.iter() {
+ assert_eq!(minmax, a.iter().copied().filter(|&val| val % modulo == key).minmax_by(|v1, v2| v1.cmp(v2)));
+ }
+ }
+
+ fn correct_grouping_map_by_minmax_by_key_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo }; // Avoid `% 0`
+ let lookup = a.iter().copied().into_grouping_map_by(|i| i % modulo).minmax_by_key(|_, &val| val);
+
+ let group_map_lookup = a.iter().copied()
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().minmax_by_key(|&val| val)))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &minmax) in lookup.iter() {
+ assert_eq!(minmax, a.iter().copied().filter(|&val| val % modulo == key).minmax_by_key(|&val| val));
+ }
+ }
+
+ fn correct_grouping_map_by_sum_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = if modulo == 0 { 1 } else { modulo } as u64; // Avoid `% 0`
+ let lookup = a.iter().map(|&b| b as u64) // Avoid overflows
+ .into_grouping_map_by(|i| i % modulo)
+ .sum();
+
+ let group_map_lookup = a.iter().map(|&b| b as u64)
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().sum()))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &sum) in lookup.iter() {
+ assert_eq!(sum, a.iter().map(|&b| b as u64).filter(|&val| val % modulo == key).sum::<u64>());
+ }
+ }
+
+ fn correct_grouping_map_by_product_modulo_key(a: Vec<u8>, modulo: u8) -> () {
+ let modulo = Wrapping(if modulo == 0 { 1 } else { modulo } as u64); // Avoid `% 0`
+ let lookup = a.iter().map(|&b| Wrapping(b as u64)) // Avoid overflows
+ .into_grouping_map_by(|i| i % modulo)
+ .product();
+
+ let group_map_lookup = a.iter().map(|&b| Wrapping(b as u64))
+ .map(|i| (i % modulo, i))
+ .into_group_map()
+ .into_iter()
+ .map(|(key, vals)| (key, vals.into_iter().product::<Wrapping<u64>>()))
+ .collect::<HashMap<_,_>>();
+ assert_eq!(lookup, group_map_lookup);
+
+ for (&key, &prod) in lookup.iter() {
+ assert_eq!(
+ prod,
+ a.iter()
+ .map(|&b| Wrapping(b as u64))
+ .filter(|&val| val % modulo == key)
+ .product::<Wrapping<u64>>()
+ );
+ }
+ }
+
+ // This should check that if multiple elements are equally minimum or maximum
+ // then `max`, `min` and `minmax` pick the first minimum and the last maximum.
+ // This is to be consistent with `std::iter::max` and `std::iter::min`.
+ fn correct_grouping_map_by_min_max_minmax_order_modulo_key() -> () {
+ use itertools::MinMaxResult;
+
+ let lookup = (0..=10)
+ .into_grouping_map_by(|_| 0)
+ .max_by(|_, _, _| Ordering::Equal);
+
+ assert_eq!(lookup[&0], 10);
+
+ let lookup = (0..=10)
+ .into_grouping_map_by(|_| 0)
+ .min_by(|_, _, _| Ordering::Equal);
+
+ assert_eq!(lookup[&0], 0);
+
+ let lookup = (0..=10)
+ .into_grouping_map_by(|_| 0)
+ .minmax_by(|_, _, _| Ordering::Equal);
+
+ assert_eq!(lookup[&0], MinMaxResult::MinMax(0, 10));
+ }
+}
+
+quickcheck! {
+ fn counts(nums: Vec<isize>) -> TestResult {
+ let counts = nums.iter().counts();
+ for (&item, &count) in counts.iter() {
+ #[allow(clippy::absurd_extreme_comparisons)]
+ if count <= 0 {
+ return TestResult::failed();
+ }
+ if count != nums.iter().filter(|&x| x == item).count() {
+ return TestResult::failed();
+ }
+ }
+ for item in nums.iter() {
+ if !counts.contains_key(item) {
+ return TestResult::failed();
+ }
+ }
+ TestResult::passed()
+ }
+}
+
+quickcheck! {
+ fn test_double_ended_zip_2(a: Vec<u8>, b: Vec<u8>) -> TestResult {
+ let mut x =
+ multizip((a.clone().into_iter(), b.clone().into_iter()))
+ .collect_vec();
+ x.reverse();
+
+ let y =
+ multizip((a.into_iter(), b.into_iter()))
+ .rfold(Vec::new(), |mut vec, e| { vec.push(e); vec });
+
+ TestResult::from_bool(itertools::equal(x, y))
+ }
+
+ fn test_double_ended_zip_3(a: Vec<u8>, b: Vec<u8>, c: Vec<u8>) -> TestResult {
+ let mut x =
+ multizip((a.clone().into_iter(), b.clone().into_iter(), c.clone().into_iter()))
+ .collect_vec();
+ x.reverse();
+
+ let y =
+ multizip((a.into_iter(), b.into_iter(), c.into_iter()))
+ .rfold(Vec::new(), |mut vec, e| { vec.push(e); vec });
+
+ TestResult::from_bool(itertools::equal(x, y))
+ }
+}
+
+
+fn is_fused<I: Iterator>(mut it: I) -> bool
+{
+ for _ in it.by_ref() {}
+ for _ in 0..10{
+ if it.next().is_some(){
+ return false;
+ }
+ }
+ true
+}
+
+quickcheck! {
+ fn fused_combination(a: Iter<i16>) -> bool
+ {
+ is_fused(a.clone().combinations(1)) &&
+ is_fused(a.combinations(3))
+ }
+
+ fn fused_combination_with_replacement(a: Iter<i16>) -> bool
+ {
+ is_fused(a.clone().combinations_with_replacement(1)) &&
+ is_fused(a.combinations_with_replacement(3))
+ }
+
+ fn fused_tuple_combination(a: Iter<i16>) -> bool
+ {
+ is_fused(a.clone().fuse().tuple_combinations::<(_,)>()) &&
+ is_fused(a.fuse().tuple_combinations::<(_,_,_)>())
+ }
+
+ fn fused_unique(a: Iter<i16>) -> bool
+ {
+ is_fused(a.fuse().unique())
+ }
+
+ fn fused_unique_by(a: Iter<i16>) -> bool
+ {
+ is_fused(a.fuse().unique_by(|x| x % 100))
+ }
+
+ fn fused_interleave_shortest(a: Iter<i16>, b: Iter<i16>) -> bool
+ {
+ !is_fused(a.clone().interleave_shortest(b.clone())) &&
+ is_fused(a.fuse().interleave_shortest(b.fuse()))
+ }
+
+ fn fused_product(a: Iter<i16>, b: Iter<i16>) -> bool
+ {
+ is_fused(a.fuse().cartesian_product(b.fuse()))
+ }
+
+ fn fused_merge(a: Iter<i16>, b: Iter<i16>) -> bool
+ {
+ is_fused(a.fuse().merge(b.fuse()))
+ }
+
+ fn fused_filter_ok(a: Iter<i16>) -> bool
+ {
+ is_fused(a.map(|x| if x % 2 == 0 {Ok(x)} else {Err(x)} )
+ .filter_ok(|x| x % 3 == 0)
+ .fuse())
+ }
+
+ fn fused_filter_map_ok(a: Iter<i16>) -> bool
+ {
+ is_fused(a.map(|x| if x % 2 == 0 {Ok(x)} else {Err(x)} )
+ .filter_map_ok(|x| if x % 3 == 0 {Some(x / 3)} else {None})
+ .fuse())
+ }
+
+ fn fused_positions(a: Iter<i16>) -> bool
+ {
+ !is_fused(a.clone().positions(|x|x%2==0)) &&
+ is_fused(a.fuse().positions(|x|x%2==0))
+ }
+
+ fn fused_update(a: Iter<i16>) -> bool
+ {
+ !is_fused(a.clone().update(|x|*x+=1)) &&
+ is_fused(a.fuse().update(|x|*x+=1))
+ }
+
+ fn fused_tuple_windows(a: Iter<i16>) -> bool
+ {
+ is_fused(a.fuse().tuple_windows::<(_,_)>())
+ }
+
+ fn fused_pad_using(a: Iter<i16>) -> bool
+ {
+ is_fused(a.fuse().pad_using(100,|_|0))
+ }
+}
+
+quickcheck! {
+ fn min_set_contains_min(a: Vec<(usize, char)>) -> bool {
+ let result_set = a.iter().min_set();
+ if let Some(result_element) = a.iter().min() {
+ result_set.contains(&result_element)
+ } else {
+ result_set.is_empty()
+ }
+ }
+
+ fn min_set_by_contains_min(a: Vec<(usize, char)>) -> bool {
+ let compare = |x: &&(usize, char), y: &&(usize, char)| x.1.cmp(&y.1);
+ let result_set = a.iter().min_set_by(compare);
+ if let Some(result_element) = a.iter().min_by(compare) {
+ result_set.contains(&result_element)
+ } else {
+ result_set.is_empty()
+ }
+ }
+
+ fn min_set_by_key_contains_min(a: Vec<(usize, char)>) -> bool {
+ let key = |x: &&(usize, char)| x.1;
+ let result_set = a.iter().min_set_by_key(&key);
+ if let Some(result_element) = a.iter().min_by_key(&key) {
+ result_set.contains(&result_element)
+ } else {
+ result_set.is_empty()
+ }
+ }
+
+ fn max_set_contains_max(a: Vec<(usize, char)>) -> bool {
+ let result_set = a.iter().max_set();
+ if let Some(result_element) = a.iter().max() {
+ result_set.contains(&result_element)
+ } else {
+ result_set.is_empty()
+ }
+ }
+
+ fn max_set_by_contains_max(a: Vec<(usize, char)>) -> bool {
+ let compare = |x: &&(usize, char), y: &&(usize, char)| x.1.cmp(&y.1);
+ let result_set = a.iter().max_set_by(compare);
+ if let Some(result_element) = a.iter().max_by(compare) {
+ result_set.contains(&result_element)
+ } else {
+ result_set.is_empty()
+ }
+ }
+
+ fn max_set_by_key_contains_max(a: Vec<(usize, char)>) -> bool {
+ let key = |x: &&(usize, char)| x.1;
+ let result_set = a.iter().max_set_by_key(&key);
+ if let Some(result_element) = a.iter().max_by_key(&key) {
+ result_set.contains(&result_element)
+ } else {
+ result_set.is_empty()
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/tests/specializations.rs b/rust/hw/char/pl011/vendor/itertools/tests/specializations.rs
new file mode 100644
index 0000000000..057e11c9f6
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/tests/specializations.rs
@@ -0,0 +1,153 @@
+use itertools::Itertools;
+use std::fmt::Debug;
+use quickcheck::quickcheck;
+
+struct Unspecialized<I>(I);
+impl<I> Iterator for Unspecialized<I>
+where
+ I: Iterator,
+{
+ type Item = I::Item;
+
+ #[inline(always)]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next()
+ }
+}
+
+macro_rules! check_specialized {
+ ($src:expr, |$it:pat| $closure:expr) => {
+ let $it = $src.clone();
+ let v1 = $closure;
+
+ let $it = Unspecialized($src.clone());
+ let v2 = $closure;
+
+ assert_eq!(v1, v2);
+ }
+}
+
+fn test_specializations<IterItem, Iter>(
+ it: &Iter,
+) where
+ IterItem: Eq + Debug + Clone,
+ Iter: Iterator<Item = IterItem> + Clone,
+{
+ check_specialized!(it, |i| i.count());
+ check_specialized!(it, |i| i.last());
+ check_specialized!(it, |i| i.collect::<Vec<_>>());
+ check_specialized!(it, |i| {
+ let mut parameters_from_fold = vec![];
+ let fold_result = i.fold(vec![], |mut acc, v: IterItem| {
+ parameters_from_fold.push((acc.clone(), v.clone()));
+ acc.push(v);
+ acc
+ });
+ (parameters_from_fold, fold_result)
+ });
+ check_specialized!(it, |mut i| {
+ let mut parameters_from_all = vec![];
+ let first = i.next();
+ let all_result = i.all(|x| {
+ parameters_from_all.push(x.clone());
+ Some(x)==first
+ });
+ (parameters_from_all, all_result)
+ });
+ let size = it.clone().count();
+ for n in 0..size + 2 {
+ check_specialized!(it, |mut i| i.nth(n));
+ }
+ // size_hint is a bit harder to check
+ let mut it_sh = it.clone();
+ for n in 0..size + 2 {
+ let len = it_sh.clone().count();
+ let (min, max) = it_sh.size_hint();
+ assert_eq!(size - n.min(size), len);
+ assert!(min <= len);
+ if let Some(max) = max {
+ assert!(len <= max);
+ }
+ it_sh.next();
+ }
+}
+
+quickcheck! {
+ fn intersperse(v: Vec<u8>) -> () {
+ test_specializations(&v.into_iter().intersperse(0));
+ }
+}
+
+quickcheck! {
+ fn put_back_qc(test_vec: Vec<i32>) -> () {
+ test_specializations(&itertools::put_back(test_vec.iter()));
+ let mut pb = itertools::put_back(test_vec.into_iter());
+ pb.put_back(1);
+ test_specializations(&pb);
+ }
+}
+
+quickcheck! {
+ fn merge_join_by_qc(i1: Vec<usize>, i2: Vec<usize>) -> () {
+ test_specializations(&i1.into_iter().merge_join_by(i2.into_iter(), std::cmp::Ord::cmp));
+ }
+}
+
+quickcheck! {
+ fn map_into(v: Vec<u8>) -> () {
+ test_specializations(&v.into_iter().map_into::<u32>());
+ }
+}
+
+quickcheck! {
+ fn map_ok(v: Vec<Result<u8, char>>) -> () {
+ test_specializations(&v.into_iter().map_ok(|u| u.checked_add(1)));
+ }
+}
+
+quickcheck! {
+ fn process_results(v: Vec<Result<u8, u8>>) -> () {
+ helper(v.iter().copied());
+ helper(v.iter().copied().filter(Result::is_ok));
+
+ fn helper(it: impl Iterator<Item = Result<u8, u8>> + Clone) {
+ macro_rules! check_results_specialized {
+ ($src:expr, |$it:pat| $closure:expr) => {
+ assert_eq!(
+ itertools::process_results($src.clone(), |$it| $closure),
+ itertools::process_results($src.clone(), |i| {
+ let $it = Unspecialized(i);
+ $closure
+ }),
+ )
+ }
+ }
+
+ check_results_specialized!(it, |i| i.count());
+ check_results_specialized!(it, |i| i.last());
+ check_results_specialized!(it, |i| i.collect::<Vec<_>>());
+ check_results_specialized!(it, |i| {
+ let mut parameters_from_fold = vec![];
+ let fold_result = i.fold(vec![], |mut acc, v| {
+ parameters_from_fold.push((acc.clone(), v));
+ acc.push(v);
+ acc
+ });
+ (parameters_from_fold, fold_result)
+ });
+ check_results_specialized!(it, |mut i| {
+ let mut parameters_from_all = vec![];
+ let first = i.next();
+ let all_result = i.all(|x| {
+ parameters_from_all.push(x);
+ Some(x)==first
+ });
+ (parameters_from_all, all_result)
+ });
+ let size = it.clone().count();
+ for n in 0..size + 2 {
+ check_results_specialized!(it, |mut i| i.nth(n));
+ }
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/tests/test_core.rs b/rust/hw/char/pl011/vendor/itertools/tests/test_core.rs
new file mode 100644
index 0000000000..df94eb665f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/tests/test_core.rs
@@ -0,0 +1,317 @@
+//! Licensed under the Apache License, Version 2.0
+//! https://www.apache.org/licenses/LICENSE-2.0 or the MIT license
+//! https://opensource.org/licenses/MIT, at your
+//! option. This file may not be copied, modified, or distributed
+//! except according to those terms.
+#![no_std]
+
+use core::iter;
+use itertools as it;
+use crate::it::Itertools;
+use crate::it::interleave;
+use crate::it::intersperse;
+use crate::it::intersperse_with;
+use crate::it::multizip;
+use crate::it::free::put_back;
+use crate::it::iproduct;
+use crate::it::izip;
+use crate::it::chain;
+
+#[test]
+fn product2() {
+ let s = "αβ";
+
+ let mut prod = iproduct!(s.chars(), 0..2);
+ assert!(prod.next() == Some(('α', 0)));
+ assert!(prod.next() == Some(('α', 1)));
+ assert!(prod.next() == Some(('β', 0)));
+ assert!(prod.next() == Some(('β', 1)));
+ assert!(prod.next() == None);
+}
+
+#[test]
+fn product_temporary() {
+ for (_x, _y, _z) in iproduct!(
+ [0, 1, 2].iter().cloned(),
+ [0, 1, 2].iter().cloned(),
+ [0, 1, 2].iter().cloned())
+ {
+ // ok
+ }
+}
+
+
+#[test]
+fn izip_macro() {
+ let mut zip = izip!(2..3);
+ assert!(zip.next() == Some(2));
+ assert!(zip.next().is_none());
+
+ let mut zip = izip!(0..3, 0..2, 0..2i8);
+ for i in 0..2 {
+ assert!((i as usize, i, i as i8) == zip.next().unwrap());
+ }
+ assert!(zip.next().is_none());
+
+ let xs: [isize; 0] = [];
+ let mut zip = izip!(0..3, 0..2, 0..2i8, &xs);
+ assert!(zip.next().is_none());
+}
+
+#[test]
+fn izip2() {
+ let _zip1: iter::Zip<_, _> = izip!(1.., 2..);
+ let _zip2: iter::Zip<_, _> = izip!(1.., 2.., );
+}
+
+#[test]
+fn izip3() {
+ let mut zip: iter::Map<iter::Zip<_, _>, _> = izip!(0..3, 0..2, 0..2i8);
+ for i in 0..2 {
+ assert!((i as usize, i, i as i8) == zip.next().unwrap());
+ }
+ assert!(zip.next().is_none());
+}
+
+#[test]
+fn multizip3() {
+ let mut zip = multizip((0..3, 0..2, 0..2i8));
+ for i in 0..2 {
+ assert!((i as usize, i, i as i8) == zip.next().unwrap());
+ }
+ assert!(zip.next().is_none());
+
+ let xs: [isize; 0] = [];
+ let mut zip = multizip((0..3, 0..2, 0..2i8, xs.iter()));
+ assert!(zip.next().is_none());
+
+ for (_, _, _, _, _) in multizip((0..3, 0..2, xs.iter(), &xs, xs.to_vec())) {
+ /* test compiles */
+ }
+}
+
+#[test]
+fn chain_macro() {
+ let mut chain = chain!(2..3);
+ assert!(chain.next() == Some(2));
+ assert!(chain.next().is_none());
+
+ let mut chain = chain!(0..2, 2..3, 3..5i8);
+ for i in 0..5i8 {
+ assert_eq!(Some(i), chain.next());
+ }
+ assert!(chain.next().is_none());
+
+ let mut chain = chain!();
+ assert_eq!(chain.next(), Option::<()>::None);
+}
+
+#[test]
+fn chain2() {
+ let _ = chain!(1.., 2..);
+ let _ = chain!(1.., 2.., );
+}
+
+#[test]
+fn write_to() {
+ let xs = [7, 9, 8];
+ let mut ys = [0; 5];
+ let cnt = ys.iter_mut().set_from(xs.iter().copied());
+ assert!(cnt == xs.len());
+ assert!(ys == [7, 9, 8, 0, 0]);
+
+ let cnt = ys.iter_mut().set_from(0..10);
+ assert!(cnt == ys.len());
+ assert!(ys == [0, 1, 2, 3, 4]);
+}
+
+#[test]
+fn test_interleave() {
+ let xs: [u8; 0] = [];
+ let ys = [7u8, 9, 8, 10];
+ let zs = [2u8, 77];
+ let it = interleave(xs.iter(), ys.iter());
+ it::assert_equal(it, ys.iter());
+
+ let rs = [7u8, 2, 9, 77, 8, 10];
+ let it = interleave(ys.iter(), zs.iter());
+ it::assert_equal(it, rs.iter());
+}
+
+#[test]
+fn test_intersperse() {
+ let xs = [1u8, 2, 3];
+ let ys = [1u8, 0, 2, 0, 3];
+ let it = intersperse(&xs, &0);
+ it::assert_equal(it, ys.iter());
+}
+
+#[test]
+fn test_intersperse_with() {
+ let xs = [1u8, 2, 3];
+ let ys = [1u8, 10, 2, 10, 3];
+ let i = 10;
+ let it = intersperse_with(&xs, || &i);
+ it::assert_equal(it, ys.iter());
+}
+
+#[allow(deprecated)]
+#[test]
+fn foreach() {
+ let xs = [1i32, 2, 3];
+ let mut sum = 0;
+ xs.iter().foreach(|elt| sum += *elt);
+ assert!(sum == 6);
+}
+
+#[test]
+fn dropping() {
+ let xs = [1, 2, 3];
+ let mut it = xs.iter().dropping(2);
+ assert_eq!(it.next(), Some(&3));
+ assert!(it.next().is_none());
+ let mut it = xs.iter().dropping(5);
+ assert!(it.next().is_none());
+}
+
+#[test]
+fn batching() {
+ let xs = [0, 1, 2, 1, 3];
+ let ys = [(0, 1), (2, 1)];
+
+ // An iterator that gathers elements up in pairs
+ let pit = xs
+ .iter()
+ .cloned()
+ .batching(|it| it.next().and_then(|x| it.next().map(|y| (x, y))));
+ it::assert_equal(pit, ys.iter().cloned());
+}
+
+#[test]
+fn test_put_back() {
+ let xs = [0, 1, 1, 1, 2, 1, 3, 3];
+ let mut pb = put_back(xs.iter().cloned());
+ pb.next();
+ pb.put_back(1);
+ pb.put_back(0);
+ it::assert_equal(pb, xs.iter().cloned());
+}
+
+#[allow(deprecated)]
+#[test]
+fn step() {
+ it::assert_equal((0..10).step(1), 0..10);
+ it::assert_equal((0..10).step(2), (0..10).filter(|x: &i32| *x % 2 == 0));
+ it::assert_equal((0..10).step(10), 0..1);
+}
+
+#[allow(deprecated)]
+#[test]
+fn merge() {
+ it::assert_equal((0..10).step(2).merge((1..10).step(2)), 0..10);
+}
+
+
+#[test]
+fn repeatn() {
+ let s = "α";
+ let mut it = it::repeat_n(s, 3);
+ assert_eq!(it.len(), 3);
+ assert_eq!(it.next(), Some(s));
+ assert_eq!(it.next(), Some(s));
+ assert_eq!(it.next(), Some(s));
+ assert_eq!(it.next(), None);
+ assert_eq!(it.next(), None);
+}
+
+#[test]
+fn count_clones() {
+ // Check that RepeatN only clones N - 1 times.
+
+ use core::cell::Cell;
+ #[derive(PartialEq, Debug)]
+ struct Foo {
+ n: Cell<usize>
+ }
+
+ impl Clone for Foo
+ {
+ fn clone(&self) -> Self
+ {
+ let n = self.n.get();
+ self.n.set(n + 1);
+ Foo { n: Cell::new(n + 1) }
+ }
+ }
+
+
+ for n in 0..10 {
+ let f = Foo{n: Cell::new(0)};
+ let it = it::repeat_n(f, n);
+ // drain it
+ let last = it.last();
+ if n == 0 {
+ assert_eq!(last, None);
+ } else {
+ assert_eq!(last, Some(Foo{n: Cell::new(n - 1)}));
+ }
+ }
+}
+
+#[test]
+fn part() {
+ let mut data = [7, 1, 1, 9, 1, 1, 3];
+ let i = it::partition(&mut data, |elt| *elt >= 3);
+ assert_eq!(i, 3);
+ assert_eq!(data, [7, 3, 9, 1, 1, 1, 1]);
+
+ let i = it::partition(&mut data, |elt| *elt == 1);
+ assert_eq!(i, 4);
+ assert_eq!(data, [1, 1, 1, 1, 9, 3, 7]);
+
+ let mut data = [1, 2, 3, 4, 5, 6, 7, 8, 9];
+ let i = it::partition(&mut data, |elt| *elt % 3 == 0);
+ assert_eq!(i, 3);
+ assert_eq!(data, [9, 6, 3, 4, 5, 2, 7, 8, 1]);
+}
+
+#[test]
+fn tree_fold1() {
+ for i in 0..100 {
+ assert_eq!((0..i).tree_fold1(|x, y| x + y), (0..i).fold1(|x, y| x + y));
+ }
+}
+
+#[test]
+fn exactly_one() {
+ assert_eq!((0..10).filter(|&x| x == 2).exactly_one().unwrap(), 2);
+ assert!((0..10).filter(|&x| x > 1 && x < 4).exactly_one().unwrap_err().eq(2..4));
+ assert!((0..10).filter(|&x| x > 1 && x < 5).exactly_one().unwrap_err().eq(2..5));
+ assert!((0..10).filter(|&_| false).exactly_one().unwrap_err().eq(0..0));
+}
+
+#[test]
+fn at_most_one() {
+ assert_eq!((0..10).filter(|&x| x == 2).at_most_one().unwrap(), Some(2));
+ assert!((0..10).filter(|&x| x > 1 && x < 4).at_most_one().unwrap_err().eq(2..4));
+ assert!((0..10).filter(|&x| x > 1 && x < 5).at_most_one().unwrap_err().eq(2..5));
+ assert_eq!((0..10).filter(|&_| false).at_most_one().unwrap(), None);
+}
+
+#[test]
+fn sum1() {
+ let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ assert_eq!(v[..0].iter().cloned().sum1::<i32>(), None);
+ assert_eq!(v[1..2].iter().cloned().sum1::<i32>(), Some(1));
+ assert_eq!(v[1..3].iter().cloned().sum1::<i32>(), Some(3));
+ assert_eq!(v.iter().cloned().sum1::<i32>(), Some(55));
+}
+
+#[test]
+fn product1() {
+ let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ assert_eq!(v[..0].iter().cloned().product1::<i32>(), None);
+ assert_eq!(v[..1].iter().cloned().product1::<i32>(), Some(0));
+ assert_eq!(v[1..3].iter().cloned().product1::<i32>(), Some(2));
+ assert_eq!(v[1..5].iter().cloned().product1::<i32>(), Some(24));
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/tests/test_std.rs b/rust/hw/char/pl011/vendor/itertools/tests/test_std.rs
new file mode 100644
index 0000000000..77207d87e3
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/tests/test_std.rs
@@ -0,0 +1,1184 @@
+use quickcheck as qc;
+use rand::{distributions::{Distribution, Standard}, Rng, SeedableRng, rngs::StdRng};
+use rand::{seq::SliceRandom, thread_rng};
+use std::{cmp::min, fmt::Debug, marker::PhantomData};
+use itertools as it;
+use crate::it::Itertools;
+use crate::it::ExactlyOneError;
+use crate::it::multizip;
+use crate::it::multipeek;
+use crate::it::peek_nth;
+use crate::it::free::rciter;
+use crate::it::free::put_back_n;
+use crate::it::FoldWhile;
+use crate::it::cloned;
+use crate::it::iproduct;
+use crate::it::izip;
+
+#[test]
+fn product3() {
+ let prod = iproduct!(0..3, 0..2, 0..2);
+ assert_eq!(prod.size_hint(), (12, Some(12)));
+ let v = prod.collect_vec();
+ for i in 0..3 {
+ for j in 0..2 {
+ for k in 0..2 {
+ assert!((i, j, k) == v[(i * 2 * 2 + j * 2 + k) as usize]);
+ }
+ }
+ }
+ for (_, _, _, _) in iproduct!(0..3, 0..2, 0..2, 0..3) {
+ /* test compiles */
+ }
+}
+
+#[test]
+fn interleave_shortest() {
+ let v0: Vec<i32> = vec![0, 2, 4];
+ let v1: Vec<i32> = vec![1, 3, 5, 7];
+ let it = v0.into_iter().interleave_shortest(v1.into_iter());
+ assert_eq!(it.size_hint(), (6, Some(6)));
+ assert_eq!(it.collect_vec(), vec![0, 1, 2, 3, 4, 5]);
+
+ let v0: Vec<i32> = vec![0, 2, 4, 6, 8];
+ let v1: Vec<i32> = vec![1, 3, 5];
+ let it = v0.into_iter().interleave_shortest(v1.into_iter());
+ assert_eq!(it.size_hint(), (7, Some(7)));
+ assert_eq!(it.collect_vec(), vec![0, 1, 2, 3, 4, 5, 6]);
+
+ let i0 = ::std::iter::repeat(0);
+ let v1: Vec<_> = vec![1, 3, 5];
+ let it = i0.interleave_shortest(v1.into_iter());
+ assert_eq!(it.size_hint(), (7, Some(7)));
+
+ let v0: Vec<_> = vec![0, 2, 4];
+ let i1 = ::std::iter::repeat(1);
+ let it = v0.into_iter().interleave_shortest(i1);
+ assert_eq!(it.size_hint(), (6, Some(6)));
+}
+
+#[test]
+fn duplicates_by() {
+ let xs = ["aaa", "bbbbb", "aa", "ccc", "bbbb", "aaaaa", "cccc"];
+ let ys = ["aa", "bbbb", "cccc"];
+ it::assert_equal(ys.iter(), xs.iter().duplicates_by(|x| x[..2].to_string()));
+ it::assert_equal(ys.iter(), xs.iter().rev().duplicates_by(|x| x[..2].to_string()).rev());
+ let ys_rev = ["ccc", "aa", "bbbbb"];
+ it::assert_equal(ys_rev.iter(), xs.iter().duplicates_by(|x| x[..2].to_string()).rev());
+}
+
+#[test]
+fn duplicates() {
+ let xs = [0, 1, 2, 3, 2, 1, 3];
+ let ys = [2, 1, 3];
+ it::assert_equal(ys.iter(), xs.iter().duplicates());
+ it::assert_equal(ys.iter(), xs.iter().rev().duplicates().rev());
+ let ys_rev = [3, 2, 1];
+ it::assert_equal(ys_rev.iter(), xs.iter().duplicates().rev());
+
+ let xs = [0, 1, 0, 1];
+ let ys = [0, 1];
+ it::assert_equal(ys.iter(), xs.iter().duplicates());
+ it::assert_equal(ys.iter(), xs.iter().rev().duplicates().rev());
+ let ys_rev = [1, 0];
+ it::assert_equal(ys_rev.iter(), xs.iter().duplicates().rev());
+
+ let xs = vec![0, 1, 2, 1, 2];
+ let ys = vec![1, 2];
+ assert_eq!(ys, xs.iter().duplicates().cloned().collect_vec());
+ assert_eq!(ys, xs.iter().rev().duplicates().rev().cloned().collect_vec());
+ let ys_rev = vec![2, 1];
+ assert_eq!(ys_rev, xs.iter().duplicates().rev().cloned().collect_vec());
+}
+
+#[test]
+fn unique_by() {
+ let xs = ["aaa", "bbbbb", "aa", "ccc", "bbbb", "aaaaa", "cccc"];
+ let ys = ["aaa", "bbbbb", "ccc"];
+ it::assert_equal(ys.iter(), xs.iter().unique_by(|x| x[..2].to_string()));
+ it::assert_equal(ys.iter(), xs.iter().rev().unique_by(|x| x[..2].to_string()).rev());
+ let ys_rev = ["cccc", "aaaaa", "bbbb"];
+ it::assert_equal(ys_rev.iter(), xs.iter().unique_by(|x| x[..2].to_string()).rev());
+}
+
+#[test]
+fn unique() {
+ let xs = [0, 1, 2, 3, 2, 1, 3];
+ let ys = [0, 1, 2, 3];
+ it::assert_equal(ys.iter(), xs.iter().unique());
+ it::assert_equal(ys.iter(), xs.iter().rev().unique().rev());
+ let ys_rev = [3, 1, 2, 0];
+ it::assert_equal(ys_rev.iter(), xs.iter().unique().rev());
+
+ let xs = [0, 1];
+ let ys = [0, 1];
+ it::assert_equal(ys.iter(), xs.iter().unique());
+ it::assert_equal(ys.iter(), xs.iter().rev().unique().rev());
+ let ys_rev = [1, 0];
+ it::assert_equal(ys_rev.iter(), xs.iter().unique().rev());
+}
+
+#[test]
+fn intersperse() {
+ let xs = ["a", "", "b", "c"];
+ let v: Vec<&str> = xs.iter().cloned().intersperse(", ").collect();
+ let text: String = v.concat();
+ assert_eq!(text, "a, , b, c".to_string());
+
+ let ys = [0, 1, 2, 3];
+ let mut it = ys[..0].iter().copied().intersperse(1);
+ assert!(it.next() == None);
+}
+
+#[test]
+fn dedup() {
+ let xs = [0, 1, 1, 1, 2, 1, 3, 3];
+ let ys = [0, 1, 2, 1, 3];
+ it::assert_equal(ys.iter(), xs.iter().dedup());
+ let xs = [0, 0, 0, 0, 0];
+ let ys = [0];
+ it::assert_equal(ys.iter(), xs.iter().dedup());
+
+ let xs = [0, 1, 1, 1, 2, 1, 3, 3];
+ let ys = [0, 1, 2, 1, 3];
+ let mut xs_d = Vec::new();
+ xs.iter().dedup().fold((), |(), &elt| xs_d.push(elt));
+ assert_eq!(&xs_d, &ys);
+}
+
+#[test]
+fn coalesce() {
+ let data = vec![-1., -2., -3., 3., 1., 0., -1.];
+ let it = data.iter().cloned().coalesce(|x, y|
+ if (x >= 0.) == (y >= 0.) {
+ Ok(x + y)
+ } else {
+ Err((x, y))
+ }
+ );
+ itertools::assert_equal(it.clone(), vec![-6., 4., -1.]);
+ assert_eq!(
+ it.fold(vec![], |mut v, n| {
+ v.push(n);
+ v
+ }),
+ vec![-6., 4., -1.]
+ );
+}
+
+#[test]
+fn dedup_by() {
+ let xs = [(0, 0), (0, 1), (1, 1), (2, 1), (0, 2), (3, 1), (0, 3), (1, 3)];
+ let ys = [(0, 0), (0, 1), (0, 2), (3, 1), (0, 3)];
+ it::assert_equal(ys.iter(), xs.iter().dedup_by(|x, y| x.1==y.1));
+ let xs = [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5)];
+ let ys = [(0, 1)];
+ it::assert_equal(ys.iter(), xs.iter().dedup_by(|x, y| x.0==y.0));
+
+ let xs = [(0, 0), (0, 1), (1, 1), (2, 1), (0, 2), (3, 1), (0, 3), (1, 3)];
+ let ys = [(0, 0), (0, 1), (0, 2), (3, 1), (0, 3)];
+ let mut xs_d = Vec::new();
+ xs.iter().dedup_by(|x, y| x.1==y.1).fold((), |(), &elt| xs_d.push(elt));
+ assert_eq!(&xs_d, &ys);
+}
+
+#[test]
+fn dedup_with_count() {
+ let xs: [i32; 8] = [0, 1, 1, 1, 2, 1, 3, 3];
+ let ys: [(usize, &i32); 5] = [(1, &0), (3, &1), (1, &2), (1, &1), (2, &3)];
+
+ it::assert_equal(ys.iter().cloned(), xs.iter().dedup_with_count());
+
+ let xs: [i32; 5] = [0, 0, 0, 0, 0];
+ let ys: [(usize, &i32); 1] = [(5, &0)];
+
+ it::assert_equal(ys.iter().cloned(), xs.iter().dedup_with_count());
+}
+
+
+#[test]
+fn dedup_by_with_count() {
+ let xs = [(0, 0), (0, 1), (1, 1), (2, 1), (0, 2), (3, 1), (0, 3), (1, 3)];
+ let ys = [(1, &(0, 0)), (3, &(0, 1)), (1, &(0, 2)), (1, &(3, 1)), (2, &(0, 3))];
+
+ it::assert_equal(ys.iter().cloned(), xs.iter().dedup_by_with_count(|x, y| x.1==y.1));
+
+ let xs = [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5)];
+ let ys = [( 5, &(0, 1))];
+
+ it::assert_equal(ys.iter().cloned(), xs.iter().dedup_by_with_count(|x, y| x.0==y.0));
+}
+
+#[test]
+fn all_equal() {
+ assert!("".chars().all_equal());
+ assert!("A".chars().all_equal());
+ assert!(!"AABBCCC".chars().all_equal());
+ assert!("AAAAAAA".chars().all_equal());
+ for (_key, mut sub) in &"AABBCCC".chars().group_by(|&x| x) {
+ assert!(sub.all_equal());
+ }
+}
+
+#[test]
+fn all_equal_value() {
+ assert_eq!("".chars().all_equal_value(), Err(None));
+ assert_eq!("A".chars().all_equal_value(), Ok('A'));
+ assert_eq!("AABBCCC".chars().all_equal_value(), Err(Some(('A', 'B'))));
+ assert_eq!("AAAAAAA".chars().all_equal_value(), Ok('A'));
+ {
+ let mut it = [1,2,3].iter().copied();
+ let result = it.all_equal_value();
+ assert_eq!(result, Err(Some((1, 2))));
+ let remaining = it.next();
+ assert_eq!(remaining, Some(3));
+ assert!(it.next().is_none());
+ }
+}
+
+#[test]
+fn all_unique() {
+ assert!("ABCDEFGH".chars().all_unique());
+ assert!(!"ABCDEFGA".chars().all_unique());
+ assert!(::std::iter::empty::<usize>().all_unique());
+}
+
+#[test]
+fn test_put_back_n() {
+ let xs = [0, 1, 1, 1, 2, 1, 3, 3];
+ let mut pb = put_back_n(xs.iter().cloned());
+ pb.next();
+ pb.next();
+ pb.put_back(1);
+ pb.put_back(0);
+ it::assert_equal(pb, xs.iter().cloned());
+}
+
+#[test]
+fn tee() {
+ let xs = [0, 1, 2, 3];
+ let (mut t1, mut t2) = xs.iter().cloned().tee();
+ assert_eq!(t1.next(), Some(0));
+ assert_eq!(t2.next(), Some(0));
+ assert_eq!(t1.next(), Some(1));
+ assert_eq!(t1.next(), Some(2));
+ assert_eq!(t1.next(), Some(3));
+ assert_eq!(t1.next(), None);
+ assert_eq!(t2.next(), Some(1));
+ assert_eq!(t2.next(), Some(2));
+ assert_eq!(t1.next(), None);
+ assert_eq!(t2.next(), Some(3));
+ assert_eq!(t2.next(), None);
+ assert_eq!(t1.next(), None);
+ assert_eq!(t2.next(), None);
+
+ let (t1, t2) = xs.iter().cloned().tee();
+ it::assert_equal(t1, xs.iter().cloned());
+ it::assert_equal(t2, xs.iter().cloned());
+
+ let (t1, t2) = xs.iter().cloned().tee();
+ it::assert_equal(t1.zip(t2), xs.iter().cloned().zip(xs.iter().cloned()));
+}
+
+
+#[test]
+fn test_rciter() {
+ let xs = [0, 1, 1, 1, 2, 1, 3, 5, 6];
+
+ let mut r1 = rciter(xs.iter().cloned());
+ let mut r2 = r1.clone();
+ assert_eq!(r1.next(), Some(0));
+ assert_eq!(r2.next(), Some(1));
+ let mut z = r1.zip(r2);
+ assert_eq!(z.next(), Some((1, 1)));
+ assert_eq!(z.next(), Some((2, 1)));
+ assert_eq!(z.next(), Some((3, 5)));
+ assert_eq!(z.next(), None);
+
+ // test intoiterator
+ let r1 = rciter(0..5);
+ let mut z = izip!(&r1, r1);
+ assert_eq!(z.next(), Some((0, 1)));
+}
+
+#[allow(deprecated)]
+#[test]
+fn trait_pointers() {
+ struct ByRef<'r, I: ?Sized>(&'r mut I) ;
+
+ impl<'r, X, I: ?Sized> Iterator for ByRef<'r, I> where
+ I: 'r + Iterator<Item=X>
+ {
+ type Item = X;
+ fn next(&mut self) -> Option<Self::Item>
+ {
+ self.0.next()
+ }
+ }
+
+ let mut it = Box::new(0..10) as Box<dyn Iterator<Item=i32>>;
+ assert_eq!(it.next(), Some(0));
+
+ {
+ /* make sure foreach works on non-Sized */
+ let jt: &mut dyn Iterator<Item = i32> = &mut *it;
+ assert_eq!(jt.next(), Some(1));
+
+ {
+ let mut r = ByRef(jt);
+ assert_eq!(r.next(), Some(2));
+ }
+
+ assert_eq!(jt.find_position(|x| *x == 4), Some((1, 4)));
+ jt.foreach(|_| ());
+ }
+}
+
+#[test]
+fn merge_by() {
+ let odd : Vec<(u32, &str)> = vec![(1, "hello"), (3, "world"), (5, "!")];
+ let even = vec![(2, "foo"), (4, "bar"), (6, "baz")];
+ let expected = vec![(1, "hello"), (2, "foo"), (3, "world"), (4, "bar"), (5, "!"), (6, "baz")];
+ let results = odd.iter().merge_by(even.iter(), |a, b| a.0 <= b.0);
+ it::assert_equal(results, expected.iter());
+}
+
+#[test]
+fn merge_by_btree() {
+ use std::collections::BTreeMap;
+ let mut bt1 = BTreeMap::new();
+ bt1.insert("hello", 1);
+ bt1.insert("world", 3);
+ let mut bt2 = BTreeMap::new();
+ bt2.insert("foo", 2);
+ bt2.insert("bar", 4);
+ let results = bt1.into_iter().merge_by(bt2.into_iter(), |a, b| a.0 <= b.0 );
+ let expected = vec![("bar", 4), ("foo", 2), ("hello", 1), ("world", 3)];
+ it::assert_equal(results, expected.into_iter());
+}
+
+#[allow(deprecated)]
+#[test]
+fn kmerge() {
+ let its = (0..4).map(|s| (s..10).step(4));
+
+ it::assert_equal(its.kmerge(), 0..10);
+}
+
+#[allow(deprecated)]
+#[test]
+fn kmerge_2() {
+ let its = vec![3, 2, 1, 0].into_iter().map(|s| (s..10).step(4));
+
+ it::assert_equal(its.kmerge(), 0..10);
+}
+
+#[test]
+fn kmerge_empty() {
+ let its = (0..4).map(|_| 0..0);
+ assert_eq!(its.kmerge().next(), None);
+}
+
+#[test]
+fn kmerge_size_hint() {
+ let its = (0..5).map(|_| (0..10));
+ assert_eq!(its.kmerge().size_hint(), (50, Some(50)));
+}
+
+#[test]
+fn kmerge_empty_size_hint() {
+ let its = (0..5).map(|_| (0..0));
+ assert_eq!(its.kmerge().size_hint(), (0, Some(0)));
+}
+
+#[test]
+fn join() {
+ let many = [1, 2, 3];
+ let one = [1];
+ let none: Vec<i32> = vec![];
+
+ assert_eq!(many.iter().join(", "), "1, 2, 3");
+ assert_eq!( one.iter().join(", "), "1");
+ assert_eq!(none.iter().join(", "), "");
+}
+
+#[test]
+fn sorted_unstable_by() {
+ let sc = [3, 4, 1, 2].iter().cloned().sorted_by(|&a, &b| {
+ a.cmp(&b)
+ });
+ it::assert_equal(sc, vec![1, 2, 3, 4]);
+
+ let v = (0..5).sorted_unstable_by(|&a, &b| a.cmp(&b).reverse());
+ it::assert_equal(v, vec![4, 3, 2, 1, 0]);
+}
+
+#[test]
+fn sorted_unstable_by_key() {
+ let sc = [3, 4, 1, 2].iter().cloned().sorted_unstable_by_key(|&x| x);
+ it::assert_equal(sc, vec![1, 2, 3, 4]);
+
+ let v = (0..5).sorted_unstable_by_key(|&x| -x);
+ it::assert_equal(v, vec![4, 3, 2, 1, 0]);
+}
+
+#[test]
+fn sorted_by() {
+ let sc = [3, 4, 1, 2].iter().cloned().sorted_by(|&a, &b| {
+ a.cmp(&b)
+ });
+ it::assert_equal(sc, vec![1, 2, 3, 4]);
+
+ let v = (0..5).sorted_by(|&a, &b| a.cmp(&b).reverse());
+ it::assert_equal(v, vec![4, 3, 2, 1, 0]);
+}
+
+qc::quickcheck! {
+ fn k_smallest_range(n: u64, m: u16, k: u16) -> () {
+ // u16 is used to constrain k and m to 0..2¹⁶,
+ // otherwise the test could use too much memory.
+ let (k, m) = (k as u64, m as u64);
+
+ // Generate a random permutation of n..n+m
+ let i = {
+ let mut v: Vec<u64> = (n..n.saturating_add(m)).collect();
+ v.shuffle(&mut thread_rng());
+ v.into_iter()
+ };
+
+ // Check that taking the k smallest elements yields n..n+min(k, m)
+ it::assert_equal(
+ i.k_smallest(k as usize),
+ n..n.saturating_add(min(k, m))
+ );
+ }
+}
+
+#[derive(Clone, Debug)]
+struct RandIter<T: 'static + Clone + Send, R: 'static + Clone + Rng + SeedableRng + Send = StdRng> {
+ idx: usize,
+ len: usize,
+ rng: R,
+ _t: PhantomData<T>
+}
+
+impl<T: Clone + Send, R: Clone + Rng + SeedableRng + Send> Iterator for RandIter<T, R>
+where Standard: Distribution<T> {
+ type Item = T;
+ fn next(&mut self) -> Option<T> {
+ if self.idx == self.len {
+ None
+ } else {
+ self.idx += 1;
+ Some(self.rng.gen())
+ }
+ }
+}
+
+impl<T: Clone + Send, R: Clone + Rng + SeedableRng + Send> qc::Arbitrary for RandIter<T, R> {
+ fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
+ RandIter {
+ idx: 0,
+ len: g.size(),
+ rng: R::seed_from_u64(g.next_u64()),
+ _t : PhantomData{},
+ }
+ }
+}
+
+// Check that taking the k smallest is the same as
+// sorting then taking the k first elements
+fn k_smallest_sort<I>(i: I, k: u16)
+where
+ I: Iterator + Clone,
+ I::Item: Ord + Debug,
+{
+ let j = i.clone();
+ let k = k as usize;
+ it::assert_equal(
+ i.k_smallest(k),
+ j.sorted().take(k)
+ )
+}
+
+macro_rules! generic_test {
+ ($f:ident, $($t:ty),+) => {
+ $(paste::item! {
+ qc::quickcheck! {
+ fn [< $f _ $t >](i: RandIter<$t>, k: u16) -> () {
+ $f(i, k)
+ }
+ }
+ })+
+ };
+}
+
+generic_test!(k_smallest_sort, u8, u16, u32, u64, i8, i16, i32, i64);
+
+#[test]
+fn sorted_by_key() {
+ let sc = [3, 4, 1, 2].iter().cloned().sorted_by_key(|&x| x);
+ it::assert_equal(sc, vec![1, 2, 3, 4]);
+
+ let v = (0..5).sorted_by_key(|&x| -x);
+ it::assert_equal(v, vec![4, 3, 2, 1, 0]);
+}
+
+#[test]
+fn sorted_by_cached_key() {
+ // Track calls to key function
+ let mut ncalls = 0;
+
+ let sorted = [3, 4, 1, 2].iter().cloned().sorted_by_cached_key(|&x| {
+ ncalls += 1;
+ x.to_string()
+ });
+ it::assert_equal(sorted, vec![1, 2, 3, 4]);
+ // Check key function called once per element
+ assert_eq!(ncalls, 4);
+
+ let mut ncalls = 0;
+
+ let sorted = (0..5).sorted_by_cached_key(|&x| {
+ ncalls += 1;
+ -x
+ });
+ it::assert_equal(sorted, vec![4, 3, 2, 1, 0]);
+ // Check key function called once per element
+ assert_eq!(ncalls, 5);
+}
+
+#[test]
+fn test_multipeek() {
+ let nums = vec![1u8,2,3,4,5];
+
+ let mp = multipeek(nums.iter().copied());
+ assert_eq!(nums, mp.collect::<Vec<_>>());
+
+ let mut mp = multipeek(nums.iter().copied());
+ assert_eq!(mp.peek(), Some(&1));
+ assert_eq!(mp.next(), Some(1));
+ assert_eq!(mp.peek(), Some(&2));
+ assert_eq!(mp.peek(), Some(&3));
+ assert_eq!(mp.next(), Some(2));
+ assert_eq!(mp.peek(), Some(&3));
+ assert_eq!(mp.peek(), Some(&4));
+ assert_eq!(mp.peek(), Some(&5));
+ assert_eq!(mp.peek(), None);
+ assert_eq!(mp.next(), Some(3));
+ assert_eq!(mp.next(), Some(4));
+ assert_eq!(mp.peek(), Some(&5));
+ assert_eq!(mp.peek(), None);
+ assert_eq!(mp.next(), Some(5));
+ assert_eq!(mp.next(), None);
+ assert_eq!(mp.peek(), None);
+}
+
+#[test]
+fn test_multipeek_reset() {
+ let data = [1, 2, 3, 4];
+
+ let mut mp = multipeek(cloned(&data));
+ assert_eq!(mp.peek(), Some(&1));
+ assert_eq!(mp.next(), Some(1));
+ assert_eq!(mp.peek(), Some(&2));
+ assert_eq!(mp.peek(), Some(&3));
+ mp.reset_peek();
+ assert_eq!(mp.peek(), Some(&2));
+ assert_eq!(mp.next(), Some(2));
+}
+
+#[test]
+fn test_multipeek_peeking_next() {
+ use crate::it::PeekingNext;
+ let nums = vec![1u8,2,3,4,5,6,7];
+
+ let mut mp = multipeek(nums.iter().copied());
+ assert_eq!(mp.peeking_next(|&x| x != 0), Some(1));
+ assert_eq!(mp.next(), Some(2));
+ assert_eq!(mp.peek(), Some(&3));
+ assert_eq!(mp.peek(), Some(&4));
+ assert_eq!(mp.peeking_next(|&x| x == 3), Some(3));
+ assert_eq!(mp.peek(), Some(&4));
+ assert_eq!(mp.peeking_next(|&x| x != 4), None);
+ assert_eq!(mp.peeking_next(|&x| x == 4), Some(4));
+ assert_eq!(mp.peek(), Some(&5));
+ assert_eq!(mp.peek(), Some(&6));
+ assert_eq!(mp.peeking_next(|&x| x != 5), None);
+ assert_eq!(mp.peek(), Some(&7));
+ assert_eq!(mp.peeking_next(|&x| x == 5), Some(5));
+ assert_eq!(mp.peeking_next(|&x| x == 6), Some(6));
+ assert_eq!(mp.peek(), Some(&7));
+ assert_eq!(mp.peek(), None);
+ assert_eq!(mp.next(), Some(7));
+ assert_eq!(mp.peek(), None);
+}
+
+#[test]
+fn test_peek_nth() {
+ let nums = vec![1u8,2,3,4,5];
+
+ let iter = peek_nth(nums.iter().copied());
+ assert_eq!(nums, iter.collect::<Vec<_>>());
+
+ let mut iter = peek_nth(nums.iter().copied());
+
+ assert_eq!(iter.peek_nth(0), Some(&1));
+ assert_eq!(iter.peek_nth(0), Some(&1));
+ assert_eq!(iter.next(), Some(1));
+
+ assert_eq!(iter.peek_nth(0), Some(&2));
+ assert_eq!(iter.peek_nth(1), Some(&3));
+ assert_eq!(iter.next(), Some(2));
+
+ assert_eq!(iter.peek_nth(0), Some(&3));
+ assert_eq!(iter.peek_nth(1), Some(&4));
+ assert_eq!(iter.peek_nth(2), Some(&5));
+ assert_eq!(iter.peek_nth(3), None);
+
+ assert_eq!(iter.next(), Some(3));
+ assert_eq!(iter.next(), Some(4));
+
+ assert_eq!(iter.peek_nth(0), Some(&5));
+ assert_eq!(iter.peek_nth(1), None);
+ assert_eq!(iter.next(), Some(5));
+ assert_eq!(iter.next(), None);
+
+ assert_eq!(iter.peek_nth(0), None);
+ assert_eq!(iter.peek_nth(1), None);
+}
+
+#[test]
+fn test_peek_nth_peeking_next() {
+ use it::PeekingNext;
+ let nums = vec![1u8,2,3,4,5,6,7];
+ let mut iter = peek_nth(nums.iter().copied());
+
+ assert_eq!(iter.peeking_next(|&x| x != 0), Some(1));
+ assert_eq!(iter.next(), Some(2));
+
+ assert_eq!(iter.peek_nth(0), Some(&3));
+ assert_eq!(iter.peek_nth(1), Some(&4));
+ assert_eq!(iter.peeking_next(|&x| x == 3), Some(3));
+ assert_eq!(iter.peek(), Some(&4));
+
+ assert_eq!(iter.peeking_next(|&x| x != 4), None);
+ assert_eq!(iter.peeking_next(|&x| x == 4), Some(4));
+ assert_eq!(iter.peek_nth(0), Some(&5));
+ assert_eq!(iter.peek_nth(1), Some(&6));
+
+ assert_eq!(iter.peeking_next(|&x| x != 5), None);
+ assert_eq!(iter.peek(), Some(&5));
+
+ assert_eq!(iter.peeking_next(|&x| x == 5), Some(5));
+ assert_eq!(iter.peeking_next(|&x| x == 6), Some(6));
+ assert_eq!(iter.peek_nth(0), Some(&7));
+ assert_eq!(iter.peek_nth(1), None);
+ assert_eq!(iter.next(), Some(7));
+ assert_eq!(iter.peek(), None);
+}
+
+#[test]
+fn pad_using() {
+ it::assert_equal((0..0).pad_using(1, |_| 1), 1..2);
+
+ let v: Vec<usize> = vec![0, 1, 2];
+ let r = v.into_iter().pad_using(5, |n| n);
+ it::assert_equal(r, vec![0, 1, 2, 3, 4]);
+
+ let v: Vec<usize> = vec![0, 1, 2];
+ let r = v.into_iter().pad_using(1, |_| panic!());
+ it::assert_equal(r, vec![0, 1, 2]);
+}
+
+#[test]
+fn group_by() {
+ for (ch1, sub) in &"AABBCCC".chars().group_by(|&x| x) {
+ for ch2 in sub {
+ assert_eq!(ch1, ch2);
+ }
+ }
+
+ for (ch1, sub) in &"AAABBBCCCCDDDD".chars().group_by(|&x| x) {
+ for ch2 in sub {
+ assert_eq!(ch1, ch2);
+ if ch1 == 'C' {
+ break;
+ }
+ }
+ }
+
+ let toupper = |ch: &char| ch.to_uppercase().next().unwrap();
+
+ // try all possible orderings
+ for indices in permutohedron::Heap::new(&mut [0, 1, 2, 3]) {
+ let groups = "AaaBbbccCcDDDD".chars().group_by(&toupper);
+ let mut subs = groups.into_iter().collect_vec();
+
+ for &idx in &indices[..] {
+ let (key, text) = match idx {
+ 0 => ('A', "Aaa".chars()),
+ 1 => ('B', "Bbb".chars()),
+ 2 => ('C', "ccCc".chars()),
+ 3 => ('D', "DDDD".chars()),
+ _ => unreachable!(),
+ };
+ assert_eq!(key, subs[idx].0);
+ it::assert_equal(&mut subs[idx].1, text);
+ }
+ }
+
+ let groups = "AAABBBCCCCDDDD".chars().group_by(|&x| x);
+ let mut subs = groups.into_iter().map(|(_, g)| g).collect_vec();
+
+ let sd = subs.pop().unwrap();
+ let sc = subs.pop().unwrap();
+ let sb = subs.pop().unwrap();
+ let sa = subs.pop().unwrap();
+ for (a, b, c, d) in multizip((sa, sb, sc, sd)) {
+ assert_eq!(a, 'A');
+ assert_eq!(b, 'B');
+ assert_eq!(c, 'C');
+ assert_eq!(d, 'D');
+ }
+
+ // check that the key closure is called exactly n times
+ {
+ let mut ntimes = 0;
+ let text = "AABCCC";
+ for (_, sub) in &text.chars().group_by(|&x| { ntimes += 1; x}) {
+ for _ in sub {
+ }
+ }
+ assert_eq!(ntimes, text.len());
+ }
+
+ {
+ let mut ntimes = 0;
+ let text = "AABCCC";
+ for _ in &text.chars().group_by(|&x| { ntimes += 1; x}) {
+ }
+ assert_eq!(ntimes, text.len());
+ }
+
+ {
+ let text = "ABCCCDEEFGHIJJKK";
+ let gr = text.chars().group_by(|&x| x);
+ it::assert_equal(gr.into_iter().flat_map(|(_, sub)| sub), text.chars());
+ }
+}
+
+#[test]
+fn group_by_lazy_2() {
+ let data = vec![0, 1];
+ let groups = data.iter().group_by(|k| *k);
+ let gs = groups.into_iter().collect_vec();
+ it::assert_equal(data.iter(), gs.into_iter().flat_map(|(_k, g)| g));
+
+ let data = vec![0, 1, 1, 0, 0];
+ let groups = data.iter().group_by(|k| *k);
+ let mut gs = groups.into_iter().collect_vec();
+ gs[1..].reverse();
+ it::assert_equal(&[0, 0, 0, 1, 1], gs.into_iter().flat_map(|(_, g)| g));
+
+ let grouper = data.iter().group_by(|k| *k);
+ let mut groups = Vec::new();
+ for (k, group) in &grouper {
+ if *k == 1 {
+ groups.push(group);
+ }
+ }
+ it::assert_equal(&mut groups[0], &[1, 1]);
+
+ let data = vec![0, 0, 0, 1, 1, 0, 0, 2, 2, 3, 3];
+ let grouper = data.iter().group_by(|k| *k);
+ let mut groups = Vec::new();
+ for (i, (_, group)) in grouper.into_iter().enumerate() {
+ if i < 2 {
+ groups.push(group);
+ } else if i < 4 {
+ for _ in group {
+ }
+ } else {
+ groups.push(group);
+ }
+ }
+ it::assert_equal(&mut groups[0], &[0, 0, 0]);
+ it::assert_equal(&mut groups[1], &[1, 1]);
+ it::assert_equal(&mut groups[2], &[3, 3]);
+
+ // use groups as chunks
+ let data = vec![0, 0, 0, 1, 1, 0, 0, 2, 2, 3, 3];
+ let mut i = 0;
+ let grouper = data.iter().group_by(move |_| { let k = i / 3; i += 1; k });
+ for (i, group) in &grouper {
+ match i {
+ 0 => it::assert_equal(group, &[0, 0, 0]),
+ 1 => it::assert_equal(group, &[1, 1, 0]),
+ 2 => it::assert_equal(group, &[0, 2, 2]),
+ 3 => it::assert_equal(group, &[3, 3]),
+ _ => unreachable!(),
+ }
+ }
+}
+
+#[test]
+fn group_by_lazy_3() {
+ // test consuming each group on the lap after it was produced
+ let data = vec![0, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2];
+ let grouper = data.iter().group_by(|elt| *elt);
+ let mut last = None;
+ for (key, group) in &grouper {
+ if let Some(gr) = last.take() {
+ for elt in gr {
+ assert!(elt != key && i32::abs(elt - key) == 1);
+ }
+ }
+ last = Some(group);
+ }
+}
+
+#[test]
+fn chunks() {
+ let data = vec![0, 0, 0, 1, 1, 0, 0, 2, 2, 3, 3];
+ let grouper = data.iter().chunks(3);
+ for (i, chunk) in grouper.into_iter().enumerate() {
+ match i {
+ 0 => it::assert_equal(chunk, &[0, 0, 0]),
+ 1 => it::assert_equal(chunk, &[1, 1, 0]),
+ 2 => it::assert_equal(chunk, &[0, 2, 2]),
+ 3 => it::assert_equal(chunk, &[3, 3]),
+ _ => unreachable!(),
+ }
+ }
+}
+
+#[test]
+fn concat_empty() {
+ let data: Vec<Vec<()>> = Vec::new();
+ assert_eq!(data.into_iter().concat(), Vec::new())
+}
+
+#[test]
+fn concat_non_empty() {
+ let data = vec![vec![1,2,3], vec![4,5,6], vec![7,8,9]];
+ assert_eq!(data.into_iter().concat(), vec![1,2,3,4,5,6,7,8,9])
+}
+
+#[test]
+fn combinations() {
+ assert!((1..3).combinations(5).next().is_none());
+
+ let it = (1..3).combinations(2);
+ it::assert_equal(it, vec![
+ vec![1, 2],
+ ]);
+
+ let it = (1..5).combinations(2);
+ it::assert_equal(it, vec![
+ vec![1, 2],
+ vec![1, 3],
+ vec![1, 4],
+ vec![2, 3],
+ vec![2, 4],
+ vec![3, 4],
+ ]);
+
+ it::assert_equal((0..0).tuple_combinations::<(_, _)>(), <Vec<_>>::new());
+ it::assert_equal((0..1).tuple_combinations::<(_, _)>(), <Vec<_>>::new());
+ it::assert_equal((0..2).tuple_combinations::<(_, _)>(), vec![(0, 1)]);
+
+ it::assert_equal((0..0).combinations(2), <Vec<Vec<_>>>::new());
+ it::assert_equal((0..1).combinations(1), vec![vec![0]]);
+ it::assert_equal((0..2).combinations(1), vec![vec![0], vec![1]]);
+ it::assert_equal((0..2).combinations(2), vec![vec![0, 1]]);
+}
+
+#[test]
+fn combinations_of_too_short() {
+ for i in 1..10 {
+ assert!((0..0).combinations(i).next().is_none());
+ assert!((0..i - 1).combinations(i).next().is_none());
+ }
+}
+
+
+#[test]
+fn combinations_zero() {
+ it::assert_equal((1..3).combinations(0), vec![vec![]]);
+ it::assert_equal((0..0).combinations(0), vec![vec![]]);
+}
+
+#[test]
+fn permutations_zero() {
+ it::assert_equal((1..3).permutations(0), vec![vec![]]);
+ it::assert_equal((0..0).permutations(0), vec![vec![]]);
+}
+
+#[test]
+fn combinations_with_replacement() {
+ // Pool smaller than n
+ it::assert_equal((0..1).combinations_with_replacement(2), vec![vec![0, 0]]);
+ // Pool larger than n
+ it::assert_equal(
+ (0..3).combinations_with_replacement(2),
+ vec![
+ vec![0, 0],
+ vec![0, 1],
+ vec![0, 2],
+ vec![1, 1],
+ vec![1, 2],
+ vec![2, 2],
+ ],
+ );
+ // Zero size
+ it::assert_equal(
+ (0..3).combinations_with_replacement(0),
+ vec![vec![]],
+ );
+ // Zero size on empty pool
+ it::assert_equal(
+ (0..0).combinations_with_replacement(0),
+ vec![vec![]],
+ );
+ // Empty pool
+ it::assert_equal(
+ (0..0).combinations_with_replacement(2),
+ <Vec<Vec<_>>>::new(),
+ );
+}
+
+#[test]
+fn powerset() {
+ it::assert_equal((0..0).powerset(), vec![vec![]]);
+ it::assert_equal((0..1).powerset(), vec![vec![], vec![0]]);
+ it::assert_equal((0..2).powerset(), vec![vec![], vec![0], vec![1], vec![0, 1]]);
+ it::assert_equal((0..3).powerset(), vec![
+ vec![],
+ vec![0], vec![1], vec![2],
+ vec![0, 1], vec![0, 2], vec![1, 2],
+ vec![0, 1, 2]
+ ]);
+
+ assert_eq!((0..4).powerset().count(), 1 << 4);
+ assert_eq!((0..8).powerset().count(), 1 << 8);
+ assert_eq!((0..16).powerset().count(), 1 << 16);
+}
+
+#[test]
+fn diff_mismatch() {
+ let a = vec![1, 2, 3, 4];
+ let b = vec![1.0, 5.0, 3.0, 4.0];
+ let b_map = b.into_iter().map(|f| f as i32);
+ let diff = it::diff_with(a.iter(), b_map, |a, b| *a == b);
+
+ assert!(match diff {
+ Some(it::Diff::FirstMismatch(1, _, from_diff)) =>
+ from_diff.collect::<Vec<_>>() == vec![5, 3, 4],
+ _ => false,
+ });
+}
+
+#[test]
+fn diff_longer() {
+ let a = vec![1, 2, 3, 4];
+ let b = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0];
+ let b_map = b.into_iter().map(|f| f as i32);
+ let diff = it::diff_with(a.iter(), b_map, |a, b| *a == b);
+
+ assert!(match diff {
+ Some(it::Diff::Longer(_, remaining)) =>
+ remaining.collect::<Vec<_>>() == vec![5, 6],
+ _ => false,
+ });
+}
+
+#[test]
+fn diff_shorter() {
+ let a = vec![1, 2, 3, 4];
+ let b = vec![1.0, 2.0];
+ let b_map = b.into_iter().map(|f| f as i32);
+ let diff = it::diff_with(a.iter(), b_map, |a, b| *a == b);
+
+ assert!(match diff {
+ Some(it::Diff::Shorter(len, _)) => len == 2,
+ _ => false,
+ });
+}
+
+#[test]
+fn extrema_set() {
+ use std::cmp::Ordering;
+
+ // A peculiar type: Equality compares both tuple items, but ordering only the
+ // first item. Used to distinguish equal elements.
+ #[derive(Clone, Debug, PartialEq, Eq)]
+ struct Val(u32, u32);
+
+ impl PartialOrd<Val> for Val {
+ fn partial_cmp(&self, other: &Val) -> Option<Ordering> {
+ self.0.partial_cmp(&other.0)
+ }
+ }
+
+ impl Ord for Val {
+ fn cmp(&self, other: &Val) -> Ordering {
+ self.0.cmp(&other.0)
+ }
+ }
+
+ assert_eq!(None::<u32>.iter().min_set(), Vec::<&u32>::new());
+ assert_eq!(None::<u32>.iter().max_set(), Vec::<&u32>::new());
+
+ assert_eq!(Some(1u32).iter().min_set(), vec![&1]);
+ assert_eq!(Some(1u32).iter().max_set(), vec![&1]);
+
+ let data = vec![Val(0, 1), Val(2, 0), Val(0, 2), Val(1, 0), Val(2, 1)];
+
+ let min_set = data.iter().min_set();
+ assert_eq!(min_set, vec![&Val(0, 1), &Val(0, 2)]);
+
+ let min_set_by_key = data.iter().min_set_by_key(|v| v.1);
+ assert_eq!(min_set_by_key, vec![&Val(2, 0), &Val(1, 0)]);
+
+ let min_set_by = data.iter().min_set_by(|x, y| x.1.cmp(&y.1));
+ assert_eq!(min_set_by, vec![&Val(2, 0), &Val(1, 0)]);
+
+ let max_set = data.iter().max_set();
+ assert_eq!(max_set, vec![&Val(2, 0), &Val(2, 1)]);
+
+ let max_set_by_key = data.iter().max_set_by_key(|v| v.1);
+ assert_eq!(max_set_by_key, vec![&Val(0, 2)]);
+
+ let max_set_by = data.iter().max_set_by(|x, y| x.1.cmp(&y.1));
+ assert_eq!(max_set_by, vec![&Val(0, 2)]);
+}
+
+#[test]
+fn minmax() {
+ use std::cmp::Ordering;
+ use crate::it::MinMaxResult;
+
+ // A peculiar type: Equality compares both tuple items, but ordering only the
+ // first item. This is so we can check the stability property easily.
+ #[derive(Clone, Debug, PartialEq, Eq)]
+ struct Val(u32, u32);
+
+ impl PartialOrd<Val> for Val {
+ fn partial_cmp(&self, other: &Val) -> Option<Ordering> {
+ self.0.partial_cmp(&other.0)
+ }
+ }
+
+ impl Ord for Val {
+ fn cmp(&self, other: &Val) -> Ordering {
+ self.0.cmp(&other.0)
+ }
+ }
+
+ assert_eq!(None::<Option<u32>>.iter().minmax(), MinMaxResult::NoElements);
+
+ assert_eq!(Some(1u32).iter().minmax(), MinMaxResult::OneElement(&1));
+
+ let data = vec![Val(0, 1), Val(2, 0), Val(0, 2), Val(1, 0), Val(2, 1)];
+
+ let minmax = data.iter().minmax();
+ assert_eq!(minmax, MinMaxResult::MinMax(&Val(0, 1), &Val(2, 1)));
+
+ let (min, max) = data.iter().minmax_by_key(|v| v.1).into_option().unwrap();
+ assert_eq!(min, &Val(2, 0));
+ assert_eq!(max, &Val(0, 2));
+
+ let (min, max) = data.iter().minmax_by(|x, y| x.1.cmp(&y.1)).into_option().unwrap();
+ assert_eq!(min, &Val(2, 0));
+ assert_eq!(max, &Val(0, 2));
+}
+
+#[test]
+fn format() {
+ let data = [0, 1, 2, 3];
+ let ans1 = "0, 1, 2, 3";
+ let ans2 = "0--1--2--3";
+
+ let t1 = format!("{}", data.iter().format(", "));
+ assert_eq!(t1, ans1);
+ let t2 = format!("{:?}", data.iter().format("--"));
+ assert_eq!(t2, ans2);
+
+ let dataf = [1.1, 5.71828, -22.];
+ let t3 = format!("{:.2e}", dataf.iter().format(", "));
+ assert_eq!(t3, "1.10e0, 5.72e0, -2.20e1");
+}
+
+#[test]
+fn while_some() {
+ let ns = (1..10).map(|x| if x % 5 != 0 { Some(x) } else { None })
+ .while_some();
+ it::assert_equal(ns, vec![1, 2, 3, 4]);
+}
+
+#[allow(deprecated)]
+#[test]
+fn fold_while() {
+ let mut iterations = 0;
+ let vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ let sum = vec.into_iter().fold_while(0, |acc, item| {
+ iterations += 1;
+ let new_sum = acc + item;
+ if new_sum <= 20 {
+ FoldWhile::Continue(new_sum)
+ } else {
+ FoldWhile::Done(acc)
+ }
+ }).into_inner();
+ assert_eq!(iterations, 6);
+ assert_eq!(sum, 15);
+}
+
+#[test]
+fn tree_fold1() {
+ let x = [
+ "",
+ "0",
+ "0 1 x",
+ "0 1 x 2 x",
+ "0 1 x 2 3 x x",
+ "0 1 x 2 3 x x 4 x",
+ "0 1 x 2 3 x x 4 5 x x",
+ "0 1 x 2 3 x x 4 5 x 6 x x",
+ "0 1 x 2 3 x x 4 5 x 6 7 x x x",
+ "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 x",
+ "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x x",
+ "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 x x",
+ "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x x",
+ "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 x x",
+ "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 13 x x x",
+ "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 13 x 14 x x x",
+ "0 1 x 2 3 x x 4 5 x 6 7 x x x 8 9 x 10 11 x x 12 13 x 14 15 x x x x",
+ ];
+ for (i, &s) in x.iter().enumerate() {
+ let expected = if s.is_empty() { None } else { Some(s.to_string()) };
+ let num_strings = (0..i).map(|x| x.to_string());
+ let actual = num_strings.tree_fold1(|a, b| format!("{} {} x", a, b));
+ assert_eq!(actual, expected);
+ }
+}
+
+#[test]
+fn exactly_one_question_mark_syntax_works() {
+ exactly_one_question_mark_return().unwrap_err();
+}
+
+fn exactly_one_question_mark_return() -> Result<(), ExactlyOneError<std::slice::Iter<'static, ()>>> {
+ [].iter().exactly_one()?;
+ Ok(())
+}
+
+#[test]
+fn multiunzip() {
+ let (a, b, c): (Vec<_>, Vec<_>, Vec<_>) = [(0, 1, 2), (3, 4, 5), (6, 7, 8)].iter().cloned().multiunzip();
+ assert_eq!((a, b, c), (vec![0, 3, 6], vec![1, 4, 7], vec![2, 5, 8]));
+ let (): () = [(), (), ()].iter().cloned().multiunzip();
+ let t: (Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>) = [(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)].iter().cloned().multiunzip();
+ assert_eq!(t, (vec![0], vec![1], vec![2], vec![3], vec![4], vec![5], vec![6], vec![7], vec![8], vec![9], vec![10], vec![11]));
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/tests/tuples.rs b/rust/hw/char/pl011/vendor/itertools/tests/tuples.rs
new file mode 100644
index 0000000000..9fc8b3cc78
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/tests/tuples.rs
@@ -0,0 +1,86 @@
+use itertools::Itertools;
+
+#[test]
+fn tuples() {
+ let v = [1, 2, 3, 4, 5];
+ let mut iter = v.iter().cloned().tuples();
+ assert_eq!(Some((1,)), iter.next());
+ assert_eq!(Some((2,)), iter.next());
+ assert_eq!(Some((3,)), iter.next());
+ assert_eq!(Some((4,)), iter.next());
+ assert_eq!(Some((5,)), iter.next());
+ assert_eq!(None, iter.next());
+ assert_eq!(None, iter.into_buffer().next());
+
+ let mut iter = v.iter().cloned().tuples();
+ assert_eq!(Some((1, 2)), iter.next());
+ assert_eq!(Some((3, 4)), iter.next());
+ assert_eq!(None, iter.next());
+ itertools::assert_equal(vec![5], iter.into_buffer());
+
+ let mut iter = v.iter().cloned().tuples();
+ assert_eq!(Some((1, 2, 3)), iter.next());
+ assert_eq!(None, iter.next());
+ itertools::assert_equal(vec![4, 5], iter.into_buffer());
+
+ let mut iter = v.iter().cloned().tuples();
+ assert_eq!(Some((1, 2, 3, 4)), iter.next());
+ assert_eq!(None, iter.next());
+ itertools::assert_equal(vec![5], iter.into_buffer());
+}
+
+#[test]
+fn tuple_windows() {
+ let v = [1, 2, 3, 4, 5];
+
+ let mut iter = v.iter().cloned().tuple_windows();
+ assert_eq!(Some((1,)), iter.next());
+ assert_eq!(Some((2,)), iter.next());
+ assert_eq!(Some((3,)), iter.next());
+
+ let mut iter = v.iter().cloned().tuple_windows();
+ assert_eq!(Some((1, 2)), iter.next());
+ assert_eq!(Some((2, 3)), iter.next());
+ assert_eq!(Some((3, 4)), iter.next());
+ assert_eq!(Some((4, 5)), iter.next());
+ assert_eq!(None, iter.next());
+
+ let mut iter = v.iter().cloned().tuple_windows();
+ assert_eq!(Some((1, 2, 3)), iter.next());
+ assert_eq!(Some((2, 3, 4)), iter.next());
+ assert_eq!(Some((3, 4, 5)), iter.next());
+ assert_eq!(None, iter.next());
+
+ let mut iter = v.iter().cloned().tuple_windows();
+ assert_eq!(Some((1, 2, 3, 4)), iter.next());
+ assert_eq!(Some((2, 3, 4, 5)), iter.next());
+ assert_eq!(None, iter.next());
+
+ let v = [1, 2, 3];
+ let mut iter = v.iter().cloned().tuple_windows::<(_, _, _, _)>();
+ assert_eq!(None, iter.next());
+}
+
+#[test]
+fn next_tuple() {
+ let v = [1, 2, 3, 4, 5];
+ let mut iter = v.iter();
+ assert_eq!(iter.next_tuple().map(|(&x, &y)| (x, y)), Some((1, 2)));
+ assert_eq!(iter.next_tuple().map(|(&x, &y)| (x, y)), Some((3, 4)));
+ assert_eq!(iter.next_tuple::<(_, _)>(), None);
+}
+
+#[test]
+fn collect_tuple() {
+ let v = [1, 2];
+ let iter = v.iter().cloned();
+ assert_eq!(iter.collect_tuple(), Some((1, 2)));
+
+ let v = [1];
+ let iter = v.iter().cloned();
+ assert_eq!(iter.collect_tuple::<(_, _)>(), None);
+
+ let v = [1, 2, 3];
+ let iter = v.iter().cloned();
+ assert_eq!(iter.collect_tuple::<(_, _)>(), None);
+}
diff --git a/rust/hw/char/pl011/vendor/itertools/tests/zip.rs b/rust/hw/char/pl011/vendor/itertools/tests/zip.rs
new file mode 100644
index 0000000000..75157d34f3
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/itertools/tests/zip.rs
@@ -0,0 +1,77 @@
+use itertools::Itertools;
+use itertools::EitherOrBoth::{Both, Left, Right};
+use itertools::free::zip_eq;
+use itertools::multizip;
+
+#[test]
+fn zip_longest_fused() {
+ let a = [Some(1), None, Some(3), Some(4)];
+ let b = [1, 2, 3];
+
+ let unfused = a.iter().batching(|it| *it.next().unwrap())
+ .zip_longest(b.iter().cloned());
+ itertools::assert_equal(unfused,
+ vec![Both(1, 1), Right(2), Right(3)]);
+}
+
+#[test]
+fn test_zip_longest_size_hint() {
+ let c = (1..10).cycle();
+ let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ let v2 = &[10, 11, 12];
+
+ assert_eq!(c.zip_longest(v.iter()).size_hint(), (std::usize::MAX, None));
+
+ assert_eq!(v.iter().zip_longest(v2.iter()).size_hint(), (10, Some(10)));
+}
+
+#[test]
+fn test_double_ended_zip_longest() {
+ let xs = [1, 2, 3, 4, 5, 6];
+ let ys = [1, 2, 3, 7];
+ let a = xs.iter().copied();
+ let b = ys.iter().copied();
+ let mut it = a.zip_longest(b);
+ assert_eq!(it.next(), Some(Both(1, 1)));
+ assert_eq!(it.next(), Some(Both(2, 2)));
+ assert_eq!(it.next_back(), Some(Left(6)));
+ assert_eq!(it.next_back(), Some(Left(5)));
+ assert_eq!(it.next_back(), Some(Both(4, 7)));
+ assert_eq!(it.next(), Some(Both(3, 3)));
+ assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_double_ended_zip() {
+ let xs = [1, 2, 3, 4, 5, 6];
+ let ys = [1, 2, 3, 7];
+ let a = xs.iter().copied();
+ let b = ys.iter().copied();
+ let mut it = multizip((a, b));
+ assert_eq!(it.next_back(), Some((4, 7)));
+ assert_eq!(it.next_back(), Some((3, 3)));
+ assert_eq!(it.next_back(), Some((2, 2)));
+ assert_eq!(it.next_back(), Some((1, 1)));
+ assert_eq!(it.next_back(), None);
+}
+
+
+#[should_panic]
+#[test]
+fn zip_eq_panic1()
+{
+ let a = [1, 2];
+ let b = [1, 2, 3];
+
+ zip_eq(&a, &b).count();
+}
+
+#[should_panic]
+#[test]
+fn zip_eq_panic2()
+{
+ let a: [i32; 0] = [];
+ let b = [1, 2, 3];
+
+ zip_eq(&a, &b).count();
+}
diff --git a/rust/hw/char/pl011/vendor/meson.build b/rust/hw/char/pl011/vendor/meson.build
new file mode 100644
index 0000000000..4611d2f11d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/meson.build
@@ -0,0 +1,18 @@
+subdir('arbitrary-int')
+subdir('unicode-ident')
+# subdir('version_check')
+subdir('either')
+
+subdir('itertools')
+subdir('proc-macro2')
+
+subdir('quote')
+
+subdir('proc-macro-error-attr')
+subdir('syn')
+
+subdir('proc-macro-error')
+
+subdir('bilge-impl')
+
+subdir('bilge')
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error-attr/.cargo-checksum.json b/rust/hw/char/pl011/vendor/proc-macro-error-attr/.cargo-checksum.json
new file mode 100644
index 0000000000..c30b5418a8
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error-attr/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"fbd3ce928441a0b43859bbbe36549f05e7a1ebfee62e5982710671a8f41de527","LICENSE-APACHE":"6fd0f3522047150ca7c1939f02bc4a15662a4741a89bc03ae784eefa18caa299","LICENSE-MIT":"544b3aed1fd723d0cadea567affdcfe0431e43e18d997a718f9d67256b814fde","build.rs":"37b0aca3c4a14dfc050c2df38ae633311d7a1532cdbb8eb57182802c4a1983eb","src/lib.rs":"9e3d13c266376b688642572bb4091e094ff5277fce4bee72bcc3c5f982dd831c","src/parse.rs":"2d8f220f91235be8ed0ddcab55ec3699b9d3b28d538ed24197797cc20194c473","src/settings.rs":"be9382479d7a857b55e5a0b1014f72150c9ee7f2bbb5a5bdeabc0f8de2d95c26"},"package":"a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error-attr/Cargo.toml b/rust/hw/char/pl011/vendor/proc-macro-error-attr/Cargo.toml
new file mode 100644
index 0000000000..a2c766de9b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error-attr/Cargo.toml
@@ -0,0 +1,33 @@
+# 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 believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "proc-macro-error-attr"
+version = "1.0.4"
+authors = ["CreepySkeleton <creepy-skeleton@yandex.ru>"]
+build = "build.rs"
+description = "Attribute macro for proc-macro-error crate"
+license = "MIT OR Apache-2.0"
+repository = "https://gitlab.com/CreepySkeleton/proc-macro-error"
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+proc-macro = true
+[dependencies.proc-macro2]
+version = "1"
+
+[dependencies.quote]
+version = "1"
+[build-dependencies.version_check]
+version = "0.9"
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-APACHE b/rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-APACHE
new file mode 100644
index 0000000000..658240a840
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ 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
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright 2019-2020 CreepySkeleton <creepy-skeleton@yandex.ru>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-MIT b/rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-MIT
new file mode 100644
index 0000000000..fc73e591d7
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-MIT
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019-2020 CreepySkeleton
+
+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/rust/hw/char/pl011/vendor/proc-macro-error-attr/build.rs b/rust/hw/char/pl011/vendor/proc-macro-error-attr/build.rs
new file mode 100644
index 0000000000..f2ac6a70ee
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error-attr/build.rs
@@ -0,0 +1,5 @@
+fn main() {
+ if version_check::is_max_version("1.36.0").unwrap_or(false) {
+ println!("cargo:rustc-cfg=always_assert_unwind");
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error-attr/meson.build b/rust/hw/char/pl011/vendor/proc-macro-error-attr/meson.build
new file mode 100644
index 0000000000..63cd12ccf2
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error-attr/meson.build
@@ -0,0 +1,20 @@
+rust = import('rust')
+
+_proc_macro_error_attr_rs = rust.proc_macro(
+ 'proc_macro_error_attr',
+ files('src/lib.rs'),
+ rust_args: rust_args + [
+ '--edition', '2018',
+ '--cfg', 'use_fallback',
+ '--cfg', 'feature="syn-error"',
+ '--cfg', 'feature="proc-macro"'
+ ],
+ dependencies: [
+ dep_proc_macro2,
+ dep_quote,
+ ],
+)
+
+dep_proc_macro_error_attr = declare_dependency(
+ link_with: _proc_macro_error_attr_rs,
+)
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error-attr/src/lib.rs b/rust/hw/char/pl011/vendor/proc-macro-error-attr/src/lib.rs
new file mode 100644
index 0000000000..ac0ac21a26
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error-attr/src/lib.rs
@@ -0,0 +1,121 @@
+//! This is `#[proc_macro_error]` attribute to be used with
+//! [`proc-macro-error`](https://docs.rs/proc-macro-error/). There you go.
+
+extern crate proc_macro;
+
+use crate::parse::parse_input;
+use crate::parse::Attribute;
+use proc_macro::TokenStream;
+use proc_macro2::{Literal, Span, TokenStream as TokenStream2, TokenTree};
+use quote::{quote, quote_spanned};
+
+use crate::settings::{Setting::*, *};
+
+mod parse;
+mod settings;
+
+type Result<T> = std::result::Result<T, Error>;
+
+struct Error {
+ span: Span,
+ message: String,
+}
+
+impl Error {
+ fn new(span: Span, message: String) -> Self {
+ Error { span, message }
+ }
+
+ fn into_compile_error(self) -> TokenStream2 {
+ let mut message = Literal::string(&self.message);
+ message.set_span(self.span);
+ quote_spanned!(self.span=> compile_error!{#message})
+ }
+}
+
+#[proc_macro_attribute]
+pub fn proc_macro_error(attr: TokenStream, input: TokenStream) -> TokenStream {
+ match impl_proc_macro_error(attr.into(), input.clone().into()) {
+ Ok(ts) => ts,
+ Err(e) => {
+ let error = e.into_compile_error();
+ let input = TokenStream2::from(input);
+
+ quote!(#input #error).into()
+ }
+ }
+}
+
+fn impl_proc_macro_error(attr: TokenStream2, input: TokenStream2) -> Result<TokenStream> {
+ let (attrs, signature, body) = parse_input(input)?;
+ let mut settings = parse_settings(attr)?;
+
+ let is_proc_macro = is_proc_macro(&attrs);
+ if is_proc_macro {
+ settings.set(AssertUnwindSafe);
+ }
+
+ if detect_proc_macro_hack(&attrs) {
+ settings.set(ProcMacroHack);
+ }
+
+ if settings.is_set(ProcMacroHack) {
+ settings.set(AllowNotMacro);
+ }
+
+ if !(settings.is_set(AllowNotMacro) || is_proc_macro) {
+ return Err(Error::new(
+ Span::call_site(),
+ "#[proc_macro_error] attribute can be used only with procedural macros\n\n \
+ = hint: if you are really sure that #[proc_macro_error] should be applied \
+ to this exact function, use #[proc_macro_error(allow_not_macro)]\n"
+ .into(),
+ ));
+ }
+
+ let body = gen_body(body, settings);
+
+ let res = quote! {
+ #(#attrs)*
+ #(#signature)*
+ { #body }
+ };
+ Ok(res.into())
+}
+
+#[cfg(not(always_assert_unwind))]
+fn gen_body(block: TokenTree, settings: Settings) -> proc_macro2::TokenStream {
+ let is_proc_macro_hack = settings.is_set(ProcMacroHack);
+ let closure = if settings.is_set(AssertUnwindSafe) {
+ quote!(::std::panic::AssertUnwindSafe(|| #block ))
+ } else {
+ quote!(|| #block)
+ };
+
+ quote!( ::proc_macro_error::entry_point(#closure, #is_proc_macro_hack) )
+}
+
+// FIXME:
+// proc_macro::TokenStream does not implement UnwindSafe until 1.37.0.
+// Considering this is the closure's return type the unwind safety check would fail
+// for virtually every closure possible, the check is meaningless.
+#[cfg(always_assert_unwind)]
+fn gen_body(block: TokenTree, settings: Settings) -> proc_macro2::TokenStream {
+ let is_proc_macro_hack = settings.is_set(ProcMacroHack);
+ let closure = quote!(::std::panic::AssertUnwindSafe(|| #block ));
+ quote!( ::proc_macro_error::entry_point(#closure, #is_proc_macro_hack) )
+}
+
+fn detect_proc_macro_hack(attrs: &[Attribute]) -> bool {
+ attrs
+ .iter()
+ .any(|attr| attr.path_is_ident("proc_macro_hack"))
+}
+
+fn is_proc_macro(attrs: &[Attribute]) -> bool {
+ attrs.iter().any(|attr| {
+ attr.path_is_ident("proc_macro")
+ || attr.path_is_ident("proc_macro_derive")
+ || attr.path_is_ident("proc_macro_attribute")
+ })
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error-attr/src/parse.rs b/rust/hw/char/pl011/vendor/proc-macro-error-attr/src/parse.rs
new file mode 100644
index 0000000000..6f4663f80e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error-attr/src/parse.rs
@@ -0,0 +1,89 @@
+use crate::{Error, Result};
+use proc_macro2::{Delimiter, Ident, Span, TokenStream, TokenTree};
+use quote::ToTokens;
+use std::iter::Peekable;
+
+pub(crate) fn parse_input(
+ input: TokenStream,
+) -> Result<(Vec<Attribute>, Vec<TokenTree>, TokenTree)> {
+ let mut input = input.into_iter().peekable();
+ let mut attrs = Vec::new();
+
+ while let Some(attr) = parse_next_attr(&mut input)? {
+ attrs.push(attr);
+ }
+
+ let sig = parse_signature(&mut input);
+ let body = input.next().ok_or_else(|| {
+ Error::new(
+ Span::call_site(),
+ "`#[proc_macro_error]` can be applied only to functions".to_string(),
+ )
+ })?;
+
+ Ok((attrs, sig, body))
+}
+
+fn parse_next_attr(
+ input: &mut Peekable<impl Iterator<Item = TokenTree>>,
+) -> Result<Option<Attribute>> {
+ let shebang = match input.peek() {
+ Some(TokenTree::Punct(ref punct)) if punct.as_char() == '#' => input.next().unwrap(),
+ _ => return Ok(None),
+ };
+
+ let group = match input.peek() {
+ Some(TokenTree::Group(ref group)) if group.delimiter() == Delimiter::Bracket => {
+ let res = group.clone();
+ input.next();
+ res
+ }
+ other => {
+ let span = other.map_or(Span::call_site(), |tt| tt.span());
+ return Err(Error::new(span, "expected `[`".to_string()));
+ }
+ };
+
+ let path = match group.stream().into_iter().next() {
+ Some(TokenTree::Ident(ident)) => Some(ident),
+ _ => None,
+ };
+
+ Ok(Some(Attribute {
+ shebang,
+ group: TokenTree::Group(group),
+ path,
+ }))
+}
+
+fn parse_signature(input: &mut Peekable<impl Iterator<Item = TokenTree>>) -> Vec<TokenTree> {
+ let mut sig = Vec::new();
+ loop {
+ match input.peek() {
+ Some(TokenTree::Group(ref group)) if group.delimiter() == Delimiter::Brace => {
+ return sig;
+ }
+ None => return sig,
+ _ => sig.push(input.next().unwrap()),
+ }
+ }
+}
+
+pub(crate) struct Attribute {
+ pub(crate) shebang: TokenTree,
+ pub(crate) group: TokenTree,
+ pub(crate) path: Option<Ident>,
+}
+
+impl Attribute {
+ pub(crate) fn path_is_ident(&self, ident: &str) -> bool {
+ self.path.as_ref().map_or(false, |p| *p == ident)
+ }
+}
+
+impl ToTokens for Attribute {
+ fn to_tokens(&self, ts: &mut TokenStream) {
+ self.shebang.to_tokens(ts);
+ self.group.to_tokens(ts);
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error-attr/src/settings.rs b/rust/hw/char/pl011/vendor/proc-macro-error-attr/src/settings.rs
new file mode 100644
index 0000000000..0b7ec766f6
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error-attr/src/settings.rs
@@ -0,0 +1,72 @@
+use crate::{Error, Result};
+use proc_macro2::{Ident, Span, TokenStream, TokenTree};
+
+macro_rules! decl_settings {
+ ($($val:expr => $variant:ident),+ $(,)*) => {
+ #[derive(PartialEq)]
+ pub(crate) enum Setting {
+ $($variant),*
+ }
+
+ fn ident_to_setting(ident: Ident) -> Result<Setting> {
+ match &*ident.to_string() {
+ $($val => Ok(Setting::$variant),)*
+ _ => {
+ let possible_vals = [$($val),*]
+ .iter()
+ .map(|v| format!("`{}`", v))
+ .collect::<Vec<_>>()
+ .join(", ");
+
+ Err(Error::new(
+ ident.span(),
+ format!("unknown setting `{}`, expected one of {}", ident, possible_vals)))
+ }
+ }
+ }
+ };
+}
+
+decl_settings! {
+ "assert_unwind_safe" => AssertUnwindSafe,
+ "allow_not_macro" => AllowNotMacro,
+ "proc_macro_hack" => ProcMacroHack,
+}
+
+pub(crate) fn parse_settings(input: TokenStream) -> Result<Settings> {
+ let mut input = input.into_iter();
+ let mut res = Settings(Vec::new());
+ loop {
+ match input.next() {
+ Some(TokenTree::Ident(ident)) => {
+ res.0.push(ident_to_setting(ident)?);
+ }
+ None => return Ok(res),
+ other => {
+ let span = other.map_or(Span::call_site(), |tt| tt.span());
+ return Err(Error::new(span, "expected identifier".to_string()));
+ }
+ }
+
+ match input.next() {
+ Some(TokenTree::Punct(ref punct)) if punct.as_char() == ',' => {}
+ None => return Ok(res),
+ other => {
+ let span = other.map_or(Span::call_site(), |tt| tt.span());
+ return Err(Error::new(span, "expected `,`".to_string()));
+ }
+ }
+ }
+}
+
+pub(crate) struct Settings(Vec<Setting>);
+
+impl Settings {
+ pub(crate) fn is_set(&self, setting: Setting) -> bool {
+ self.0.iter().any(|s| *s == setting)
+ }
+
+ pub(crate) fn set(&mut self, setting: Setting) {
+ self.0.push(setting)
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/.cargo-checksum.json b/rust/hw/char/pl011/vendor/proc-macro-error/.cargo-checksum.json
new file mode 100644
index 0000000000..79bcfa696f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"b84c4baa5fb093c6aaca44b98f9f28ef54d399ef6dd43c91f1dca618ab366b45","Cargo.toml":"50db093e1a4617606939dfb1f098cb59babbea0d7b390e973a3ed6bb1406170d","LICENSE-APACHE":"4665f973ccb9393807a7fb1264add6b3513d19abc6b357e4cb52c6fe59cc6a3b","LICENSE-MIT":"544b3aed1fd723d0cadea567affdcfe0431e43e18d997a718f9d67256b814fde","README.md":"72d59787d0a1f7bf161e292d0bc1bc25fdfb08cd6ad379a34cc3ed1b388d11fa","build.rs":"6238a0ad4f1146fbf55112419609e6449986154cf7ded1b5fdc978b06f4413b3","src/diagnostic.rs":"cb8724bb0bf9d2eee2f7119d0960fd5349edaa80e147abdef060ebf4572eca01","src/dummy.rs":"b44728091ddcdf9786523c01178efcedd83462bfe8bac6b97b1c2ffb19c96d09","src/imp/delegate.rs":"81da3a602a883240161dd98deb52b3b4ae29e626bfd2e1e07ef5e38d1be00679","src/imp/fallback.rs":"c3d333aba1122ac7e26f038f69750aa02e6a1222433a7cffd1c2f961befedd93","src/lib.rs":"e563d5dceaeb81551a5cb2610c1a3ad1a46200a6cbf8c3c3b394d8ac307b8cfa","src/macros.rs":"3be6feccd343cd9dc4bf03780f3107909bf70e02c6c7c72912e4b160dc6a68fc","src/sealed.rs":"dcf569c4c7ce1d372ff51b0fa73fa67f995bdca8e520cb225cde789c71276439","tests/macro-errors.rs":"7f793921dfbec692bfb2bbb067faf0480c0e7eeec83982b5e9fcddd817817616","tests/ok.rs":"a8c1925ac8647d185c7490ed1e33e3ce3203f5945bd3db4dcaf50ea55078df29","tests/runtime-errors.rs":"e53aa7d8e6c0e5128a90e856105eb05e4e7e72ea6db1bd580f3fe439bff62f24","tests/ui/abort.rs":"e209c8dd9dde6bde7440f8795624ad84b0f8486f563c8fe838238818f459bb67","tests/ui/abort.stderr":"dd0605e79be0309f92b251d055f087b0375c48ec60da978df354b48e8563fa10","tests/ui/append_dummy.rs":"ecaf939c8aabd94eef2dd1c10e9515489ba78e4db5b25195e19833b020d2483c","tests/ui/append_dummy.stderr":"ef03b01fc823aba8cfb9eb6d116640ca953fec569e61ed6ed6b7b7fa3bbad686","tests/ui/children_messages.rs":"32299679804133cb5295ed7a9341bf1ab86a4f1277679ee9738a83115c6b1d2b","tests/ui/children_messages.stderr":"dadeb86e1c7094d5fb38664b1766212b3d083fbe04962c137f8281fb3f5d162e","tests/ui/dummy.rs":"ba51c9158cef88ff2ddf0185be26fcd35a641d73c7124fab9ace0bbd546de847","tests/ui/dummy.stderr":"0635fd563d26691d07a2a875111f0b5e155caa45c37ad9cbaefe5fe617eac703","tests/ui/emit.rs":"82aaf06bcee56b7e139bbcba3a92c29448af14974d6806a28c9961aa764026e5","tests/ui/emit.stderr":"d3daa6d304453d436317495b7fc1d9d36bbebb7705bef75a5260d6d8fcfad5b1","tests/ui/explicit_span_range.rs":"3c37d5fc75b2bd460a091acd97a19acc80a40ba8d1d4ac7f36cd2f0e171bf5e7","tests/ui/explicit_span_range.stderr":"d7562847c326badbce2df8546e6f625eef0725b1dd2c786a037cc46357e4d2e8","tests/ui/misuse.rs":"0d66c61ab5c9723cf2f85cd12216751ab09722e9386cc27928034ee17f1c34e3","tests/ui/misuse.stderr":"52568a2208423e8e4050774559f269e79181a350f0805a34880bfa208e08c6bb","tests/ui/multiple_tokens.rs":"74997da1fdd3bce88a04ab42866c651723861fba4f59e826ee602d905398dcca","tests/ui/multiple_tokens.stderr":"e347ef1c18949711ce41957848e255095132f855c94db1e7e28d32e7d2c79a74","tests/ui/not_proc_macro.rs":"ca448d832ccf0cfdcda6f04281d8134a76c61b3ad96437e972b2cb5c6e0844c4","tests/ui/not_proc_macro.stderr":"a22c53a7dd5a03ddfaee5a7fb7fe5d61cb588b2d81a30c1e935b789baf0d2676","tests/ui/option_ext.rs":"1db81c17172f155c0ca8bcf92d55b5852b92107a3ba1d4b2ae6d14020df67f96","tests/ui/option_ext.stderr":"3b363759db60ee4f249dfde4d4571963032d5f0043249de40bd3b38eecc65404","tests/ui/proc_macro_hack.rs":"1d08c3e2c4c331e230c7cdaa2635ca1e43077252f90d3a430dcd091c646a842c","tests/ui/proc_macro_hack.stderr":"65e887dc208b92bfcd44405e76d5d05e315c3c5c5f637070954b7d593c723731","tests/ui/result_ext.rs":"ef398e76aab82a574ca5a988a91353e1a87fcfcb459d30314eceed3cbcf6fcd8","tests/ui/result_ext.stderr":"9e1e387b1378d9ec40ccb29be9f8cdaa5b42060c3f4f9b3c09fb307d5dcf7d85","tests/ui/to_tokens_span.rs":"d017a3c4cd583defe9806cdc51220bde89ced871ddd4d65b7cd089882feb1f61","tests/ui/to_tokens_span.stderr":"0b88e659ab214d6c7dfcd99274d327fe72da4b9bd009477e0e65165ddde65e02","tests/ui/unknown_setting.rs":"16fe9631b51023909497e857a6c674cd216ba9802fbdba360bb8273d6e00fa31","tests/ui/unknown_setting.stderr":"d605f151ce8eba5b2f867667394bd2d2adf0a233145516a9d6b801817521e587","tests/ui/unrelated_panic.rs":"438db25f8f14f1263152545a1c5135e20b3f5063dc4ab223fd8145b891039b24","tests/ui/unrelated_panic.stderr":"04cd814f2bd57d5271f93f90f0dd078b09ee3fd73137245a914d698e4a33ed57"},"package":"da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/CHANGELOG.md b/rust/hw/char/pl011/vendor/proc-macro-error/CHANGELOG.md
new file mode 100644
index 0000000000..3c422f1c45
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/CHANGELOG.md
@@ -0,0 +1,162 @@
+# v1.0.4 (2020-7-31)
+
+* `SpanRange` facility is now public.
+* Docs have been improved.
+* Introduced the `syn-error` feature so you can opt-out from the `syn` dependency.
+
+# v1.0.3 (2020-6-26)
+
+* Corrected a few typos.
+* Fixed the `emit_call_site_warning` macro.
+
+# v1.0.2 (2020-4-9)
+
+* An obsolete note was removed from documentation.
+
+# v1.0.1 (2020-4-9)
+
+* `proc-macro-hack` is now well tested and supported. Not sure about `proc-macro-nested`,
+ please fill a request if you need it.
+* Fixed `emit_call_site_error`.
+* Documentation improvements.
+
+# v1.0.0 (2020-3-25)
+
+I believe the API can be considered stable because it's been a few months without
+breaking changes, and I also don't think this crate will receive much further evolution.
+It's perfect, admit it.
+
+Hence, meet the new, stable release!
+
+### Improvements
+
+* Supported nested `#[proc_macro_error]` attributes. Well, you aren't supposed to do that,
+ but I caught myself doing it by accident on one occasion and the behavior was... surprising.
+ Better to handle this smooth.
+
+# v0.4.12 (2020-3-23)
+
+* Error message on macros' misuse is now a bit more understandable.
+
+# v0.4.11 (2020-3-02)
+
+* `build.rs` no longer fails when `rustc` date could not be determined,
+ (thanks to [`Fabian Möller`](https://gitlab.com/CreepySkeleton/proc-macro-error/issues/8)
+ for noticing and to [`Igor Gnatenko`](https://gitlab.com/CreepySkeleton/proc-macro-error/-/merge_requests/25)
+ for fixing).
+
+# v0.4.10 (2020-2-29)
+
+* `proc-macro-error` doesn't depend on syn\[full\] anymore, the compilation
+ is \~30secs faster.
+
+# v0.4.9 (2020-2-13)
+
+* New function: `append_dummy`.
+
+# v0.4.8 (2020-2-01)
+
+* Support for children messages
+
+# v0.4.7 (2020-1-31)
+
+* Now any type that implements `quote::ToTokens` can be used instead of spans.
+ This allows for high quality error messages.
+
+# v0.4.6 (2020-1-31)
+
+* `From<syn::Error>` implementation doesn't lose span info anymore, see
+ [#6](https://gitlab.com/CreepySkeleton/proc-macro-error/issues/6).
+
+# v0.4.5 (2020-1-20)
+Just a small intermediate release.
+
+* Fix some bugs.
+* Populate license files into subfolders.
+
+# v0.4.4 (2019-11-13)
+* Fix `abort_if_dirty` + warnings bug
+* Allow trailing commas in macros
+
+# v0.4.2 (2019-11-7)
+* FINALLY fixed `__pme__suggestions not found` bug
+
+# v0.4.1 (2019-11-7) YANKED
+* Fixed `__pme__suggestions not found` bug
+* Documentation improvements, links checked
+
+# v0.4.0 (2019-11-6) YANKED
+
+## New features
+* "help" messages that can have their own span on nightly, they
+ inherit parent span on stable.
+ ```rust
+ let cond_help = if condition { Some("some help message") else { None } };
+ abort!(
+ span, // parent span
+ "something's wrong, {} wrongs in total", 10; // main message
+ help = "here's a help for you, {}", "take it"; // unconditional help message
+ help =? cond_help; // conditional help message, must be Option
+ note = note_span => "don't forget the note, {}", "would you?" // notes can have their own span but it's effective only on nightly
+ )
+ ```
+* Warnings via `emit_warning` and `emit_warning_call_site`. Nightly only, they're ignored on stable.
+* Now `proc-macro-error` delegates to `proc_macro::Diagnostic` on nightly.
+
+## Breaking changes
+* `MacroError` is now replaced by `Diagnostic`. Its API resembles `proc_macro::Diagnostic`.
+* `Diagnostic` does not implement `From<&str/String>` so `Result<T, &str/String>::abort_or_exit()`
+ won't work anymore (nobody used it anyway).
+* `macro_error!` macro is replaced with `diagnostic!`.
+
+## Improvements
+* Now `proc-macro-error` renders notes exactly just like rustc does.
+* We don't parse a body of a function annotated with `#[proc_macro_error]` anymore,
+ only looking at the signature. This should somewhat decrease expansion time for large functions.
+
+# v0.3.3 (2019-10-16)
+* Now you can use any word instead of "help", undocumented.
+
+# v0.3.2 (2019-10-16)
+* Introduced support for "help" messages, undocumented.
+
+# v0.3.0 (2019-10-8)
+
+## The crate has been completely rewritten from scratch!
+
+## Changes (most are breaking):
+* Renamed macros:
+ * `span_error` => `abort`
+ * `call_site_error` => `abort_call_site`
+* `filter_macro_errors` was replaced by `#[proc_macro_error]` attribute.
+* `set_dummy` now takes `TokenStream` instead of `Option<TokenStream>`
+* Support for multiple errors via `emit_error` and `emit_call_site_error`
+* New `macro_error` macro for building errors in format=like style.
+* `MacroError` API had been reconsidered. It also now implements `quote::ToTokens`.
+
+# v0.2.6 (2019-09-02)
+* Introduce support for dummy implementations via `dummy::set_dummy`
+* `multi::*` is now deprecated, will be completely rewritten in v0.3
+
+# v0.2.0 (2019-08-15)
+
+## Breaking changes
+* `trigger_error` replaced with `MacroError::trigger` and `filter_macro_error_panics`
+ is hidden from docs.
+ This is not quite a breaking change since users weren't supposed to use these functions directly anyway.
+* All dependencies are updated to `v1.*`.
+
+## New features
+* Ability to stack multiple errors via `multi::MultiMacroErrors` and emit them at once.
+
+## Improvements
+* Now `MacroError` implements `std::fmt::Display` instead of `std::string::ToString`.
+* `MacroError::span` inherent method.
+* `From<MacroError> for proc_macro/proc_macro2::TokenStream` implementations.
+* `AsRef/AsMut<String> for MacroError` implementations.
+
+# v0.1.x (2019-07-XX)
+
+## New features
+* An easy way to report errors inside within a proc-macro via `span_error`,
+ `call_site_error` and `filter_macro_errors`.
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/Cargo.toml b/rust/hw/char/pl011/vendor/proc-macro-error/Cargo.toml
new file mode 100644
index 0000000000..869585ffc2
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/Cargo.toml
@@ -0,0 +1,56 @@
+# 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 believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "proc-macro-error"
+version = "1.0.4"
+authors = ["CreepySkeleton <creepy-skeleton@yandex.ru>"]
+build = "build.rs"
+description = "Almost drop-in replacement to panics in proc-macros"
+readme = "README.md"
+keywords = ["proc-macro", "error", "errors"]
+categories = ["development-tools::procedural-macro-helpers"]
+license = "MIT OR Apache-2.0"
+repository = "https://gitlab.com/CreepySkeleton/proc-macro-error"
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+[dependencies.proc-macro-error-attr]
+version = "=1.0.4"
+
+[dependencies.proc-macro2]
+version = "1"
+
+[dependencies.quote]
+version = "1"
+
+[dependencies.syn]
+version = "1"
+optional = true
+default-features = false
+[dev-dependencies.serde_derive]
+version = "=1.0.107"
+
+[dev-dependencies.toml]
+version = "=0.5.2"
+
+[dev-dependencies.trybuild]
+version = "1.0.19"
+features = ["diff"]
+[build-dependencies.version_check]
+version = "0.9"
+
+[features]
+default = ["syn-error"]
+syn-error = ["syn"]
+[badges.maintenance]
+status = "passively-maintained"
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-APACHE b/rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-APACHE
new file mode 100644
index 0000000000..cc17374b25
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ 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
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright 2019-2020 CreepySkeleton <creepy-skeleton@yandex.ru>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-MIT b/rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-MIT
new file mode 100644
index 0000000000..fc73e591d7
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-MIT
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019-2020 CreepySkeleton
+
+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/rust/hw/char/pl011/vendor/proc-macro-error/README.md b/rust/hw/char/pl011/vendor/proc-macro-error/README.md
new file mode 100644
index 0000000000..7fbe07c53a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/README.md
@@ -0,0 +1,258 @@
+# Makes error reporting in procedural macros nice and easy
+
+[](https://travis-ci.org/CreepySkeleton/proc-macro-error)
+[](https://docs.rs/proc-macro-error)
+[](https://github.com/rust-secure-code/safety-dance/)
+
+This crate aims to make error reporting in proc-macros simple and easy to use.
+Migrate from `panic!`-based errors for as little effort as possible!
+
+Also, you can explicitly [append a dummy token stream][crate::dummy] to your errors.
+
+To achieve his, this crate serves as a tiny shim around `proc_macro::Diagnostic` and
+`compile_error!`. It detects the most preferable way to emit errors based on compiler's version.
+When the underlying diagnostic type is finally stabilized, this crate will be simply
+delegating to it, requiring no changes in your code!
+
+So you can just use this crate and have *both* some of `proc_macro::Diagnostic` functionality
+available on stable ahead of time and your error-reporting code future-proof.
+
+```toml
+[dependencies]
+proc-macro-error = "1.0"
+```
+
+*Supports rustc 1.31 and up*
+
+[Documentation and guide][guide]
+
+## Quick example
+
+Code:
+
+```rust
+#[proc_macro]
+#[proc_macro_error]
+pub fn make_fn(input: TokenStream) -> TokenStream {
+ let mut input = TokenStream2::from(input).into_iter();
+ let name = input.next().unwrap();
+ if let Some(second) = input.next() {
+ abort! { second,
+ "I don't like this part!";
+ note = "I see what you did there...";
+ help = "I need only one part, you know?";
+ }
+ }
+
+ quote!( fn #name() {} ).into()
+}
+```
+
+This is how the error is rendered in a terminal:
+
+<p align="center">
+<img src="https://user-images.githubusercontent.com/50968528/78830016-d3b46a80-79d6-11ea-9de2-972e8d7904ef.png" width="600">
+</p>
+
+And this is what your users will see in their IDE:
+
+<p align="center">
+<img src="https://user-images.githubusercontent.com/50968528/78830547-a9af7800-79d7-11ea-822e-59e29bda335c.png" width="600">
+</p>
+
+## Examples
+
+### Panic-like usage
+
+```rust
+use proc_macro_error::{
+ proc_macro_error,
+ abort,
+ abort_call_site,
+ ResultExt,
+ OptionExt,
+};
+use proc_macro::TokenStream;
+use syn::{DeriveInput, parse_macro_input};
+use quote::quote;
+
+// This is your main entry point
+#[proc_macro]
+// This attribute *MUST* be placed on top of the #[proc_macro] function
+#[proc_macro_error]
+pub fn make_answer(input: TokenStream) -> TokenStream {
+ let input = parse_macro_input!(input as DeriveInput);
+
+ if let Err(err) = some_logic(&input) {
+ // we've got a span to blame, let's use it
+ // This immediately aborts the proc-macro and shows the error
+ //
+ // You can use `proc_macro::Span`, `proc_macro2::Span`, and
+ // anything that implements `quote::ToTokens` (almost every type from
+ // `syn` and `proc_macro2`)
+ abort!(err, "You made an error, go fix it: {}", err.msg);
+ }
+
+ // `Result` has some handy shortcuts if your error type implements
+ // `Into<Diagnostic>`. `Option` has one unconditionally.
+ more_logic(&input).expect_or_abort("What a careless user, behave!");
+
+ if !more_logic_for_logic_god(&input) {
+ // We don't have an exact location this time,
+ // so just highlight the proc-macro invocation itself
+ abort_call_site!(
+ "Bad, bad user! Now go stand in the corner and think about what you did!");
+ }
+
+ // Now all the processing is done, return `proc_macro::TokenStream`
+ quote!(/* stuff */).into()
+}
+```
+
+### `proc_macro::Diagnostic`-like usage
+
+```rust
+use proc_macro_error::*;
+use proc_macro::TokenStream;
+use syn::{spanned::Spanned, DeriveInput, ItemStruct, Fields, Attribute , parse_macro_input};
+use quote::quote;
+
+fn process_attrs(attrs: &[Attribute]) -> Vec<Attribute> {
+ attrs
+ .iter()
+ .filter_map(|attr| match process_attr(attr) {
+ Ok(res) => Some(res),
+ Err(msg) => {
+ emit_error!(attr, "Invalid attribute: {}", msg);
+ None
+ }
+ })
+ .collect()
+}
+
+fn process_fields(_attrs: &Fields) -> Vec<TokenStream> {
+ // processing fields in pretty much the same way as attributes
+ unimplemented!()
+}
+
+#[proc_macro]
+#[proc_macro_error]
+pub fn make_answer(input: TokenStream) -> TokenStream {
+ let input = parse_macro_input!(input as ItemStruct);
+ let attrs = process_attrs(&input.attrs);
+
+ // abort right now if some errors were encountered
+ // at the attributes processing stage
+ abort_if_dirty();
+
+ let fields = process_fields(&input.fields);
+
+ // no need to think about emitted errors
+ // #[proc_macro_error] will handle them for you
+ //
+ // just return a TokenStream as you normally would
+ quote!(/* stuff */).into()
+}
+```
+
+## Real world examples
+
+* [`structopt-derive`](https://github.com/TeXitoi/structopt/tree/master/structopt-derive)
+ (abort-like usage)
+* [`auto-impl`](https://github.com/auto-impl-rs/auto_impl/) (emit-like usage)
+
+## Limitations
+
+- Warnings are emitted only on nightly, they are ignored on stable.
+- "help" suggestions can't have their own span info on stable,
+ (essentially inheriting the parent span).
+- If your macro happens to trigger a panic, no errors will be displayed. This is not a
+ technical limitation but rather intentional design. `panic` is not for error reporting.
+
+## MSRV policy
+
+`proc_macro_error` will always be compatible with proc-macro Holy Trinity:
+`proc_macro2`, `syn`, `quote` crates. In other words, if the Trinity is available
+to you - `proc_macro_error` is available too.
+
+> **Important!**
+>
+> If you want to use `#[proc_macro_error]` with `synstructure`, you're going
+> to have to put the attribute inside the `decl_derive!` invocation. Unfortunately,
+> due to some bug in pre-1.34 rustc, putting proc-macro attributes inside macro
+> invocations doesn't work, so your MSRV is effectively 1.34.
+
+## Motivation
+
+Error handling in proc-macros sucks. There's not much of a choice today:
+you either "bubble up" the error up to the top-level of the macro and convert it to
+a [`compile_error!`][compl_err] invocation or just use a good old panic. Both these ways suck:
+
+- Former sucks because it's quite redundant to unroll a proper error handling
+ just for critical errors that will crash the macro anyway; so people mostly
+ choose not to bother with it at all and use panic. Simple `.expect` is too tempting.
+
+ Also, if you do decide to implement this `Result`-based architecture in your macro
+ you're going to have to rewrite it entirely once [`proc_macro::Diagnostic`][] is finally
+ stable. Not cool.
+
+- Later sucks because there's no way to carry out the span info via `panic!`.
+ `rustc` will highlight the invocation itself but not some specific token inside it.
+
+ Furthermore, panics aren't for error-reporting at all; panics are for bug-detecting
+ (like unwrapping on `None` or out-of-range indexing) or for early development stages
+ when you need a prototype ASAP so error handling can wait. Mixing these usages only
+ messes things up.
+
+- There is [`proc_macro::Diagnostic`][] which is awesome but it has been experimental
+ for more than a year and is unlikely to be stabilized any time soon.
+
+ This crate's API is intentionally designed to be compatible with `proc_macro::Diagnostic`
+ and delegates to it whenever possible. Once `Diagnostics` is stable this crate
+ will **always** delegate to it, no code changes will be required on user side.
+
+That said, we need a solution, but this solution must meet these conditions:
+
+- It must be better than `panic!`. The main point: it must offer a way to carry the span information
+ over to user.
+- It must take as little effort as possible to migrate from `panic!`. Ideally, a new
+ macro with similar semantics plus ability to carry out span info.
+- It must maintain compatibility with [`proc_macro::Diagnostic`][] .
+- **It must be usable on stable**.
+
+This crate aims to provide such a mechanism. All you have to do is annotate your top-level
+`#[proc_macro]` function with `#[proc_macro_error]` attribute and change panics to
+[`abort!`]/[`abort_call_site!`] where appropriate, see [the Guide][guide].
+
+## Disclaimer
+Please note that **this crate is not intended to be used in any way other
+than error reporting in procedural macros**, use `Result` and `?` (possibly along with one of the
+many helpers out there) for anything else.
+
+<br>
+
+#### License
+
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
+
+<br>
+
+<sub>
+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.
+</sub>
+
+
+[compl_err]: https://doc.rust-lang.org/std/macro.compile_error.html
+[`proc_macro::Diagnostic`]: https://doc.rust-lang.org/proc_macro/struct.Diagnostic.html
+
+[crate::dummy]: https://docs.rs/proc-macro-error/1/proc_macro_error/dummy/index.html
+[crate::multi]: https://docs.rs/proc-macro-error/1/proc_macro_error/multi/index.html
+
+[`abort_call_site!`]: https://docs.rs/proc-macro-error/1/proc_macro_error/macro.abort_call_site.html
+[`abort!`]: https://docs.rs/proc-macro-error/1/proc_macro_error/macro.abort.html
+[guide]: https://docs.rs/proc-macro-error
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/build.rs b/rust/hw/char/pl011/vendor/proc-macro-error/build.rs
new file mode 100644
index 0000000000..3c1196f269
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/build.rs
@@ -0,0 +1,11 @@
+fn main() {
+ if !version_check::is_feature_flaggable().unwrap_or(false) {
+ println!("cargo:rustc-cfg=use_fallback");
+ }
+
+ if version_check::is_max_version("1.38.0").unwrap_or(false)
+ || !version_check::Channel::read().unwrap().is_stable()
+ {
+ println!("cargo:rustc-cfg=skip_ui_tests");
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/meson.build b/rust/hw/char/pl011/vendor/proc-macro-error/meson.build
new file mode 100644
index 0000000000..db5d09f5db
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/meson.build
@@ -0,0 +1,22 @@
+_proc_macro_error_rs = static_library(
+ 'proc_macro_error',
+ files('src/lib.rs'),
+ rust_abi: 'rust',
+ rust_args: rust_args + [
+ '--edition', '2018',
+ '--cfg', 'use_fallback',
+ '--cfg', 'feature="syn-error"',
+ '--cfg', 'feature="proc-macro"',
+ '-A', 'non_fmt_panics'
+ ],
+ dependencies: [
+ dep_proc_macro_error_attr,
+ dep_proc_macro2,
+ dep_quote,
+ dep_syn,
+ ],
+)
+
+dep_proc_macro_error = declare_dependency(
+ link_with: _proc_macro_error_rs,
+)
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/src/diagnostic.rs b/rust/hw/char/pl011/vendor/proc-macro-error/src/diagnostic.rs
new file mode 100644
index 0000000000..983e6174fe
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/src/diagnostic.rs
@@ -0,0 +1,349 @@
+use crate::{abort_now, check_correctness, sealed::Sealed, SpanRange};
+use proc_macro2::Span;
+use proc_macro2::TokenStream;
+
+use quote::{quote_spanned, ToTokens};
+
+/// Represents a diagnostic level
+///
+/// # Warnings
+///
+/// Warnings are ignored on stable/beta
+#[derive(Debug, PartialEq)]
+pub enum Level {
+ Error,
+ Warning,
+ #[doc(hidden)]
+ NonExhaustive,
+}
+
+/// Represents a single diagnostic message
+#[derive(Debug)]
+pub struct Diagnostic {
+ pub(crate) level: Level,
+ pub(crate) span_range: SpanRange,
+ pub(crate) msg: String,
+ pub(crate) suggestions: Vec<(SuggestionKind, String, Option<SpanRange>)>,
+ pub(crate) children: Vec<(SpanRange, String)>,
+}
+
+/// A collection of methods that do not exist in `proc_macro::Diagnostic`
+/// but still useful to have around.
+///
+/// This trait is sealed and cannot be implemented outside of `proc_macro_error`.
+pub trait DiagnosticExt: Sealed {
+ /// Create a new diagnostic message that points to the `span_range`.
+ ///
+ /// This function is the same as `Diagnostic::spanned` but produces considerably
+ /// better error messages for multi-token spans on stable.
+ fn spanned_range(span_range: SpanRange, level: Level, message: String) -> Self;
+
+ /// Add another error message to self such that it will be emitted right after
+ /// the main message.
+ ///
+ /// This function is the same as `Diagnostic::span_error` but produces considerably
+ /// better error messages for multi-token spans on stable.
+ fn span_range_error(self, span_range: SpanRange, msg: String) -> Self;
+
+ /// Attach a "help" note to your main message, the note will have it's own span on nightly.
+ ///
+ /// This function is the same as `Diagnostic::span_help` but produces considerably
+ /// better error messages for multi-token spans on stable.
+ ///
+ /// # Span
+ ///
+ /// The span is ignored on stable, the note effectively inherits its parent's (main message) span
+ fn span_range_help(self, span_range: SpanRange, msg: String) -> Self;
+
+ /// Attach a note to your main message, the note will have it's own span on nightly.
+ ///
+ /// This function is the same as `Diagnostic::span_note` but produces considerably
+ /// better error messages for multi-token spans on stable.
+ ///
+ /// # Span
+ ///
+ /// The span is ignored on stable, the note effectively inherits its parent's (main message) span
+ fn span_range_note(self, span_range: SpanRange, msg: String) -> Self;
+}
+
+impl DiagnosticExt for Diagnostic {
+ fn spanned_range(span_range: SpanRange, level: Level, message: String) -> Self {
+ Diagnostic {
+ level,
+ span_range,
+ msg: message,
+ suggestions: vec![],
+ children: vec![],
+ }
+ }
+
+ fn span_range_error(mut self, span_range: SpanRange, msg: String) -> Self {
+ self.children.push((span_range, msg));
+ self
+ }
+
+ fn span_range_help(mut self, span_range: SpanRange, msg: String) -> Self {
+ self.suggestions
+ .push((SuggestionKind::Help, msg, Some(span_range)));
+ self
+ }
+
+ fn span_range_note(mut self, span_range: SpanRange, msg: String) -> Self {
+ self.suggestions
+ .push((SuggestionKind::Note, msg, Some(span_range)));
+ self
+ }
+}
+
+impl Diagnostic {
+ /// Create a new diagnostic message that points to `Span::call_site()`
+ pub fn new(level: Level, message: String) -> Self {
+ Diagnostic::spanned(Span::call_site(), level, message)
+ }
+
+ /// Create a new diagnostic message that points to the `span`
+ pub fn spanned(span: Span, level: Level, message: String) -> Self {
+ Diagnostic::spanned_range(
+ SpanRange {
+ first: span,
+ last: span,
+ },
+ level,
+ message,
+ )
+ }
+
+ /// Add another error message to self such that it will be emitted right after
+ /// the main message.
+ pub fn span_error(self, span: Span, msg: String) -> Self {
+ self.span_range_error(
+ SpanRange {
+ first: span,
+ last: span,
+ },
+ msg,
+ )
+ }
+
+ /// Attach a "help" note to your main message, the note will have it's own span on nightly.
+ ///
+ /// # Span
+ ///
+ /// The span is ignored on stable, the note effectively inherits its parent's (main message) span
+ pub fn span_help(self, span: Span, msg: String) -> Self {
+ self.span_range_help(
+ SpanRange {
+ first: span,
+ last: span,
+ },
+ msg,
+ )
+ }
+
+ /// Attach a "help" note to your main message.
+ pub fn help(mut self, msg: String) -> Self {
+ self.suggestions.push((SuggestionKind::Help, msg, None));
+ self
+ }
+
+ /// Attach a note to your main message, the note will have it's own span on nightly.
+ ///
+ /// # Span
+ ///
+ /// The span is ignored on stable, the note effectively inherits its parent's (main message) span
+ pub fn span_note(self, span: Span, msg: String) -> Self {
+ self.span_range_note(
+ SpanRange {
+ first: span,
+ last: span,
+ },
+ msg,
+ )
+ }
+
+ /// Attach a note to your main message
+ pub fn note(mut self, msg: String) -> Self {
+ self.suggestions.push((SuggestionKind::Note, msg, None));
+ self
+ }
+
+ /// The message of main warning/error (no notes attached)
+ pub fn message(&self) -> &str {
+ &self.msg
+ }
+
+ /// Abort the proc-macro's execution and display the diagnostic.
+ ///
+ /// # Warnings
+ ///
+ /// Warnings are not emitted on stable and beta, but this function will abort anyway.
+ pub fn abort(self) -> ! {
+ self.emit();
+ abort_now()
+ }
+
+ /// Display the diagnostic while not aborting macro execution.
+ ///
+ /// # Warnings
+ ///
+ /// Warnings are ignored on stable/beta
+ pub fn emit(self) {
+ check_correctness();
+ crate::imp::emit_diagnostic(self);
+ }
+}
+
+/// **NOT PUBLIC API! NOTHING TO SEE HERE!!!**
+#[doc(hidden)]
+impl Diagnostic {
+ pub fn span_suggestion(self, span: Span, suggestion: &str, msg: String) -> Self {
+ match suggestion {
+ "help" | "hint" => self.span_help(span, msg),
+ _ => self.span_note(span, msg),
+ }
+ }
+
+ pub fn suggestion(self, suggestion: &str, msg: String) -> Self {
+ match suggestion {
+ "help" | "hint" => self.help(msg),
+ _ => self.note(msg),
+ }
+ }
+}
+
+impl ToTokens for Diagnostic {
+ fn to_tokens(&self, ts: &mut TokenStream) {
+ use std::borrow::Cow;
+
+ fn ensure_lf(buf: &mut String, s: &str) {
+ if s.ends_with('\n') {
+ buf.push_str(s);
+ } else {
+ buf.push_str(s);
+ buf.push('\n');
+ }
+ }
+
+ fn diag_to_tokens(
+ span_range: SpanRange,
+ level: &Level,
+ msg: &str,
+ suggestions: &[(SuggestionKind, String, Option<SpanRange>)],
+ ) -> TokenStream {
+ if *level == Level::Warning {
+ return TokenStream::new();
+ }
+
+ let message = if suggestions.is_empty() {
+ Cow::Borrowed(msg)
+ } else {
+ let mut message = String::new();
+ ensure_lf(&mut message, msg);
+ message.push('\n');
+
+ for (kind, note, _span) in suggestions {
+ message.push_str(" = ");
+ message.push_str(kind.name());
+ message.push_str(": ");
+ ensure_lf(&mut message, note);
+ }
+ message.push('\n');
+
+ Cow::Owned(message)
+ };
+
+ let mut msg = proc_macro2::Literal::string(&message);
+ msg.set_span(span_range.last);
+ let group = quote_spanned!(span_range.last=> { #msg } );
+ quote_spanned!(span_range.first=> compile_error!#group)
+ }
+
+ ts.extend(diag_to_tokens(
+ self.span_range,
+ &self.level,
+ &self.msg,
+ &self.suggestions,
+ ));
+ ts.extend(
+ self.children
+ .iter()
+ .map(|(span_range, msg)| diag_to_tokens(*span_range, &Level::Error, &msg, &[])),
+ );
+ }
+}
+
+#[derive(Debug)]
+pub(crate) enum SuggestionKind {
+ Help,
+ Note,
+}
+
+impl SuggestionKind {
+ fn name(&self) -> &'static str {
+ match self {
+ SuggestionKind::Note => "note",
+ SuggestionKind::Help => "help",
+ }
+ }
+}
+
+#[cfg(feature = "syn-error")]
+impl From<syn::Error> for Diagnostic {
+ fn from(err: syn::Error) -> Self {
+ use proc_macro2::{Delimiter, TokenTree};
+
+ fn gut_error(ts: &mut impl Iterator<Item = TokenTree>) -> Option<(SpanRange, String)> {
+ let first = match ts.next() {
+ // compile_error
+ None => return None,
+ Some(tt) => tt.span(),
+ };
+ ts.next().unwrap(); // !
+
+ let lit = match ts.next().unwrap() {
+ TokenTree::Group(group) => {
+ // Currently `syn` builds `compile_error!` invocations
+ // exclusively in `ident{"..."}` (braced) form which is not
+ // followed by `;` (semicolon).
+ //
+ // But if it changes to `ident("...");` (parenthesized)
+ // or `ident["..."];` (bracketed) form,
+ // we will need to skip the `;` as well.
+ // Highly unlikely, but better safe than sorry.
+
+ if group.delimiter() == Delimiter::Parenthesis
+ || group.delimiter() == Delimiter::Bracket
+ {
+ ts.next().unwrap(); // ;
+ }
+
+ match group.stream().into_iter().next().unwrap() {
+ TokenTree::Literal(lit) => lit,
+ _ => unreachable!(),
+ }
+ }
+ _ => unreachable!(),
+ };
+
+ let last = lit.span();
+ let mut msg = lit.to_string();
+
+ // "abc" => abc
+ msg.pop();
+ msg.remove(0);
+
+ Some((SpanRange { first, last }, msg))
+ }
+
+ let mut ts = err.to_compile_error().into_iter();
+
+ let (span_range, msg) = gut_error(&mut ts).unwrap();
+ let mut res = Diagnostic::spanned_range(span_range, Level::Error, msg);
+
+ while let Some((span_range, msg)) = gut_error(&mut ts) {
+ res = res.span_range_error(span_range, msg);
+ }
+
+ res
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/src/dummy.rs b/rust/hw/char/pl011/vendor/proc-macro-error/src/dummy.rs
new file mode 100644
index 0000000000..571a595aa9
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/src/dummy.rs
@@ -0,0 +1,150 @@
+//! Facility to emit dummy implementations (or whatever) in case
+//! an error happen.
+//!
+//! `compile_error!` does not abort a compilation right away. This means
+//! `rustc` doesn't just show you the error and abort, it carries on the
+//! compilation process looking for other errors to report.
+//!
+//! Let's consider an example:
+//!
+//! ```rust,ignore
+//! use proc_macro::TokenStream;
+//! use proc_macro_error::*;
+//!
+//! trait MyTrait {
+//! fn do_thing();
+//! }
+//!
+//! // this proc macro is supposed to generate MyTrait impl
+//! #[proc_macro_derive(MyTrait)]
+//! #[proc_macro_error]
+//! fn example(input: TokenStream) -> TokenStream {
+//! // somewhere deep inside
+//! abort!(span, "something's wrong");
+//!
+//! // this implementation will be generated if no error happened
+//! quote! {
+//! impl MyTrait for #name {
+//! fn do_thing() {/* whatever */}
+//! }
+//! }
+//! }
+//!
+//! // ================
+//! // in main.rs
+//!
+//! // this derive triggers an error
+//! #[derive(MyTrait)] // first BOOM!
+//! struct Foo;
+//!
+//! fn main() {
+//! Foo::do_thing(); // second BOOM!
+//! }
+//! ```
+//!
+//! The problem is: the generated token stream contains only `compile_error!`
+//! invocation, the impl was not generated. That means user will see two compilation
+//! errors:
+//!
+//! ```text
+//! error: something's wrong
+//! --> $DIR/probe.rs:9:10
+//! |
+//! 9 |#[proc_macro_derive(MyTrait)]
+//! | ^^^^^^^
+//!
+//! error[E0599]: no function or associated item named `do_thing` found for type `Foo` in the current scope
+//! --> src\main.rs:3:10
+//! |
+//! 1 | struct Foo;
+//! | ----------- function or associated item `do_thing` not found for this
+//! 2 | fn main() {
+//! 3 | Foo::do_thing(); // second BOOM!
+//! | ^^^^^^^^ function or associated item not found in `Foo`
+//! ```
+//!
+//! But the second error is meaningless! We definitely need to fix this.
+//!
+//! Most used approach in cases like this is "dummy implementation" -
+//! omit `impl MyTrait for #name` and fill functions bodies with `unimplemented!()`.
+//!
+//! This is how you do it:
+//!
+//! ```rust,ignore
+//! use proc_macro::TokenStream;
+//! use proc_macro_error::*;
+//!
+//! trait MyTrait {
+//! fn do_thing();
+//! }
+//!
+//! // this proc macro is supposed to generate MyTrait impl
+//! #[proc_macro_derive(MyTrait)]
+//! #[proc_macro_error]
+//! fn example(input: TokenStream) -> TokenStream {
+//! // first of all - we set a dummy impl which will be appended to
+//! // `compile_error!` invocations in case a trigger does happen
+//! set_dummy(quote! {
+//! impl MyTrait for #name {
+//! fn do_thing() { unimplemented!() }
+//! }
+//! });
+//!
+//! // somewhere deep inside
+//! abort!(span, "something's wrong");
+//!
+//! // this implementation will be generated if no error happened
+//! quote! {
+//! impl MyTrait for #name {
+//! fn do_thing() {/* whatever */}
+//! }
+//! }
+//! }
+//!
+//! // ================
+//! // in main.rs
+//!
+//! // this derive triggers an error
+//! #[derive(MyTrait)] // first BOOM!
+//! struct Foo;
+//!
+//! fn main() {
+//! Foo::do_thing(); // no more errors!
+//! }
+//! ```
+
+use proc_macro2::TokenStream;
+use std::cell::RefCell;
+
+use crate::check_correctness;
+
+thread_local! {
+ static DUMMY_IMPL: RefCell<Option<TokenStream>> = RefCell::new(None);
+}
+
+/// Sets dummy token stream which will be appended to `compile_error!(msg);...`
+/// invocations in case you'll emit any errors.
+///
+/// See [guide](../index.html#guide).
+pub fn set_dummy(dummy: TokenStream) -> Option<TokenStream> {
+ check_correctness();
+ DUMMY_IMPL.with(|old_dummy| old_dummy.replace(Some(dummy)))
+}
+
+/// Same as [`set_dummy`] but, instead of resetting, appends tokens to the
+/// existing dummy (if any). Behaves as `set_dummy` if no dummy is present.
+pub fn append_dummy(dummy: TokenStream) {
+ check_correctness();
+ DUMMY_IMPL.with(|old_dummy| {
+ let mut cell = old_dummy.borrow_mut();
+ if let Some(ts) = cell.as_mut() {
+ ts.extend(dummy);
+ } else {
+ *cell = Some(dummy);
+ }
+ });
+}
+
+pub(crate) fn cleanup() -> Option<TokenStream> {
+ DUMMY_IMPL.with(|old_dummy| old_dummy.replace(None))
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/src/imp/delegate.rs b/rust/hw/char/pl011/vendor/proc-macro-error/src/imp/delegate.rs
new file mode 100644
index 0000000000..07def2b98e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/src/imp/delegate.rs
@@ -0,0 +1,69 @@
+//! This implementation uses [`proc_macro::Diagnostic`], nightly only.
+
+use std::cell::Cell;
+
+use proc_macro::{Diagnostic as PDiag, Level as PLevel};
+
+use crate::{
+ abort_now, check_correctness,
+ diagnostic::{Diagnostic, Level, SuggestionKind},
+};
+
+pub fn abort_if_dirty() {
+ check_correctness();
+ if IS_DIRTY.with(|c| c.get()) {
+ abort_now()
+ }
+}
+
+pub(crate) fn cleanup() -> Vec<Diagnostic> {
+ IS_DIRTY.with(|c| c.set(false));
+ vec![]
+}
+
+pub(crate) fn emit_diagnostic(diag: Diagnostic) {
+ let Diagnostic {
+ level,
+ span_range,
+ msg,
+ suggestions,
+ children,
+ } = diag;
+
+ let span = span_range.collapse().unwrap();
+
+ let level = match level {
+ Level::Warning => PLevel::Warning,
+ Level::Error => {
+ IS_DIRTY.with(|c| c.set(true));
+ PLevel::Error
+ }
+ _ => unreachable!(),
+ };
+
+ let mut res = PDiag::spanned(span, level, msg);
+
+ for (kind, msg, span) in suggestions {
+ res = match (kind, span) {
+ (SuggestionKind::Note, Some(span_range)) => {
+ res.span_note(span_range.collapse().unwrap(), msg)
+ }
+ (SuggestionKind::Help, Some(span_range)) => {
+ res.span_help(span_range.collapse().unwrap(), msg)
+ }
+ (SuggestionKind::Note, None) => res.note(msg),
+ (SuggestionKind::Help, None) => res.help(msg),
+ }
+ }
+
+ for (span_range, msg) in children {
+ let span = span_range.collapse().unwrap();
+ res = res.span_error(span, msg);
+ }
+
+ res.emit()
+}
+
+thread_local! {
+ static IS_DIRTY: Cell<bool> = Cell::new(false);
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/src/imp/fallback.rs b/rust/hw/char/pl011/vendor/proc-macro-error/src/imp/fallback.rs
new file mode 100644
index 0000000000..ad1f730bfc
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/src/imp/fallback.rs
@@ -0,0 +1,30 @@
+//! This implementation uses self-written stable facilities.
+
+use crate::{
+ abort_now, check_correctness,
+ diagnostic::{Diagnostic, Level},
+};
+use std::cell::RefCell;
+
+pub fn abort_if_dirty() {
+ check_correctness();
+ ERR_STORAGE.with(|storage| {
+ if !storage.borrow().is_empty() {
+ abort_now()
+ }
+ });
+}
+
+pub(crate) fn cleanup() -> Vec<Diagnostic> {
+ ERR_STORAGE.with(|storage| storage.replace(Vec::new()))
+}
+
+pub(crate) fn emit_diagnostic(diag: Diagnostic) {
+ if diag.level == Level::Error {
+ ERR_STORAGE.with(|storage| storage.borrow_mut().push(diag));
+ }
+}
+
+thread_local! {
+ static ERR_STORAGE: RefCell<Vec<Diagnostic>> = RefCell::new(Vec::new());
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/src/lib.rs b/rust/hw/char/pl011/vendor/proc-macro-error/src/lib.rs
new file mode 100644
index 0000000000..fb867fdc03
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/src/lib.rs
@@ -0,0 +1,560 @@
+//! # proc-macro-error
+//!
+//! This crate aims to make error reporting in proc-macros simple and easy to use.
+//! Migrate from `panic!`-based errors for as little effort as possible!
+//!
+//! (Also, you can explicitly [append a dummy token stream](dummy/index.html) to your errors).
+//!
+//! To achieve his, this crate serves as a tiny shim around `proc_macro::Diagnostic` and
+//! `compile_error!`. It detects the best way of emitting available based on compiler's version.
+//! When the underlying diagnostic type is finally stabilized, this crate will simply be
+//! delegating to it requiring no changes in your code!
+//!
+//! So you can just use this crate and have *both* some of `proc_macro::Diagnostic` functionality
+//! available on stable ahead of time *and* your error-reporting code future-proof.
+//!
+//! ## Cargo features
+//!
+//! This crate provides *enabled by default* `syn-error` feature that gates
+//! `impl From<syn::Error> for Diagnostic` conversion. If you don't use `syn` and want
+//! to cut off some of compilation time, you can disable it via
+//!
+//! ```toml
+//! [dependencies]
+//! proc-macro-error = { version = "1", default-features = false }
+//! ```
+//!
+//! ***Please note that disabling this feature makes sense only if you don't depend on `syn`
+//! directly or indirectly, and you very likely do.**
+//!
+//! ## Real world examples
+//!
+//! * [`structopt-derive`](https://github.com/TeXitoi/structopt/tree/master/structopt-derive)
+//! (abort-like usage)
+//! * [`auto-impl`](https://github.com/auto-impl-rs/auto_impl/) (emit-like usage)
+//!
+//! ## Limitations
+//!
+//! - Warnings are emitted only on nightly, they are ignored on stable.
+//! - "help" suggestions can't have their own span info on stable,
+//! (essentially inheriting the parent span).
+//! - If a panic occurs somewhere in your macro no errors will be displayed. This is not a
+//! technical limitation but rather intentional design. `panic` is not for error reporting.
+//!
+//! ### `#[proc_macro_error]` attribute
+//!
+//! **This attribute MUST be present on the top level of your macro** (the function
+//! annotated with any of `#[proc_macro]`, `#[proc_macro_derive]`, `#[proc_macro_attribute]`).
+//!
+//! This attribute performs the setup and cleanup necessary to make things work.
+//!
+//! In most cases you'll need the simple `#[proc_macro_error]` form without any
+//! additional settings. Feel free to [skip the "Syntax" section](#macros).
+//!
+//! #### Syntax
+//!
+//! `#[proc_macro_error]` or `#[proc_macro_error(settings...)]`, where `settings...`
+//! is a comma-separated list of:
+//!
+//! - `proc_macro_hack`:
+//!
+//! In order to correctly cooperate with `#[proc_macro_hack]`, `#[proc_macro_error]`
+//! attribute must be placed *before* (above) it, like this:
+//!
+//! ```no_run
+//! # use proc_macro2::TokenStream;
+//! # const IGNORE: &str = "
+//! #[proc_macro_error]
+//! #[proc_macro_hack]
+//! #[proc_macro]
+//! # ";
+//! fn my_macro(input: TokenStream) -> TokenStream {
+//! unimplemented!()
+//! }
+//! ```
+//!
+//! If, for some reason, you can't place it like that you can use
+//! `#[proc_macro_error(proc_macro_hack)]` instead.
+//!
+//! # Note
+//!
+//! If `proc-macro-hack` was detected (by any means) `allow_not_macro`
+//! and `assert_unwind_safe` will be applied automatically.
+//!
+//! - `allow_not_macro`:
+//!
+//! By default, the attribute checks that it's applied to a proc-macro.
+//! If none of `#[proc_macro]`, `#[proc_macro_derive]` nor `#[proc_macro_attribute]` are
+//! present it will panic. It's the intention - this crate is supposed to be used only with
+//! proc-macros.
+//!
+//! This setting is made to bypass the check, useful in certain circumstances.
+//!
+//! Pay attention: the function this attribute is applied to must return
+//! `proc_macro::TokenStream`.
+//!
+//! This setting is implied if `proc-macro-hack` was detected.
+//!
+//! - `assert_unwind_safe`:
+//!
+//! By default, your code must be [unwind safe]. If your code is not unwind safe,
+//! but you believe it's correct, you can use this setting to bypass the check.
+//! You would need this for code that uses `lazy_static` or `thread_local` with
+//! `Cell/RefCell` inside (and the like).
+//!
+//! This setting is implied if `#[proc_macro_error]` is applied to a function
+//! marked as `#[proc_macro]`, `#[proc_macro_derive]` or `#[proc_macro_attribute]`.
+//!
+//! This setting is also implied if `proc-macro-hack` was detected.
+//!
+//! ## Macros
+//!
+//! Most of the time you want to use the macros. Syntax is described in the next section below.
+//!
+//! You'll need to decide how you want to emit errors:
+//!
+//! * Emit the error and abort. Very much panic-like usage. Served by [`abort!`] and
+//! [`abort_call_site!`].
+//! * Emit the error but do not abort right away, looking for other errors to report.
+//! Served by [`emit_error!`] and [`emit_call_site_error!`].
+//!
+//! You **can** mix these usages.
+//!
+//! `abort` and `emit_error` take a "source span" as the first argument. This source
+//! will be used to highlight the place the error originates from. It must be one of:
+//!
+//! * *Something* that implements [`ToTokens`] (most types in `syn` and `proc-macro2` do).
+//! This source is the preferable one since it doesn't lose span information on multi-token
+//! spans, see [this issue](https://gitlab.com/CreepySkeleton/proc-macro-error/-/issues/6)
+//! for details.
+//! * [`proc_macro::Span`]
+//! * [`proc-macro2::Span`]
+//!
+//! The rest is your message in format-like style.
+//!
+//! See [the next section](#syntax-1) for detailed syntax.
+//!
+//! - [`abort!`]:
+//!
+//! Very much panic-like usage - abort right away and show the error.
+//! Expands to [`!`] (never type).
+//!
+//! - [`abort_call_site!`]:
+//!
+//! Shortcut for `abort!(Span::call_site(), ...)`. Expands to [`!`] (never type).
+//!
+//! - [`emit_error!`]:
+//!
+//! [`proc_macro::Diagnostic`]-like usage - emit the error but keep going,
+//! looking for other errors to report.
+//! The compilation will fail nonetheless. Expands to [`()`] (unit type).
+//!
+//! - [`emit_call_site_error!`]:
+//!
+//! Shortcut for `emit_error!(Span::call_site(), ...)`. Expands to [`()`] (unit type).
+//!
+//! - [`emit_warning!`]:
+//!
+//! Like `emit_error!` but emit a warning instead of error. The compilation won't fail
+//! because of warnings.
+//! Expands to [`()`] (unit type).
+//!
+//! **Beware**: warnings are nightly only, they are completely ignored on stable.
+//!
+//! - [`emit_call_site_warning!`]:
+//!
+//! Shortcut for `emit_warning!(Span::call_site(), ...)`. Expands to [`()`] (unit type).
+//!
+//! - [`diagnostic`]:
+//!
+//! Build an instance of `Diagnostic` in format-like style.
+//!
+//! #### Syntax
+//!
+//! All the macros have pretty much the same syntax:
+//!
+//! 1. ```ignore
+//! abort!(single_expr)
+//! ```
+//! Shortcut for `Diagnostic::from(expr).abort()`.
+//!
+//! 2. ```ignore
+//! abort!(span, message)
+//! ```
+//! The first argument is an expression the span info should be taken from.
+//!
+//! The second argument is the error message, it must implement [`ToString`].
+//!
+//! 3. ```ignore
+//! abort!(span, format_literal, format_args...)
+//! ```
+//!
+//! This form is pretty much the same as 2, except `format!(format_literal, format_args...)`
+//! will be used to for the message instead of [`ToString`].
+//!
+//! That's it. `abort!`, `emit_warning`, `emit_error` share this exact syntax.
+//!
+//! `abort_call_site!`, `emit_call_site_warning`, `emit_call_site_error` lack 1 form
+//! and do not take span in 2'th and 3'th forms. Those are essentially shortcuts for
+//! `macro!(Span::call_site(), args...)`.
+//!
+//! `diagnostic!` requires a [`Level`] instance between `span` and second argument
+//! (1'th form is the same).
+//!
+//! > **Important!**
+//! >
+//! > If you have some type from `proc_macro` or `syn` to point to, do not call `.span()`
+//! > on it but rather use it directly:
+//! > ```no_run
+//! > # use proc_macro_error::abort;
+//! > # let input = proc_macro2::TokenStream::new();
+//! > let ty: syn::Type = syn::parse2(input).unwrap();
+//! > abort!(ty, "BOOM");
+//! > // ^^ <-- avoid .span()
+//! > ```
+//! >
+//! > `.span()` calls work too, but you may experience regressions in message quality.
+//!
+//! #### Note attachments
+//!
+//! 3. Every macro can have "note" attachments (only 2 and 3 form).
+//! ```ignore
+//! let opt_help = if have_some_info { Some("did you mean `this`?") } else { None };
+//!
+//! abort!(
+//! span, message; // <--- attachments start with `;` (semicolon)
+//!
+//! help = "format {} {}", "arg1", "arg2"; // <--- every attachment ends with `;`,
+//! // maybe except the last one
+//!
+//! note = "to_string"; // <--- one arg uses `.to_string()` instead of `format!()`
+//!
+//! yay = "I see what {} did here", "you"; // <--- "help =" and "hint =" are mapped
+//! // to Diagnostic::help,
+//! // anything else is Diagnostic::note
+//!
+//! wow = note_span => "custom span"; // <--- attachments can have their own span
+//! // it takes effect only on nightly though
+//!
+//! hint =? opt_help; // <-- "optional" attachment, get displayed only if `Some`
+//! // must be single `Option` expression
+//!
+//! note =? note_span => opt_help // <-- optional attachments can have custom spans too
+//! );
+//! ```
+//!
+
+//! ### Diagnostic type
+//!
+//! [`Diagnostic`] type is intentionally designed to be API compatible with [`proc_macro::Diagnostic`].
+//! Not all API is implemented, only the part that can be reasonably implemented on stable.
+//!
+//!
+//! [`abort!`]: macro.abort.html
+//! [`abort_call_site!`]: macro.abort_call_site.html
+//! [`emit_warning!`]: macro.emit_warning.html
+//! [`emit_error!`]: macro.emit_error.html
+//! [`emit_call_site_warning!`]: macro.emit_call_site_error.html
+//! [`emit_call_site_error!`]: macro.emit_call_site_warning.html
+//! [`diagnostic!`]: macro.diagnostic.html
+//! [`Diagnostic`]: struct.Diagnostic.html
+//!
+//! [`proc_macro::Span`]: https://doc.rust-lang.org/proc_macro/struct.Span.html
+//! [`proc_macro::Diagnostic`]: https://doc.rust-lang.org/proc_macro/struct.Diagnostic.html
+//!
+//! [unwind safe]: https://doc.rust-lang.org/std/panic/trait.UnwindSafe.html#what-is-unwind-safety
+//! [`!`]: https://doc.rust-lang.org/std/primitive.never.html
+//! [`()`]: https://doc.rust-lang.org/std/primitive.unit.html
+//! [`ToString`]: https://doc.rust-lang.org/std/string/trait.ToString.html
+//!
+//! [`proc-macro2::Span`]: https://docs.rs/proc-macro2/1.0.10/proc_macro2/struct.Span.html
+//! [`ToTokens`]: https://docs.rs/quote/1.0.3/quote/trait.ToTokens.html
+//!
+
+#![cfg_attr(not(use_fallback), feature(proc_macro_diagnostic))]
+#![forbid(unsafe_code)]
+#![allow(clippy::needless_doctest_main)]
+
+extern crate proc_macro;
+
+pub use crate::{
+ diagnostic::{Diagnostic, DiagnosticExt, Level},
+ dummy::{append_dummy, set_dummy},
+};
+pub use proc_macro_error_attr::proc_macro_error;
+
+use proc_macro2::Span;
+use quote::{quote, ToTokens};
+
+use std::cell::Cell;
+use std::panic::{catch_unwind, resume_unwind, UnwindSafe};
+
+pub mod dummy;
+
+mod diagnostic;
+mod macros;
+mod sealed;
+
+#[cfg(use_fallback)]
+#[path = "imp/fallback.rs"]
+mod imp;
+
+#[cfg(not(use_fallback))]
+#[path = "imp/delegate.rs"]
+mod imp;
+
+#[derive(Debug, Clone, Copy)]
+pub struct SpanRange {
+ pub first: Span,
+ pub last: Span,
+}
+
+impl SpanRange {
+ /// Create a range with the `first` and `last` spans being the same.
+ pub fn single_span(span: Span) -> Self {
+ SpanRange {
+ first: span,
+ last: span,
+ }
+ }
+
+ /// Create a `SpanRange` resolving at call site.
+ pub fn call_site() -> Self {
+ SpanRange::single_span(Span::call_site())
+ }
+
+ /// Construct span range from a `TokenStream`. This method always preserves all the
+ /// range.
+ ///
+ /// ### Note
+ ///
+ /// If the stream is empty, the result is `SpanRange::call_site()`. If the stream
+ /// consists of only one `TokenTree`, the result is `SpanRange::single_span(tt.span())`
+ /// that doesn't lose anything.
+ pub fn from_tokens(ts: &dyn ToTokens) -> Self {
+ let mut spans = ts.to_token_stream().into_iter().map(|tt| tt.span());
+ let first = spans.next().unwrap_or_else(|| Span::call_site());
+ let last = spans.last().unwrap_or(first);
+
+ SpanRange { first, last }
+ }
+
+ /// Join two span ranges. The resulting range will start at `self.first` and end at
+ /// `other.last`.
+ pub fn join_range(self, other: SpanRange) -> Self {
+ SpanRange {
+ first: self.first,
+ last: other.last,
+ }
+ }
+
+ /// Collapse the range into single span, preserving as much information as possible.
+ pub fn collapse(self) -> Span {
+ self.first.join(self.last).unwrap_or(self.first)
+ }
+}
+
+/// This traits expands `Result<T, Into<Diagnostic>>` with some handy shortcuts.
+pub trait ResultExt {
+ type Ok;
+
+ /// Behaves like `Result::unwrap`: if self is `Ok` yield the contained value,
+ /// otherwise abort macro execution via `abort!`.
+ fn unwrap_or_abort(self) -> Self::Ok;
+
+ /// Behaves like `Result::expect`: if self is `Ok` yield the contained value,
+ /// otherwise abort macro execution via `abort!`.
+ /// If it aborts then resulting error message will be preceded with `message`.
+ fn expect_or_abort(self, msg: &str) -> Self::Ok;
+}
+
+/// This traits expands `Option` with some handy shortcuts.
+pub trait OptionExt {
+ type Some;
+
+ /// Behaves like `Option::expect`: if self is `Some` yield the contained value,
+ /// otherwise abort macro execution via `abort_call_site!`.
+ /// If it aborts the `message` will be used for [`compile_error!`][compl_err] invocation.
+ ///
+ /// [compl_err]: https://doc.rust-lang.org/std/macro.compile_error.html
+ fn expect_or_abort(self, msg: &str) -> Self::Some;
+}
+
+/// Abort macro execution and display all the emitted errors, if any.
+///
+/// Does nothing if no errors were emitted (warnings do not count).
+pub fn abort_if_dirty() {
+ imp::abort_if_dirty();
+}
+
+impl<T, E: Into<Diagnostic>> ResultExt for Result<T, E> {
+ type Ok = T;
+
+ fn unwrap_or_abort(self) -> T {
+ match self {
+ Ok(res) => res,
+ Err(e) => e.into().abort(),
+ }
+ }
+
+ fn expect_or_abort(self, message: &str) -> T {
+ match self {
+ Ok(res) => res,
+ Err(e) => {
+ let mut e = e.into();
+ e.msg = format!("{}: {}", message, e.msg);
+ e.abort()
+ }
+ }
+ }
+}
+
+impl<T> OptionExt for Option<T> {
+ type Some = T;
+
+ fn expect_or_abort(self, message: &str) -> T {
+ match self {
+ Some(res) => res,
+ None => abort_call_site!(message),
+ }
+ }
+}
+
+/// This is the entry point for a proc-macro.
+///
+/// **NOT PUBLIC API, SUBJECT TO CHANGE WITHOUT ANY NOTICE**
+#[doc(hidden)]
+pub fn entry_point<F>(f: F, proc_macro_hack: bool) -> proc_macro::TokenStream
+where
+ F: FnOnce() -> proc_macro::TokenStream + UnwindSafe,
+{
+ ENTERED_ENTRY_POINT.with(|flag| flag.set(flag.get() + 1));
+ let caught = catch_unwind(f);
+ let dummy = dummy::cleanup();
+ let err_storage = imp::cleanup();
+ ENTERED_ENTRY_POINT.with(|flag| flag.set(flag.get() - 1));
+
+ let gen_error = || {
+ if proc_macro_hack {
+ quote! {{
+ macro_rules! proc_macro_call {
+ () => ( unimplemented!() )
+ }
+
+ #(#err_storage)*
+ #dummy
+
+ unimplemented!()
+ }}
+ } else {
+ quote!( #(#err_storage)* #dummy )
+ }
+ };
+
+ match caught {
+ Ok(ts) => {
+ if err_storage.is_empty() {
+ ts
+ } else {
+ gen_error().into()
+ }
+ }
+
+ Err(boxed) => match boxed.downcast::<AbortNow>() {
+ Ok(_) => gen_error().into(),
+ Err(boxed) => resume_unwind(boxed),
+ },
+ }
+}
+
+fn abort_now() -> ! {
+ check_correctness();
+ panic!(AbortNow)
+}
+
+thread_local! {
+ static ENTERED_ENTRY_POINT: Cell<usize> = Cell::new(0);
+}
+
+struct AbortNow;
+
+fn check_correctness() {
+ if ENTERED_ENTRY_POINT.with(|flag| flag.get()) == 0 {
+ panic!(
+ "proc-macro-error API cannot be used outside of `entry_point` invocation, \
+ perhaps you forgot to annotate your #[proc_macro] function with `#[proc_macro_error]"
+ );
+ }
+}
+
+/// **ALL THE STUFF INSIDE IS NOT PUBLIC API!!!**
+#[doc(hidden)]
+pub mod __export {
+ // reexports for use in macros
+ pub extern crate proc_macro;
+ pub extern crate proc_macro2;
+
+ use proc_macro2::Span;
+ use quote::ToTokens;
+
+ use crate::SpanRange;
+
+ // inspired by
+ // https://github.com/dtolnay/case-studies/blob/master/autoref-specialization/README.md#simple-application
+
+ pub trait SpanAsSpanRange {
+ #[allow(non_snake_case)]
+ fn FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange(&self) -> SpanRange;
+ }
+
+ pub trait Span2AsSpanRange {
+ #[allow(non_snake_case)]
+ fn FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange(&self) -> SpanRange;
+ }
+
+ pub trait ToTokensAsSpanRange {
+ #[allow(non_snake_case)]
+ fn FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange(&self) -> SpanRange;
+ }
+
+ pub trait SpanRangeAsSpanRange {
+ #[allow(non_snake_case)]
+ fn FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange(&self) -> SpanRange;
+ }
+
+ impl<T: ToTokens> ToTokensAsSpanRange for &T {
+ fn FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange(&self) -> SpanRange {
+ let mut ts = self.to_token_stream().into_iter();
+ let first = ts
+ .next()
+ .map(|tt| tt.span())
+ .unwrap_or_else(Span::call_site);
+ let last = ts.last().map(|tt| tt.span()).unwrap_or(first);
+ SpanRange { first, last }
+ }
+ }
+
+ impl Span2AsSpanRange for Span {
+ fn FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange(&self) -> SpanRange {
+ SpanRange {
+ first: *self,
+ last: *self,
+ }
+ }
+ }
+
+ impl SpanAsSpanRange for proc_macro::Span {
+ fn FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange(&self) -> SpanRange {
+ SpanRange {
+ first: self.clone().into(),
+ last: self.clone().into(),
+ }
+ }
+ }
+
+ impl SpanRangeAsSpanRange for SpanRange {
+ fn FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange(&self) -> SpanRange {
+ *self
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/src/macros.rs b/rust/hw/char/pl011/vendor/proc-macro-error/src/macros.rs
new file mode 100644
index 0000000000..747b684d56
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/src/macros.rs
@@ -0,0 +1,288 @@
+// FIXME: this can be greatly simplified via $()?
+// as soon as MRSV hits 1.32
+
+/// Build [`Diagnostic`](struct.Diagnostic.html) instance from provided arguments.
+///
+/// # Syntax
+///
+/// See [the guide](index.html#guide).
+///
+#[macro_export]
+macro_rules! diagnostic {
+ // from alias
+ ($err:expr) => { $crate::Diagnostic::from($err) };
+
+ // span, message, help
+ ($span:expr, $level:expr, $fmt:expr, $($args:expr),+ ; $($rest:tt)+) => {{
+ #[allow(unused_imports)]
+ use $crate::__export::{
+ ToTokensAsSpanRange,
+ Span2AsSpanRange,
+ SpanAsSpanRange,
+ SpanRangeAsSpanRange
+ };
+ use $crate::DiagnosticExt;
+ let span_range = (&$span).FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange();
+
+ let diag = $crate::Diagnostic::spanned_range(
+ span_range,
+ $level,
+ format!($fmt, $($args),*)
+ );
+ $crate::__pme__suggestions!(diag $($rest)*);
+ diag
+ }};
+
+ ($span:expr, $level:expr, $msg:expr ; $($rest:tt)+) => {{
+ #[allow(unused_imports)]
+ use $crate::__export::{
+ ToTokensAsSpanRange,
+ Span2AsSpanRange,
+ SpanAsSpanRange,
+ SpanRangeAsSpanRange
+ };
+ use $crate::DiagnosticExt;
+ let span_range = (&$span).FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange();
+
+ let diag = $crate::Diagnostic::spanned_range(span_range, $level, $msg.to_string());
+ $crate::__pme__suggestions!(diag $($rest)*);
+ diag
+ }};
+
+ // span, message, no help
+ ($span:expr, $level:expr, $fmt:expr, $($args:expr),+) => {{
+ #[allow(unused_imports)]
+ use $crate::__export::{
+ ToTokensAsSpanRange,
+ Span2AsSpanRange,
+ SpanAsSpanRange,
+ SpanRangeAsSpanRange
+ };
+ use $crate::DiagnosticExt;
+ let span_range = (&$span).FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange();
+
+ $crate::Diagnostic::spanned_range(
+ span_range,
+ $level,
+ format!($fmt, $($args),*)
+ )
+ }};
+
+ ($span:expr, $level:expr, $msg:expr) => {{
+ #[allow(unused_imports)]
+ use $crate::__export::{
+ ToTokensAsSpanRange,
+ Span2AsSpanRange,
+ SpanAsSpanRange,
+ SpanRangeAsSpanRange
+ };
+ use $crate::DiagnosticExt;
+ let span_range = (&$span).FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange();
+
+ $crate::Diagnostic::spanned_range(span_range, $level, $msg.to_string())
+ }};
+
+
+ // trailing commas
+
+ ($span:expr, $level:expr, $fmt:expr, $($args:expr),+, ; $($rest:tt)+) => {
+ $crate::diagnostic!($span, $level, $fmt, $($args),* ; $($rest)*)
+ };
+ ($span:expr, $level:expr, $msg:expr, ; $($rest:tt)+) => {
+ $crate::diagnostic!($span, $level, $msg ; $($rest)*)
+ };
+ ($span:expr, $level:expr, $fmt:expr, $($args:expr),+,) => {
+ $crate::diagnostic!($span, $level, $fmt, $($args),*)
+ };
+ ($span:expr, $level:expr, $msg:expr,) => {
+ $crate::diagnostic!($span, $level, $msg)
+ };
+ // ($err:expr,) => { $crate::diagnostic!($err) };
+}
+
+/// Abort proc-macro execution right now and display the error.
+///
+/// # Syntax
+///
+/// See [the guide](index.html#guide).
+#[macro_export]
+macro_rules! abort {
+ ($err:expr) => {
+ $crate::diagnostic!($err).abort()
+ };
+
+ ($span:expr, $($tts:tt)*) => {
+ $crate::diagnostic!($span, $crate::Level::Error, $($tts)*).abort()
+ };
+}
+
+/// Shortcut for `abort!(Span::call_site(), msg...)`. This macro
+/// is still preferable over plain panic, panics are not for error reporting.
+///
+/// # Syntax
+///
+/// See [the guide](index.html#guide).
+///
+#[macro_export]
+macro_rules! abort_call_site {
+ ($($tts:tt)*) => {
+ $crate::abort!($crate::__export::proc_macro2::Span::call_site(), $($tts)*)
+ };
+}
+
+/// Emit an error while not aborting the proc-macro right away.
+///
+/// # Syntax
+///
+/// See [the guide](index.html#guide).
+///
+#[macro_export]
+macro_rules! emit_error {
+ ($err:expr) => {
+ $crate::diagnostic!($err).emit()
+ };
+
+ ($span:expr, $($tts:tt)*) => {{
+ let level = $crate::Level::Error;
+ $crate::diagnostic!($span, level, $($tts)*).emit()
+ }};
+}
+
+/// Shortcut for `emit_error!(Span::call_site(), ...)`. This macro
+/// is still preferable over plain panic, panics are not for error reporting..
+///
+/// # Syntax
+///
+/// See [the guide](index.html#guide).
+///
+#[macro_export]
+macro_rules! emit_call_site_error {
+ ($($tts:tt)*) => {
+ $crate::emit_error!($crate::__export::proc_macro2::Span::call_site(), $($tts)*)
+ };
+}
+
+/// Emit a warning. Warnings are not errors and compilation won't fail because of them.
+///
+/// **Does nothing on stable**
+///
+/// # Syntax
+///
+/// See [the guide](index.html#guide).
+///
+#[macro_export]
+macro_rules! emit_warning {
+ ($span:expr, $($tts:tt)*) => {
+ $crate::diagnostic!($span, $crate::Level::Warning, $($tts)*).emit()
+ };
+}
+
+/// Shortcut for `emit_warning!(Span::call_site(), ...)`.
+///
+/// **Does nothing on stable**
+///
+/// # Syntax
+///
+/// See [the guide](index.html#guide).
+///
+#[macro_export]
+macro_rules! emit_call_site_warning {
+ ($($tts:tt)*) => {{
+ $crate::emit_warning!($crate::__export::proc_macro2::Span::call_site(), $($tts)*)
+ }};
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pme__suggestions {
+ ($var:ident) => ();
+
+ ($var:ident $help:ident =? $msg:expr) => {
+ let $var = if let Some(msg) = $msg {
+ $var.suggestion(stringify!($help), msg.to_string())
+ } else {
+ $var
+ };
+ };
+ ($var:ident $help:ident =? $span:expr => $msg:expr) => {
+ let $var = if let Some(msg) = $msg {
+ $var.span_suggestion($span.into(), stringify!($help), msg.to_string())
+ } else {
+ $var
+ };
+ };
+
+ ($var:ident $help:ident =? $msg:expr ; $($rest:tt)*) => {
+ $crate::__pme__suggestions!($var $help =? $msg);
+ $crate::__pme__suggestions!($var $($rest)*);
+ };
+ ($var:ident $help:ident =? $span:expr => $msg:expr ; $($rest:tt)*) => {
+ $crate::__pme__suggestions!($var $help =? $span => $msg);
+ $crate::__pme__suggestions!($var $($rest)*);
+ };
+
+
+ ($var:ident $help:ident = $msg:expr) => {
+ let $var = $var.suggestion(stringify!($help), $msg.to_string());
+ };
+ ($var:ident $help:ident = $fmt:expr, $($args:expr),+) => {
+ let $var = $var.suggestion(
+ stringify!($help),
+ format!($fmt, $($args),*)
+ );
+ };
+ ($var:ident $help:ident = $span:expr => $msg:expr) => {
+ let $var = $var.span_suggestion($span.into(), stringify!($help), $msg.to_string());
+ };
+ ($var:ident $help:ident = $span:expr => $fmt:expr, $($args:expr),+) => {
+ let $var = $var.span_suggestion(
+ $span.into(),
+ stringify!($help),
+ format!($fmt, $($args),*)
+ );
+ };
+
+ ($var:ident $help:ident = $msg:expr ; $($rest:tt)*) => {
+ $crate::__pme__suggestions!($var $help = $msg);
+ $crate::__pme__suggestions!($var $($rest)*);
+ };
+ ($var:ident $help:ident = $fmt:expr, $($args:expr),+ ; $($rest:tt)*) => {
+ $crate::__pme__suggestions!($var $help = $fmt, $($args),*);
+ $crate::__pme__suggestions!($var $($rest)*);
+ };
+ ($var:ident $help:ident = $span:expr => $msg:expr ; $($rest:tt)*) => {
+ $crate::__pme__suggestions!($var $help = $span => $msg);
+ $crate::__pme__suggestions!($var $($rest)*);
+ };
+ ($var:ident $help:ident = $span:expr => $fmt:expr, $($args:expr),+ ; $($rest:tt)*) => {
+ $crate::__pme__suggestions!($var $help = $span => $fmt, $($args),*);
+ $crate::__pme__suggestions!($var $($rest)*);
+ };
+
+ // trailing commas
+
+ ($var:ident $help:ident = $msg:expr,) => {
+ $crate::__pme__suggestions!($var $help = $msg)
+ };
+ ($var:ident $help:ident = $fmt:expr, $($args:expr),+,) => {
+ $crate::__pme__suggestions!($var $help = $fmt, $($args)*)
+ };
+ ($var:ident $help:ident = $span:expr => $msg:expr,) => {
+ $crate::__pme__suggestions!($var $help = $span => $msg)
+ };
+ ($var:ident $help:ident = $span:expr => $fmt:expr, $($args:expr),*,) => {
+ $crate::__pme__suggestions!($var $help = $span => $fmt, $($args)*)
+ };
+ ($var:ident $help:ident = $msg:expr, ; $($rest:tt)*) => {
+ $crate::__pme__suggestions!($var $help = $msg; $($rest)*)
+ };
+ ($var:ident $help:ident = $fmt:expr, $($args:expr),+, ; $($rest:tt)*) => {
+ $crate::__pme__suggestions!($var $help = $fmt, $($args),*; $($rest)*)
+ };
+ ($var:ident $help:ident = $span:expr => $msg:expr, ; $($rest:tt)*) => {
+ $crate::__pme__suggestions!($var $help = $span => $msg; $($rest)*)
+ };
+ ($var:ident $help:ident = $span:expr => $fmt:expr, $($args:expr),+, ; $($rest:tt)*) => {
+ $crate::__pme__suggestions!($var $help = $span => $fmt, $($args),*; $($rest)*)
+ };
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/src/sealed.rs b/rust/hw/char/pl011/vendor/proc-macro-error/src/sealed.rs
new file mode 100644
index 0000000000..a2d5081e55
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/src/sealed.rs
@@ -0,0 +1,3 @@
+pub trait Sealed {}
+
+impl Sealed for crate::Diagnostic {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/macro-errors.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/macro-errors.rs
new file mode 100644
index 0000000000..dd60f88a80
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/macro-errors.rs
@@ -0,0 +1,8 @@
+extern crate trybuild;
+
+#[cfg_attr(skip_ui_tests, ignore)]
+#[test]
+fn ui() {
+ let t = trybuild::TestCases::new();
+ t.compile_fail("tests/ui/*.rs");
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ok.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ok.rs
new file mode 100644
index 0000000000..cf64c027f8
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ok.rs
@@ -0,0 +1,10 @@
+extern crate test_crate;
+
+use test_crate::*;
+
+ok!(it_works);
+
+#[test]
+fn check_it_works() {
+ it_works();
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/runtime-errors.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/runtime-errors.rs
new file mode 100644
index 0000000000..13108a2d91
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/runtime-errors.rs
@@ -0,0 +1,13 @@
+use proc_macro_error::*;
+
+#[test]
+#[should_panic = "proc-macro-error API cannot be used outside of"]
+fn missing_attr_emit() {
+ emit_call_site_error!("You won't see me");
+}
+
+#[test]
+#[should_panic = "proc-macro-error API cannot be used outside of"]
+fn missing_attr_abort() {
+ abort_call_site!("You won't see me");
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.rs
new file mode 100644
index 0000000000..f63118251e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.rs
@@ -0,0 +1,11 @@
+extern crate test_crate;
+use test_crate::*;
+
+abort_from!(one, two);
+abort_to_string!(one, two);
+abort_format!(one, two);
+direct_abort!(one, two);
+abort_notes!(one, two);
+abort_call_site_test!(one, two);
+
+fn main() {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.stderr
new file mode 100644
index 0000000000..c5399d9d91
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.stderr
@@ -0,0 +1,48 @@
+error: abort!(span, from) test
+ --> $DIR/abort.rs:4:13
+ |
+4 | abort_from!(one, two);
+ | ^^^
+
+error: abort!(span, single_expr) test
+ --> $DIR/abort.rs:5:18
+ |
+5 | abort_to_string!(one, two);
+ | ^^^
+
+error: abort!(span, expr1, expr2) test
+ --> $DIR/abort.rs:6:15
+ |
+6 | abort_format!(one, two);
+ | ^^^
+
+error: Diagnostic::abort() test
+ --> $DIR/abort.rs:7:15
+ |
+7 | direct_abort!(one, two);
+ | ^^^
+
+error: This is an error
+
+ = note: simple note
+ = help: simple help
+ = help: simple hint
+ = note: simple yay
+ = note: format note
+ = note: Some note
+ = note: spanned simple note
+ = note: spanned format note
+ = note: Some note
+
+ --> $DIR/abort.rs:8:14
+ |
+8 | abort_notes!(one, two);
+ | ^^^
+
+error: abort_call_site! test
+ --> $DIR/abort.rs:9:1
+ |
+9 | abort_call_site_test!(one, two);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.rs
new file mode 100644
index 0000000000..53d6feacc1
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.rs
@@ -0,0 +1,13 @@
+extern crate test_crate;
+use test_crate::*;
+
+enum NeedDefault {
+ A,
+ B
+}
+
+append_dummy!(need_default);
+
+fn main() {
+ let _ = NeedDefault::default();
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.stderr
new file mode 100644
index 0000000000..8a47ddaac4
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.stderr
@@ -0,0 +1,5 @@
+error: append_dummy test
+ --> $DIR/append_dummy.rs:9:15
+ |
+9 | append_dummy!(need_default);
+ | ^^^^^^^^^^^^
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.rs
new file mode 100644
index 0000000000..fb9e6dc697
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.rs
@@ -0,0 +1,6 @@
+extern crate test_crate;
+use test_crate::*;
+
+children_messages!(one, two, three, four);
+
+fn main() {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.stderr
new file mode 100644
index 0000000000..3b49d83165
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.stderr
@@ -0,0 +1,23 @@
+error: main macro message
+ --> $DIR/children_messages.rs:4:20
+ |
+4 | children_messages!(one, two, three, four);
+ | ^^^
+
+error: child message
+ --> $DIR/children_messages.rs:4:25
+ |
+4 | children_messages!(one, two, three, four);
+ | ^^^
+
+error: main syn::Error
+ --> $DIR/children_messages.rs:4:30
+ |
+4 | children_messages!(one, two, three, four);
+ | ^^^^^
+
+error: child syn::Error
+ --> $DIR/children_messages.rs:4:37
+ |
+4 | children_messages!(one, two, three, four);
+ | ^^^^
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.rs
new file mode 100644
index 0000000000..caa4827886
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.rs
@@ -0,0 +1,13 @@
+extern crate test_crate;
+use test_crate::*;
+
+enum NeedDefault {
+ A,
+ B
+}
+
+dummy!(need_default);
+
+fn main() {
+ let _ = NeedDefault::default();
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.stderr
new file mode 100644
index 0000000000..bae078afa8
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.stderr
@@ -0,0 +1,5 @@
+error: set_dummy test
+ --> $DIR/dummy.rs:9:8
+ |
+9 | dummy!(need_default);
+ | ^^^^^^^^^^^^
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.rs
new file mode 100644
index 0000000000..c5c7db095f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.rs
@@ -0,0 +1,7 @@
+extern crate test_crate;
+use test_crate::*;
+
+emit!(one, two, three, four, five);
+emit_notes!(one, two);
+
+fn main() {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.stderr
new file mode 100644
index 0000000000..9484bd628b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.stderr
@@ -0,0 +1,48 @@
+error: emit!(span, from) test
+ --> $DIR/emit.rs:4:7
+ |
+4 | emit!(one, two, three, four, five);
+ | ^^^
+
+error: emit!(span, expr1, expr2) test
+ --> $DIR/emit.rs:4:12
+ |
+4 | emit!(one, two, three, four, five);
+ | ^^^
+
+error: emit!(span, single_expr) test
+ --> $DIR/emit.rs:4:17
+ |
+4 | emit!(one, two, three, four, five);
+ | ^^^^^
+
+error: Diagnostic::emit() test
+ --> $DIR/emit.rs:4:24
+ |
+4 | emit!(one, two, three, four, five);
+ | ^^^^
+
+error: emit_call_site_error!(expr) test
+ --> $DIR/emit.rs:4:1
+ |
+4 | emit!(one, two, three, four, five);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: This is an error
+
+ = note: simple note
+ = help: simple help
+ = help: simple hint
+ = note: simple yay
+ = note: format note
+ = note: Some note
+ = note: spanned simple note
+ = note: spanned format note
+ = note: Some note
+
+ --> $DIR/emit.rs:5:13
+ |
+5 | emit_notes!(one, two);
+ | ^^^
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.rs
new file mode 100644
index 0000000000..82bbebcc55
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.rs
@@ -0,0 +1,6 @@
+extern crate test_crate;
+use test_crate::*;
+
+explicit_span_range!(one, two, three, four);
+
+fn main() {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.stderr
new file mode 100644
index 0000000000..781a71e76a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.stderr
@@ -0,0 +1,5 @@
+error: explicit SpanRange
+ --> $DIR/explicit_span_range.rs:4:22
+ |
+4 | explicit_span_range!(one, two, three, four);
+ | ^^^^^^^^^^^^^^^
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.rs
new file mode 100644
index 0000000000..e6d2d24971
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.rs
@@ -0,0 +1,11 @@
+extern crate proc_macro_error;
+use proc_macro_error::abort;
+
+struct Foo;
+
+#[allow(unused)]
+fn foo() {
+ abort!(Foo, "BOOM");
+}
+
+fn main() {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.stderr
new file mode 100644
index 0000000000..8eaf6456fd
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.stderr
@@ -0,0 +1,13 @@
+error[E0599]: no method named `FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange` found for reference `&Foo` in the current scope
+ --> $DIR/misuse.rs:8:5
+ |
+4 | struct Foo;
+ | ----------- doesn't satisfy `Foo: quote::to_tokens::ToTokens`
+...
+8 | abort!(Foo, "BOOM");
+ | ^^^^^^^^^^^^^^^^^^^^ method not found in `&Foo`
+ |
+ = note: the method `FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange` exists but the following trait bounds were not satisfied:
+ `Foo: quote::to_tokens::ToTokens`
+ which is required by `&Foo: proc_macro_error::__export::ToTokensAsSpanRange`
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.rs
new file mode 100644
index 0000000000..215928f6f4
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.rs
@@ -0,0 +1,6 @@
+extern crate test_crate;
+
+#[test_crate::multiple_tokens]
+type T = ();
+
+fn main() {}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.stderr
new file mode 100644
index 0000000000..c6172c6cc6
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.stderr
@@ -0,0 +1,5 @@
+error: ...
+ --> $DIR/multiple_tokens.rs:4:1
+ |
+4 | type T = ();
+ | ^^^^^^^^^^^^
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.rs
new file mode 100644
index 0000000000..e241c5cd28
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.rs
@@ -0,0 +1,4 @@
+use proc_macro_error::proc_macro_error;
+
+#[proc_macro_error]
+fn main() {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.stderr
new file mode 100644
index 0000000000..f19f01bd8e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.stderr
@@ -0,0 +1,10 @@
+error: #[proc_macro_error] attribute can be used only with procedural macros
+
+ = hint: if you are really sure that #[proc_macro_error] should be applied to this exact function, use #[proc_macro_error(allow_not_macro)]
+
+ --> $DIR/not_proc_macro.rs:3:1
+ |
+3 | #[proc_macro_error]
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.rs
new file mode 100644
index 0000000000..dfbfc03835
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.rs
@@ -0,0 +1,6 @@
+extern crate test_crate;
+use test_crate::*;
+
+option_ext!(one, two);
+
+fn main() {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.stderr
new file mode 100644
index 0000000000..91b151ec2f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.stderr
@@ -0,0 +1,7 @@
+error: Option::expect_or_abort() test
+ --> $DIR/option_ext.rs:4:1
+ |
+4 | option_ext!(one, two);
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.rs
new file mode 100644
index 0000000000..2504bdd401
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.rs
@@ -0,0 +1,10 @@
+// Adapted from https://github.com/dtolnay/proc-macro-hack/blob/master/example/src/main.rs
+// Licensed under either of Apache License, Version 2.0 or MIT license at your option.
+
+use proc_macro_hack_test::add_one;
+
+fn main() {
+ let two = 2;
+ let nine = add_one!(two) + add_one!(2 + 3);
+ println!("nine = {}", nine);
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.stderr
new file mode 100644
index 0000000000..0e984f918d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.stderr
@@ -0,0 +1,26 @@
+error: BOOM
+ --> $DIR/proc_macro_hack.rs:8:25
+ |
+8 | let nine = add_one!(two) + add_one!(2 + 3);
+ | ^^^
+ |
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: BOOM
+ --> $DIR/proc_macro_hack.rs:8:41
+ |
+8 | let nine = add_one!(two) + add_one!(2 + 3);
+ | ^^^^^
+ |
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: unreachable expression
+ --> $DIR/proc_macro_hack.rs:8:32
+ |
+8 | let nine = add_one!(two) + add_one!(2 + 3);
+ | ------------- ^^^^^^^^^^^^^^^ unreachable expression
+ | |
+ | any code following this expression is unreachable
+ |
+ = note: `#[warn(unreachable_code)]` on by default
+ = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.rs
new file mode 100644
index 0000000000..bdd560dba9
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.rs
@@ -0,0 +1,7 @@
+extern crate test_crate;
+use test_crate::*;
+
+result_unwrap_or_abort!(one, two);
+result_expect_or_abort!(one, two);
+
+fn main() {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.stderr
new file mode 100644
index 0000000000..f2dc0e4235
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.stderr
@@ -0,0 +1,11 @@
+error: Result::unwrap_or_abort() test
+ --> $DIR/result_ext.rs:4:25
+ |
+4 | result_unwrap_or_abort!(one, two);
+ | ^^^
+
+error: BOOM: Result::expect_or_abort() test
+ --> $DIR/result_ext.rs:5:25
+ |
+5 | result_expect_or_abort!(one, two);
+ | ^^^
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.rs
new file mode 100644
index 0000000000..a7c3fc976c
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.rs
@@ -0,0 +1,6 @@
+extern crate test_crate;
+use test_crate::*;
+
+to_tokens_span!(std::option::Option);
+
+fn main() {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.stderr
new file mode 100644
index 0000000000..b8c4968263
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.stderr
@@ -0,0 +1,11 @@
+error: whole type
+ --> $DIR/to_tokens_span.rs:4:17
+ |
+4 | to_tokens_span!(std::option::Option);
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: explicit .span()
+ --> $DIR/to_tokens_span.rs:4:17
+ |
+4 | to_tokens_span!(std::option::Option);
+ | ^^^
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.rs
new file mode 100644
index 0000000000..d8e58eaf87
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.rs
@@ -0,0 +1,4 @@
+use proc_macro_error::proc_macro_error;
+
+#[proc_macro_error(allow_not_macro, assert_unwind_safe, trololo)]
+fn main() {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.stderr
new file mode 100644
index 0000000000..a55de0b31b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.stderr
@@ -0,0 +1,5 @@
+error: unknown setting `trololo`, expected one of `assert_unwind_safe`, `allow_not_macro`, `proc_macro_hack`
+ --> $DIR/unknown_setting.rs:3:57
+ |
+3 | #[proc_macro_error(allow_not_macro, assert_unwind_safe, trololo)]
+ | ^^^^^^^
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.rs b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.rs
new file mode 100644
index 0000000000..c74e3e0623
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.rs
@@ -0,0 +1,6 @@
+extern crate test_crate;
+use test_crate::*;
+
+unrelated_panic!();
+
+fn main() {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.stderr b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.stderr
new file mode 100644
index 0000000000..d46d689f2f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.stderr
@@ -0,0 +1,7 @@
+error: proc macro panicked
+ --> $DIR/unrelated_panic.rs:4:1
+ |
+4 | unrelated_panic!();
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: message: unrelated panic test
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/.cargo-checksum.json b/rust/hw/char/pl011/vendor/proc-macro2/.cargo-checksum.json
new file mode 100644
index 0000000000..83f4c8a5ec
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"cdfebba5c7483fd052619894a923bd5aa5959a0fcfd7a2fc7e695c6a6231e87a","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"c609b6865476d6c35879784e9155367a97a0da496aa5c3c61488440a20f59883","build.rs":"c385804afdf08a6292ed1f44afec6cfd0d9600410030ab5dc5bba842fbf0b6b3","build/probe.rs":"971fd2178dc506ccdc5c2065c37b77696a4aee8e00330ca52625db4a857f68d3","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/detection.rs":"ed9a5f9a979ab01247d7a68eeb1afa3c13209334c5bfff0f9289cb07e5bb4e8b","src/extra.rs":"29f094473279a29b71c3cc9f5fa27c2e2c30c670390cf7e4b7cf451486cc857e","src/fallback.rs":"be1ce5e32c88c29d41d2ab663375951817d52decce3dc9e335ec22378be8fa65","src/lib.rs":"4bd042e054d240332664d67f537419a4fa5e29a4c020d1fac3b6f1f58378ae49","src/location.rs":"9225c5a55f03b56cce42bc55ceb509e8216a5e0b24c94aa1cd071b04e3d6c15f","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":"2e7106f582367d168638be7364d4e9aadbe0affca8b51dd80f0b3977cc2fcf83","tests/test_fmt.rs":"b7743b612af65f2c88cbe109d50a093db7aa7e87f9e37bf45b7bbaeb240aa020","tests/test_size.rs":"08fb1d6bcf867707dfa18d30fceb18c58e8c44c89e058d8d6bfd2b281c77e14e"},"package":"ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6"}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/Cargo.toml b/rust/hw/char/pl011/vendor/proc-macro2/Cargo.toml
new file mode 100644
index 0000000000..193a898a8c
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/Cargo.toml
@@ -0,0 +1,104 @@
+# 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.56"
+name = "proc-macro2"
+version = "1.0.84"
+authors = [
+ "David Tolnay <dtolnay@gmail.com>",
+ "Alex Crichton <alex@alexcrichton.com>",
+]
+build = "build.rs"
+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"
+readme = "README.md"
+keywords = [
+ "macros",
+ "syn",
+]
+categories = ["development-tools::procedural-macro-helpers"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/dtolnay/proc-macro2"
+
+[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"]
+
+[lib]
+name = "proc_macro2"
+path = "src/lib.rs"
+doc-scrape-examples = false
+
+[[test]]
+name = "comments"
+path = "tests/comments.rs"
+
+[[test]]
+name = "test_fmt"
+path = "tests/test_fmt.rs"
+
+[[test]]
+name = "features"
+path = "tests/features.rs"
+
+[[test]]
+name = "marker"
+path = "tests/marker.rs"
+
+[[test]]
+name = "test_size"
+path = "tests/test_size.rs"
+
+[[test]]
+name = "test"
+path = "tests/test.rs"
+
+[dependencies.unicode-ident]
+version = "1.0"
+
+[dev-dependencies.flate2]
+version = "1.0"
+
+[dev-dependencies.quote]
+version = "1.0"
+default-features = false
+
+[dev-dependencies.rayon]
+version = "1.0"
+
+[dev-dependencies.rustversion]
+version = "1"
+
+[dev-dependencies.tar]
+version = "0.4"
+
+[features]
+default = ["proc-macro"]
+nightly = []
+proc-macro = []
+span-locations = []
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/LICENSE-APACHE b/rust/hw/char/pl011/vendor/proc-macro2/LICENSE-APACHE
new file mode 100644
index 0000000000..1b5ec8b78e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/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/rust/hw/char/pl011/vendor/proc-macro2/LICENSE-MIT b/rust/hw/char/pl011/vendor/proc-macro2/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/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/rust/hw/char/pl011/vendor/proc-macro2/README.md b/rust/hw/char/pl011/vendor/proc-macro2/README.md
new file mode 100644
index 0000000000..3a29ce8b89
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/README.md
@@ -0,0 +1,94 @@
+# proc-macro2
+
+[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/proc--macro2-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/proc-macro2)
+[<img alt="crates.io" src="https://img.shields.io/crates/v/proc-macro2.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/proc-macro2)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-proc--macro2-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/proc-macro2)
+[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/proc-macro2/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/proc-macro2/actions?query=branch%3Amaster)
+
+A wrapper around the procedural macro API of the compiler's `proc_macro` crate.
+This library serves two purposes:
+
+- **Bring proc-macro-like functionality to other contexts like build.rs and
+ main.rs.** Types from `proc_macro` are entirely specific to procedural macros
+ and cannot ever exist in code outside of a procedural macro. Meanwhile
+ `proc_macro2` types may exist anywhere including non-macro code. By developing
+ foundational libraries like [syn] and [quote] against `proc_macro2` rather
+ than `proc_macro`, the procedural macro ecosystem becomes easily applicable to
+ many other use cases and we avoid reimplementing non-macro equivalents of
+ those libraries.
+
+- **Make procedural macros unit testable.** As a consequence of being specific
+ to procedural macros, nothing that uses `proc_macro` can be executed from a
+ unit test. In order for helper libraries or components of a macro to be
+ testable in isolation, they must be implemented using `proc_macro2`.
+
+[syn]: https://github.com/dtolnay/syn
+[quote]: https://github.com/dtolnay/quote
+
+## Usage
+
+```toml
+[dependencies]
+proc-macro2 = "1.0"
+```
+
+The skeleton of a typical procedural macro typically looks like this:
+
+```rust
+extern crate proc_macro;
+
+#[proc_macro_derive(MyDerive)]
+pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+ let input = proc_macro2::TokenStream::from(input);
+
+ let output: proc_macro2::TokenStream = {
+ /* transform input */
+ };
+
+ proc_macro::TokenStream::from(output)
+}
+```
+
+If parsing with [Syn], you'll use [`parse_macro_input!`] instead to propagate
+parse errors correctly back to the compiler when parsing fails.
+
+[`parse_macro_input!`]: https://docs.rs/syn/2.0/syn/macro.parse_macro_input.html
+
+## Unstable features
+
+The default feature set of proc-macro2 tracks the most recent stable compiler
+API. Functionality in `proc_macro` that is not yet stable is not exposed by
+proc-macro2 by default.
+
+To opt into the additional APIs available in the most recent nightly compiler,
+the `procmacro2_semver_exempt` config flag must be passed to rustc. We will
+polyfill those nightly-only APIs back to Rust 1.56.0. As these are unstable APIs
+that track the nightly compiler, minor versions of proc-macro2 may make breaking
+changes to them at any time.
+
+```
+RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build
+```
+
+Note that this must not only be done for your crate, but for any crate that
+depends on your crate. This infectious nature is intentional, as it serves as a
+reminder that you are outside of the normal semver guarantees.
+
+Semver exempt methods are marked as such in the proc-macro2 documentation.
+
+<br>
+
+#### License
+
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
+
+<br>
+
+<sub>
+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.
+</sub>
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/build.rs b/rust/hw/char/pl011/vendor/proc-macro2/build.rs
new file mode 100644
index 0000000000..0a95c22661
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/build.rs
@@ -0,0 +1,227 @@
+// 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::iter;
+use std::path::Path;
+use std::process::{self, Command, Stdio};
+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 {
+ // https://github.com/dtolnay/proc-macro2/issues/147
+ println!("cargo:rustc-cfg=procmacro2_semver_exempt");
+ }
+
+ if semver_exempt || cfg!(feature = "span-locations") {
+ println!("cargo:rustc-cfg=span_locations");
+ }
+
+ if rustc < 57 {
+ println!("cargo:rustc-cfg=no_is_available");
+ }
+
+ if rustc < 66 {
+ println!("cargo:rustc-cfg=no_source_text");
+ }
+
+ if rustc < 79 {
+ println!("cargo:rustc-cfg=no_literal_byte_character");
+ println!("cargo:rustc-cfg=no_literal_c_string");
+ }
+
+ if !cfg!(feature = "proc-macro") {
+ println!("cargo:rerun-if-changed=build.rs");
+ return;
+ }
+
+ println!("cargo:rerun-if-changed=build/probe.rs");
+
+ let proc_macro_span;
+ let consider_rustc_bootstrap;
+ if compile_probe(false) {
+ // This is a nightly or dev compiler, so it supports unstable features
+ // regardless of RUSTC_BOOTSTRAP. No need to rerun build script if
+ // RUSTC_BOOTSTRAP is changed.
+ proc_macro_span = true;
+ consider_rustc_bootstrap = false;
+ } else if let Some(rustc_bootstrap) = env::var_os("RUSTC_BOOTSTRAP") {
+ if compile_probe(true) {
+ // This is a stable or beta compiler for which the user has set
+ // RUSTC_BOOTSTRAP to turn on unstable features. Rerun build script
+ // if they change it.
+ proc_macro_span = true;
+ consider_rustc_bootstrap = true;
+ } else if rustc_bootstrap == "1" {
+ // This compiler does not support the proc macro Span API in the
+ // form that proc-macro2 expects. No need to pay attention to
+ // RUSTC_BOOTSTRAP.
+ proc_macro_span = false;
+ consider_rustc_bootstrap = false;
+ } else {
+ // This is a stable or beta compiler for which RUSTC_BOOTSTRAP is
+ // set to restrict the use of unstable features by this crate.
+ proc_macro_span = false;
+ consider_rustc_bootstrap = true;
+ }
+ } else {
+ // Without RUSTC_BOOTSTRAP, this compiler does not support the proc
+ // macro Span API in the form that proc-macro2 expects, but try again if
+ // the user turns on unstable features.
+ proc_macro_span = false;
+ consider_rustc_bootstrap = true;
+ }
+
+ if proc_macro_span || !semver_exempt {
+ println!("cargo:rustc-cfg=wrap_proc_macro");
+ }
+
+ if proc_macro_span {
+ println!("cargo:rustc-cfg=proc_macro_span");
+ }
+
+ if semver_exempt && proc_macro_span {
+ println!("cargo:rustc-cfg=super_unstable");
+ }
+
+ if consider_rustc_bootstrap {
+ println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP");
+ }
+}
+
+fn compile_probe(rustc_bootstrap: bool) -> bool {
+ if env::var_os("RUSTC_STAGE").is_some() {
+ // We are running inside rustc bootstrap. This is a highly non-standard
+ // environment with issues such as:
+ //
+ // https://github.com/rust-lang/cargo/issues/11138
+ // https://github.com/rust-lang/rust/issues/114839
+ //
+ // Let's just not use nightly features here.
+ return false;
+ }
+
+ let rustc = cargo_env_var("RUSTC");
+ let out_dir = cargo_env_var("OUT_DIR");
+ let probefile = Path::new("build").join("probe.rs");
+
+ 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());
+ let mut rustc = rustc_wrapper
+ .into_iter()
+ .chain(rustc_workspace_wrapper)
+ .chain(iter::once(rustc));
+ let mut cmd = Command::new(rustc.next().unwrap());
+ cmd.args(rustc);
+
+ if !rustc_bootstrap {
+ cmd.env_remove("RUSTC_BOOTSTRAP");
+ }
+
+ cmd.stderr(Stdio::null())
+ .arg("--edition=2021")
+ .arg("--crate-name=proc_macro2")
+ .arg("--crate-type=lib")
+ .arg("--cap-lints=allow")
+ .arg("--emit=dep-info,metadata")
+ .arg("--out-dir")
+ .arg(out_dir)
+ .arg(probefile);
+
+ if let Some(target) = env::var_os("TARGET") {
+ cmd.arg("--target").arg(target);
+ }
+
+ // If Cargo wants to set RUSTFLAGS, use that.
+ if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") {
+ if !rustflags.is_empty() {
+ for arg in rustflags.split('\x1f') {
+ cmd.arg(arg);
+ }
+ }
+ }
+
+ match cmd.status() {
+ Ok(status) => status.success(),
+ Err(_) => false,
+ }
+}
+
+fn rustc_minor_version() -> Option<u32> {
+ let rustc = cargo_env_var("RUSTC");
+ let output = Command::new(rustc).arg("--version").output().ok()?;
+ let version = str::from_utf8(&output.stdout).ok()?;
+ let mut pieces = version.split('.');
+ if pieces.next() != Some("rustc 1") {
+ return None;
+ }
+ pieces.next()?.parse().ok()
+}
+
+fn cargo_env_var(key: &str) -> OsString {
+ env::var_os(key).unwrap_or_else(|| {
+ eprintln!(
+ "Environment variable ${} is not set during execution of build script",
+ key,
+ );
+ process::exit(1);
+ })
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/build/probe.rs b/rust/hw/char/pl011/vendor/proc-macro2/build/probe.rs
new file mode 100644
index 0000000000..2c4947a0b8
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/build/probe.rs
@@ -0,0 +1,25 @@
+// This code exercises the surface area that we expect of Span's unstable API.
+// If the current toolchain is able to compile it, then proc-macro2 is able to
+// offer these APIs too.
+
+#![feature(proc_macro_span)]
+
+extern crate proc_macro;
+
+use core::ops::{Range, RangeBounds};
+use proc_macro::{Literal, Span};
+
+pub fn byte_range(this: &Span) -> Range<usize> {
+ this.byte_range()
+}
+
+pub fn join(this: &Span, other: Span) -> Option<Span> {
+ this.join(other)
+}
+
+pub fn subspan<R: RangeBounds<usize>>(this: &Literal, range: R) -> Option<Span> {
+ this.subspan(range)
+}
+
+// Include in sccache cache key.
+const _: Option<&str> = option_env!("RUSTC_BOOTSTRAP");
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/meson.build b/rust/hw/char/pl011/vendor/proc-macro2/meson.build
new file mode 100644
index 0000000000..2a97df4a70
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/meson.build
@@ -0,0 +1,19 @@
+_proc_macro2_rs = static_library(
+ 'proc_macro2',
+ files('src/lib.rs'),
+ gnu_symbol_visibility: 'hidden',
+ rust_abi: 'rust',
+ rust_args: rust_args + [
+ '--edition', '2021',
+ '--cfg', 'feature="proc-macro"',
+ '--cfg', 'span_locations',
+ '--cfg', 'wrap_proc_macro',
+ ],
+ dependencies: [
+ dep_unicode_ident,
+ ],
+)
+
+dep_proc_macro2 = declare_dependency(
+ link_with: _proc_macro2_rs,
+)
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/rust-toolchain.toml b/rust/hw/char/pl011/vendor/proc-macro2/rust-toolchain.toml
new file mode 100644
index 0000000000..20fe888c30
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/rust-toolchain.toml
@@ -0,0 +1,2 @@
+[toolchain]
+components = ["rust-src"]
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/src/detection.rs b/rust/hw/char/pl011/vendor/proc-macro2/src/detection.rs
new file mode 100644
index 0000000000..beba7b2373
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/src/detection.rs
@@ -0,0 +1,75 @@
+use core::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::Once;
+
+static WORKS: AtomicUsize = AtomicUsize::new(0);
+static INIT: Once = Once::new();
+
+pub(crate) fn inside_proc_macro() -> bool {
+ match WORKS.load(Ordering::Relaxed) {
+ 1 => return false,
+ 2 => return true,
+ _ => {}
+ }
+
+ INIT.call_once(initialize);
+ inside_proc_macro()
+}
+
+pub(crate) fn force_fallback() {
+ WORKS.store(1, Ordering::Relaxed);
+}
+
+pub(crate) fn unforce_fallback() {
+ initialize();
+}
+
+#[cfg(not(no_is_available))]
+fn initialize() {
+ let available = proc_macro::is_available();
+ WORKS.store(available as usize + 1, Ordering::Relaxed);
+}
+
+// Swap in a null panic hook to avoid printing "thread panicked" to stderr,
+// then use catch_unwind to determine whether the compiler's proc_macro is
+// working. When proc-macro2 is used from outside of a procedural macro all
+// of the proc_macro crate's APIs currently panic.
+//
+// The Once is to prevent the possibility of this ordering:
+//
+// thread 1 calls take_hook, gets the user's original hook
+// thread 1 calls set_hook with the null hook
+// thread 2 calls take_hook, thinks null hook is the original hook
+// thread 2 calls set_hook with the null hook
+// thread 1 calls set_hook with the actual original hook
+// thread 2 calls set_hook with what it thinks is the original hook
+//
+// in which the user's hook has been lost.
+//
+// There is still a race condition where a panic in a different thread can
+// happen during the interval that the user's original panic hook is
+// unregistered such that their hook is incorrectly not called. This is
+// sufficiently unlikely and less bad than printing panic messages to stderr
+// on correct use of this crate. Maybe there is a libstd feature request
+// here. For now, if a user needs to guarantee that this failure mode does
+// not occur, they need to call e.g. `proc_macro2::Span::call_site()` from
+// the main thread before launching any other threads.
+#[cfg(no_is_available)]
+fn initialize() {
+ use std::panic::{self, PanicInfo};
+
+ type PanicHook = dyn Fn(&PanicInfo) + Sync + Send + 'static;
+
+ let null_hook: Box<PanicHook> = Box::new(|_panic_info| { /* ignore */ });
+ let sanity_check = &*null_hook as *const PanicHook;
+ let original_hook = panic::take_hook();
+ panic::set_hook(null_hook);
+
+ let works = panic::catch_unwind(proc_macro::Span::call_site).is_ok();
+ WORKS.store(works as usize + 1, Ordering::Relaxed);
+
+ let hopefully_null_hook = panic::take_hook();
+ panic::set_hook(original_hook);
+ if sanity_check != &*hopefully_null_hook {
+ panic!("observed race condition in proc_macro2::inside_proc_macro");
+ }
+}
--git a/rust/hw/char/pl011/vendor/proc-macro2/src/extra.rs b/rust/hw/char/pl011/vendor/proc-macro2/src/extra.rs
new file mode 100644
index 0000000000..522a90e136
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/src/extra.rs
@@ -0,0 +1,151 @@
+//! Items which do not have a correspondence to any API in the proc_macro crate,
+//! but are necessary to include in proc-macro2.
+
+use crate::fallback;
+use crate::imp;
+use crate::marker::{ProcMacroAutoTraits, MARKER};
+use crate::Span;
+use core::fmt::{self, Debug};
+
+/// Invalidate any `proc_macro2::Span` that exist on the current thread.
+///
+/// The implementation of `Span` uses thread-local data structures and this
+/// function clears them. Calling any method on a `Span` on the current thread
+/// created prior to the invalidation will return incorrect values or crash.
+///
+/// This function is useful for programs that process more than 2<sup>32</sup>
+/// bytes of Rust source code on the same thread. Just like rustc, proc-macro2
+/// uses 32-bit source locations, and these wrap around when the total source
+/// code processed by the same thread exceeds 2<sup>32</sup> bytes (4
+/// gigabytes). After a wraparound, `Span` methods such as `source_text()` can
+/// return wrong data.
+///
+/// # Example
+///
+/// As of late 2023, there is 200 GB of Rust code published on crates.io.
+/// Looking at just the newest version of every crate, it is 16 GB of code. So a
+/// workload that involves parsing it all would overflow a 32-bit source
+/// location unless spans are being invalidated.
+///
+/// ```
+/// use flate2::read::GzDecoder;
+/// use std::ffi::OsStr;
+/// use std::io::{BufReader, Read};
+/// use std::str::FromStr;
+/// use tar::Archive;
+///
+/// rayon::scope(|s| {
+/// for krate in every_version_of_every_crate() {
+/// s.spawn(move |_| {
+/// proc_macro2::extra::invalidate_current_thread_spans();
+///
+/// let reader = BufReader::new(krate);
+/// let tar = GzDecoder::new(reader);
+/// let mut archive = Archive::new(tar);
+/// for entry in archive.entries().unwrap() {
+/// let mut entry = entry.unwrap();
+/// let path = entry.path().unwrap();
+/// if path.extension() != Some(OsStr::new("rs")) {
+/// continue;
+/// }
+/// let mut content = String::new();
+/// entry.read_to_string(&mut content).unwrap();
+/// match proc_macro2::TokenStream::from_str(&content) {
+/// Ok(tokens) => {/* ... */},
+/// Err(_) => continue,
+/// }
+/// }
+/// });
+/// }
+/// });
+/// #
+/// # fn every_version_of_every_crate() -> Vec<std::fs::File> {
+/// # Vec::new()
+/// # }
+/// ```
+///
+/// # Panics
+///
+/// This function is not applicable to and will panic if called from a
+/// procedural macro.
+#[cfg(span_locations)]
+#[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))]
+pub fn invalidate_current_thread_spans() {
+ crate::imp::invalidate_current_thread_spans();
+}
+
+/// An object that holds a [`Group`]'s `span_open()` and `span_close()` together
+/// in a more compact representation than holding those 2 spans individually.
+///
+/// [`Group`]: crate::Group
+#[derive(Copy, Clone)]
+pub struct DelimSpan {
+ inner: DelimSpanEnum,
+ _marker: ProcMacroAutoTraits,
+}
+
+#[derive(Copy, Clone)]
+enum DelimSpanEnum {
+ #[cfg(wrap_proc_macro)]
+ Compiler {
+ join: proc_macro::Span,
+ open: proc_macro::Span,
+ close: proc_macro::Span,
+ },
+ Fallback(fallback::Span),
+}
+
+impl DelimSpan {
+ pub(crate) fn new(group: &imp::Group) -> Self {
+ #[cfg(wrap_proc_macro)]
+ let inner = match group {
+ imp::Group::Compiler(group) => DelimSpanEnum::Compiler {
+ join: group.span(),
+ open: group.span_open(),
+ close: group.span_close(),
+ },
+ imp::Group::Fallback(group) => DelimSpanEnum::Fallback(group.span()),
+ };
+
+ #[cfg(not(wrap_proc_macro))]
+ let inner = DelimSpanEnum::Fallback(group.span());
+
+ DelimSpan {
+ inner,
+ _marker: MARKER,
+ }
+ }
+
+ /// Returns a span covering the entire delimited group.
+ pub fn join(&self) -> Span {
+ match &self.inner {
+ #[cfg(wrap_proc_macro)]
+ DelimSpanEnum::Compiler { join, .. } => Span::_new(imp::Span::Compiler(*join)),
+ DelimSpanEnum::Fallback(span) => Span::_new_fallback(*span),
+ }
+ }
+
+ /// Returns a span for the opening punctuation of the group only.
+ pub fn open(&self) -> Span {
+ match &self.inner {
+ #[cfg(wrap_proc_macro)]
+ DelimSpanEnum::Compiler { open, .. } => Span::_new(imp::Span::Compiler(*open)),
+ DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.first_byte()),
+ }
+ }
+
+ /// Returns a span for the closing punctuation of the group only.
+ pub fn close(&self) -> Span {
+ match &self.inner {
+ #[cfg(wrap_proc_macro)]
+ DelimSpanEnum::Compiler { close, .. } => Span::_new(imp::Span::Compiler(*close)),
+ DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.last_byte()),
+ }
+ }
+}
+
+impl Debug for DelimSpan {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.join(), f)
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/src/fallback.rs b/rust/hw/char/pl011/vendor/proc-macro2/src/fallback.rs
new file mode 100644
index 0000000000..2d1c991997
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/src/fallback.rs
@@ -0,0 +1,1226 @@
+#[cfg(span_locations)]
+use crate::location::LineColumn;
+use crate::parse::{self, Cursor};
+use crate::rcvec::{RcVec, RcVecBuilder, RcVecIntoIter, RcVecMut};
+use crate::{Delimiter, Spacing, TokenTree};
+#[cfg(all(span_locations, not(fuzzing)))]
+use alloc::collections::BTreeMap;
+#[cfg(all(span_locations, not(fuzzing)))]
+use core::cell::RefCell;
+#[cfg(span_locations)]
+use core::cmp;
+use core::fmt::{self, Debug, Display, Write};
+use core::mem::ManuallyDrop;
+#[cfg(span_locations)]
+use core::ops::Range;
+use core::ops::RangeBounds;
+use core::ptr;
+use core::str::{self, FromStr};
+use std::ffi::CStr;
+#[cfg(procmacro2_semver_exempt)]
+use std::path::PathBuf;
+
+/// Force use of proc-macro2's fallback implementation of the API for now, even
+/// if the compiler's implementation is available.
+pub fn force() {
+ #[cfg(wrap_proc_macro)]
+ crate::detection::force_fallback();
+}
+
+/// Resume using the compiler's implementation of the proc macro API if it is
+/// available.
+pub fn unforce() {
+ #[cfg(wrap_proc_macro)]
+ crate::detection::unforce_fallback();
+}
+
+#[derive(Clone)]
+pub(crate) struct TokenStream {
+ inner: RcVec<TokenTree>,
+}
+
+#[derive(Debug)]
+pub(crate) struct LexError {
+ pub(crate) span: Span,
+}
+
+impl LexError {
+ pub(crate) fn span(&self) -> Span {
+ self.span
+ }
+
+ pub(crate) fn call_site() -> Self {
+ LexError {
+ span: Span::call_site(),
+ }
+ }
+}
+
+impl TokenStream {
+ pub fn new() -> Self {
+ TokenStream {
+ inner: RcVecBuilder::new().build(),
+ }
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.inner.len() == 0
+ }
+
+ fn take_inner(self) -> RcVecBuilder<TokenTree> {
+ let nodrop = ManuallyDrop::new(self);
+ unsafe { ptr::read(&nodrop.inner) }.make_owned()
+ }
+}
+
+fn push_token_from_proc_macro(mut vec: RcVecMut<TokenTree>, token: TokenTree) {
+ // https://github.com/dtolnay/proc-macro2/issues/235
+ match token {
+ TokenTree::Literal(crate::Literal {
+ #[cfg(wrap_proc_macro)]
+ inner: crate::imp::Literal::Fallback(literal),
+ #[cfg(not(wrap_proc_macro))]
+ inner: literal,
+ ..
+ }) if literal.repr.starts_with('-') => {
+ push_negative_literal(vec, literal);
+ }
+ _ => vec.push(token),
+ }
+
+ #[cold]
+ fn push_negative_literal(mut vec: RcVecMut<TokenTree>, mut literal: Literal) {
+ literal.repr.remove(0);
+ let mut punct = crate::Punct::new('-', Spacing::Alone);
+ punct.set_span(crate::Span::_new_fallback(literal.span));
+ vec.push(TokenTree::Punct(punct));
+ vec.push(TokenTree::Literal(crate::Literal::_new_fallback(literal)));
+ }
+}
+
+// Nonrecursive to prevent stack overflow.
+impl Drop for TokenStream {
+ fn drop(&mut self) {
+ let mut inner = match self.inner.get_mut() {
+ Some(inner) => inner,
+ None => return,
+ };
+ while let Some(token) = inner.pop() {
+ let group = match token {
+ TokenTree::Group(group) => group.inner,
+ _ => continue,
+ };
+ #[cfg(wrap_proc_macro)]
+ let group = match group {
+ crate::imp::Group::Fallback(group) => group,
+ crate::imp::Group::Compiler(_) => continue,
+ };
+ inner.extend(group.stream.take_inner());
+ }
+ }
+}
+
+pub(crate) struct TokenStreamBuilder {
+ inner: RcVecBuilder<TokenTree>,
+}
+
+impl TokenStreamBuilder {
+ pub fn new() -> Self {
+ TokenStreamBuilder {
+ inner: RcVecBuilder::new(),
+ }
+ }
+
+ pub fn with_capacity(cap: usize) -> Self {
+ TokenStreamBuilder {
+ inner: RcVecBuilder::with_capacity(cap),
+ }
+ }
+
+ pub fn push_token_from_parser(&mut self, tt: TokenTree) {
+ self.inner.push(tt);
+ }
+
+ pub fn build(self) -> TokenStream {
+ TokenStream {
+ inner: self.inner.build(),
+ }
+ }
+}
+
+#[cfg(span_locations)]
+fn get_cursor(src: &str) -> Cursor {
+ #[cfg(fuzzing)]
+ return Cursor { rest: src, off: 1 };
+
+ // Create a dummy file & add it to the source map
+ #[cfg(not(fuzzing))]
+ SOURCE_MAP.with(|sm| {
+ let mut sm = sm.borrow_mut();
+ let span = sm.add_file(src);
+ Cursor {
+ rest: src,
+ off: span.lo,
+ }
+ })
+}
+
+#[cfg(not(span_locations))]
+fn get_cursor(src: &str) -> Cursor {
+ Cursor { rest: src }
+}
+
+impl FromStr for TokenStream {
+ type Err = LexError;
+
+ fn from_str(src: &str) -> Result<TokenStream, LexError> {
+ // 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")
+ }
+}
+
+impl Display for TokenStream {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let mut joint = false;
+ for (i, tt) in self.inner.iter().enumerate() {
+ if i != 0 && !joint {
+ write!(f, " ")?;
+ }
+ joint = false;
+ match tt {
+ TokenTree::Group(tt) => Display::fmt(tt, f),
+ TokenTree::Ident(tt) => Display::fmt(tt, f),
+ TokenTree::Punct(tt) => {
+ joint = tt.spacing() == Spacing::Joint;
+ Display::fmt(tt, f)
+ }
+ TokenTree::Literal(tt) => Display::fmt(tt, f),
+ }?;
+ }
+
+ Ok(())
+ }
+}
+
+impl Debug for TokenStream {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("TokenStream ")?;
+ f.debug_list().entries(self.clone()).finish()
+ }
+}
+
+#[cfg(feature = "proc-macro")]
+impl From<proc_macro::TokenStream> for TokenStream {
+ fn from(inner: proc_macro::TokenStream) -> Self {
+ inner
+ .to_string()
+ .parse()
+ .expect("compiler token stream parse failed")
+ }
+}
+
+#[cfg(feature = "proc-macro")]
+impl From<TokenStream> for proc_macro::TokenStream {
+ fn from(inner: TokenStream) -> Self {
+ inner
+ .to_string()
+ .parse()
+ .expect("failed to parse to compiler tokens")
+ }
+}
+
+impl From<TokenTree> for TokenStream {
+ fn from(tree: TokenTree) -> Self {
+ let mut stream = RcVecBuilder::new();
+ push_token_from_proc_macro(stream.as_mut(), tree);
+ TokenStream {
+ inner: stream.build(),
+ }
+ }
+}
+
+impl FromIterator<TokenTree> for TokenStream {
+ fn from_iter<I: IntoIterator<Item = TokenTree>>(tokens: I) -> Self {
+ let mut stream = TokenStream::new();
+ stream.extend(tokens);
+ stream
+ }
+}
+
+impl FromIterator<TokenStream> for TokenStream {
+ fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
+ let mut v = RcVecBuilder::new();
+
+ for stream in streams {
+ v.extend(stream.take_inner());
+ }
+
+ TokenStream { inner: v.build() }
+ }
+}
+
+impl Extend<TokenTree> for TokenStream {
+ fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, tokens: I) {
+ let mut vec = self.inner.make_mut();
+ tokens
+ .into_iter()
+ .for_each(|token| push_token_from_proc_macro(vec.as_mut(), token));
+ }
+}
+
+impl Extend<TokenStream> for TokenStream {
+ fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
+ self.inner.make_mut().extend(streams.into_iter().flatten());
+ }
+}
+
+pub(crate) type TokenTreeIter = RcVecIntoIter<TokenTree>;
+
+impl IntoIterator for TokenStream {
+ type Item = TokenTree;
+ type IntoIter = TokenTreeIter;
+
+ fn into_iter(self) -> TokenTreeIter {
+ self.take_inner().into_iter()
+ }
+}
+
+#[cfg(procmacro2_semver_exempt)]
+#[derive(Clone, PartialEq, Eq)]
+pub(crate) struct SourceFile {
+ path: PathBuf,
+}
+
+#[cfg(procmacro2_semver_exempt)]
+impl SourceFile {
+ /// Get the path to this source file as a string.
+ pub fn path(&self) -> PathBuf {
+ self.path.clone()
+ }
+
+ pub fn is_real(&self) -> bool {
+ false
+ }
+}
+
+#[cfg(procmacro2_semver_exempt)]
+impl Debug for SourceFile {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("SourceFile")
+ .field("path", &self.path())
+ .field("is_real", &self.is_real())
+ .finish()
+ }
+}
+
+#[cfg(all(span_locations, not(fuzzing)))]
+thread_local! {
+ static SOURCE_MAP: RefCell<SourceMap> = RefCell::new(SourceMap {
+ // Start with a single dummy file which all call_site() and def_site()
+ // spans reference.
+ files: vec![FileInfo {
+ source_text: String::new(),
+ span: Span { lo: 0, hi: 0 },
+ lines: vec![0],
+ char_index_to_byte_offset: BTreeMap::new(),
+ }],
+ });
+}
+
+#[cfg(span_locations)]
+pub(crate) fn invalidate_current_thread_spans() {
+ #[cfg(not(fuzzing))]
+ SOURCE_MAP.with(|sm| sm.borrow_mut().files.truncate(1));
+}
+
+#[cfg(all(span_locations, not(fuzzing)))]
+struct FileInfo {
+ source_text: String,
+ span: Span,
+ lines: Vec<usize>,
+ char_index_to_byte_offset: BTreeMap<usize, usize>,
+}
+
+#[cfg(all(span_locations, not(fuzzing)))]
+impl FileInfo {
+ fn offset_line_column(&self, offset: usize) -> LineColumn {
+ assert!(self.span_within(Span {
+ lo: offset as u32,
+ hi: offset as u32,
+ }));
+ let offset = offset - self.span.lo as usize;
+ match self.lines.binary_search(&offset) {
+ Ok(found) => LineColumn {
+ line: found + 1,
+ column: 0,
+ },
+ Err(idx) => LineColumn {
+ line: idx,
+ column: offset - self.lines[idx - 1],
+ },
+ }
+ }
+
+ fn span_within(&self, span: Span) -> bool {
+ span.lo >= self.span.lo && span.hi <= self.span.hi
+ }
+
+ fn byte_range(&mut self, span: Span) -> Range<usize> {
+ let lo_char = (span.lo - self.span.lo) as usize;
+
+ // Look up offset of the largest already-computed char index that is
+ // less than or equal to the current requested one. We resume counting
+ // chars from that point.
+ let (&last_char_index, &last_byte_offset) = self
+ .char_index_to_byte_offset
+ .range(..=lo_char)
+ .next_back()
+ .unwrap_or((&0, &0));
+
+ let lo_byte = if last_char_index == lo_char {
+ last_byte_offset
+ } else {
+ let total_byte_offset = match self.source_text[last_byte_offset..]
+ .char_indices()
+ .nth(lo_char - last_char_index)
+ {
+ Some((additional_offset, _ch)) => last_byte_offset + additional_offset,
+ None => self.source_text.len(),
+ };
+ self.char_index_to_byte_offset
+ .insert(lo_char, total_byte_offset);
+ total_byte_offset
+ };
+
+ let trunc_lo = &self.source_text[lo_byte..];
+ let char_len = (span.hi - span.lo) as usize;
+ lo_byte..match trunc_lo.char_indices().nth(char_len) {
+ Some((offset, _ch)) => lo_byte + offset,
+ None => self.source_text.len(),
+ }
+ }
+
+ fn source_text(&mut self, span: Span) -> String {
+ let byte_range = self.byte_range(span);
+ self.source_text[byte_range].to_owned()
+ }
+}
+
+/// Computes the offsets of each line in the given source string
+/// and the total number of characters
+#[cfg(all(span_locations, not(fuzzing)))]
+fn lines_offsets(s: &str) -> (usize, Vec<usize>) {
+ let mut lines = vec![0];
+ let mut total = 0;
+
+ for ch in s.chars() {
+ total += 1;
+ if ch == '\n' {
+ lines.push(total);
+ }
+ }
+
+ (total, lines)
+}
+
+#[cfg(all(span_locations, not(fuzzing)))]
+struct SourceMap {
+ files: Vec<FileInfo>,
+}
+
+#[cfg(all(span_locations, not(fuzzing)))]
+impl SourceMap {
+ fn next_start_pos(&self) -> u32 {
+ // Add 1 so there's always space between files.
+ //
+ // We'll always have at least 1 file, as we initialize our files list
+ // with a dummy file.
+ self.files.last().unwrap().span.hi + 1
+ }
+
+ fn add_file(&mut self, src: &str) -> Span {
+ let (len, lines) = lines_offsets(src);
+ let lo = self.next_start_pos();
+ let span = Span {
+ lo,
+ hi: lo + (len as u32),
+ };
+
+ self.files.push(FileInfo {
+ source_text: src.to_owned(),
+ span,
+ lines,
+ // Populated lazily by source_text().
+ char_index_to_byte_offset: BTreeMap::new(),
+ });
+
+ span
+ }
+
+ #[cfg(procmacro2_semver_exempt)]
+ fn filepath(&self, span: Span) -> PathBuf {
+ for (i, file) in self.files.iter().enumerate() {
+ if file.span_within(span) {
+ return PathBuf::from(if i == 0 {
+ "<unspecified>".to_owned()
+ } else {
+ format!("<parsed string {}>", i)
+ });
+ }
+ }
+ unreachable!("Invalid span with no related FileInfo!");
+ }
+
+ fn fileinfo(&self, span: Span) -> &FileInfo {
+ for file in &self.files {
+ if file.span_within(span) {
+ return file;
+ }
+ }
+ unreachable!("Invalid span with no related FileInfo!");
+ }
+
+ fn fileinfo_mut(&mut self, span: Span) -> &mut FileInfo {
+ for file in &mut self.files {
+ if file.span_within(span) {
+ return file;
+ }
+ }
+ unreachable!("Invalid span with no related FileInfo!");
+ }
+}
+
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub(crate) struct Span {
+ #[cfg(span_locations)]
+ pub(crate) lo: u32,
+ #[cfg(span_locations)]
+ pub(crate) hi: u32,
+}
+
+impl Span {
+ #[cfg(not(span_locations))]
+ pub fn call_site() -> Self {
+ Span {}
+ }
+
+ #[cfg(span_locations)]
+ pub fn call_site() -> Self {
+ Span { lo: 0, hi: 0 }
+ }
+
+ pub fn mixed_site() -> Self {
+ Span::call_site()
+ }
+
+ #[cfg(procmacro2_semver_exempt)]
+ pub fn def_site() -> Self {
+ Span::call_site()
+ }
+
+ pub 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 {
+ other
+ }
+
+ #[cfg(procmacro2_semver_exempt)]
+ pub fn source_file(&self) -> SourceFile {
+ #[cfg(fuzzing)]
+ return SourceFile {
+ path: PathBuf::from("<unspecified>"),
+ };
+
+ #[cfg(not(fuzzing))]
+ SOURCE_MAP.with(|sm| {
+ let sm = sm.borrow();
+ let path = sm.filepath(*self);
+ SourceFile { path }
+ })
+ }
+
+ #[cfg(span_locations)]
+ pub fn byte_range(&self) -> Range<usize> {
+ #[cfg(fuzzing)]
+ return 0..0;
+
+ #[cfg(not(fuzzing))]
+ {
+ if self.is_call_site() {
+ 0..0
+ } else {
+ SOURCE_MAP.with(|sm| sm.borrow_mut().fileinfo_mut(*self).byte_range(*self))
+ }
+ }
+ }
+
+ #[cfg(span_locations)]
+ pub fn start(&self) -> LineColumn {
+ #[cfg(fuzzing)]
+ return LineColumn { line: 0, column: 0 };
+
+ #[cfg(not(fuzzing))]
+ SOURCE_MAP.with(|sm| {
+ let sm = sm.borrow();
+ let fi = sm.fileinfo(*self);
+ fi.offset_line_column(self.lo as usize)
+ })
+ }
+
+ #[cfg(span_locations)]
+ pub fn end(&self) -> LineColumn {
+ #[cfg(fuzzing)]
+ return LineColumn { line: 0, column: 0 };
+
+ #[cfg(not(fuzzing))]
+ SOURCE_MAP.with(|sm| {
+ let sm = sm.borrow();
+ let fi = sm.fileinfo(*self);
+ fi.offset_line_column(self.hi as usize)
+ })
+ }
+
+ #[cfg(not(span_locations))]
+ pub fn join(&self, _other: Span) -> Option<Span> {
+ Some(Span {})
+ }
+
+ #[cfg(span_locations)]
+ pub fn join(&self, other: Span) -> Option<Span> {
+ #[cfg(fuzzing)]
+ return {
+ let _ = other;
+ None
+ };
+
+ #[cfg(not(fuzzing))]
+ SOURCE_MAP.with(|sm| {
+ let sm = sm.borrow();
+ // If `other` is not within the same FileInfo as us, return None.
+ if !sm.fileinfo(*self).span_within(other) {
+ return None;
+ }
+ Some(Span {
+ lo: cmp::min(self.lo, other.lo),
+ hi: cmp::max(self.hi, other.hi),
+ })
+ })
+ }
+
+ #[cfg(not(span_locations))]
+ pub fn source_text(&self) -> Option<String> {
+ None
+ }
+
+ #[cfg(span_locations)]
+ pub fn source_text(&self) -> Option<String> {
+ #[cfg(fuzzing)]
+ return None;
+
+ #[cfg(not(fuzzing))]
+ {
+ if self.is_call_site() {
+ None
+ } else {
+ Some(SOURCE_MAP.with(|sm| sm.borrow_mut().fileinfo_mut(*self).source_text(*self)))
+ }
+ }
+ }
+
+ #[cfg(not(span_locations))]
+ pub(crate) fn first_byte(self) -> Self {
+ self
+ }
+
+ #[cfg(span_locations)]
+ pub(crate) fn first_byte(self) -> Self {
+ Span {
+ lo: self.lo,
+ hi: cmp::min(self.lo.saturating_add(1), self.hi),
+ }
+ }
+
+ #[cfg(not(span_locations))]
+ pub(crate) fn last_byte(self) -> Self {
+ self
+ }
+
+ #[cfg(span_locations)]
+ pub(crate) fn last_byte(self) -> Self {
+ Span {
+ lo: cmp::max(self.hi.saturating_sub(1), self.lo),
+ hi: self.hi,
+ }
+ }
+
+ #[cfg(span_locations)]
+ fn is_call_site(&self) -> bool {
+ self.lo == 0 && self.hi == 0
+ }
+}
+
+impl Debug for Span {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ #[cfg(span_locations)]
+ return write!(f, "bytes({}..{})", self.lo, self.hi);
+
+ #[cfg(not(span_locations))]
+ write!(f, "Span")
+ }
+}
+
+pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) {
+ #[cfg(span_locations)]
+ {
+ if span.is_call_site() {
+ return;
+ }
+ }
+
+ if cfg!(span_locations) {
+ debug.field("span", &span);
+ }
+}
+
+#[derive(Clone)]
+pub(crate) struct Group {
+ delimiter: Delimiter,
+ stream: TokenStream,
+ span: Span,
+}
+
+impl Group {
+ pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self {
+ Group {
+ delimiter,
+ stream,
+ span: Span::call_site(),
+ }
+ }
+
+ pub fn delimiter(&self) -> Delimiter {
+ self.delimiter
+ }
+
+ pub fn stream(&self) -> TokenStream {
+ self.stream.clone()
+ }
+
+ pub fn span(&self) -> Span {
+ self.span
+ }
+
+ pub fn span_open(&self) -> Span {
+ self.span.first_byte()
+ }
+
+ pub fn span_close(&self) -> Span {
+ self.span.last_byte()
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.span = span;
+ }
+}
+
+impl Display for Group {
+ // We attempt to match libproc_macro's formatting.
+ // Empty parens: ()
+ // Nonempty parens: (...)
+ // Empty brackets: []
+ // Nonempty brackets: [...]
+ // Empty braces: { }
+ // Nonempty braces: { ... }
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let (open, close) = match self.delimiter {
+ Delimiter::Parenthesis => ("(", ")"),
+ Delimiter::Brace => ("{ ", "}"),
+ Delimiter::Bracket => ("[", "]"),
+ Delimiter::None => ("", ""),
+ };
+
+ f.write_str(open)?;
+ Display::fmt(&self.stream, f)?;
+ if self.delimiter == Delimiter::Brace && !self.stream.inner.is_empty() {
+ f.write_str(" ")?;
+ }
+ f.write_str(close)?;
+
+ Ok(())
+ }
+}
+
+impl Debug for Group {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ let mut debug = fmt.debug_struct("Group");
+ debug.field("delimiter", &self.delimiter);
+ debug.field("stream", &self.stream);
+ debug_span_field_if_nontrivial(&mut debug, self.span);
+ debug.finish()
+ }
+}
+
+#[derive(Clone)]
+pub(crate) struct Ident {
+ sym: Box<str>,
+ span: Span,
+ raw: bool,
+}
+
+impl Ident {
+ #[track_caller]
+ pub 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 {
+ Ident {
+ sym: Box::from(string),
+ span,
+ raw: false,
+ }
+ }
+
+ #[track_caller]
+ pub 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 {
+ Ident {
+ sym: Box::from(string),
+ span,
+ raw: true,
+ }
+ }
+
+ pub fn span(&self) -> Span {
+ self.span
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.span = span;
+ }
+}
+
+pub(crate) fn is_ident_start(c: char) -> bool {
+ c == '_' || unicode_ident::is_xid_start(c)
+}
+
+pub(crate) fn is_ident_continue(c: char) -> bool {
+ unicode_ident::is_xid_continue(c)
+}
+
+#[track_caller]
+fn validate_ident(string: &str) {
+ if string.is_empty() {
+ panic!("Ident is not allowed to be empty; use Option<Ident>");
+ }
+
+ if string.bytes().all(|digit| b'0' <= digit && digit <= b'9') {
+ panic!("Ident cannot be a number; use Literal instead");
+ }
+
+ fn ident_ok(string: &str) -> bool {
+ let mut chars = string.chars();
+ let first = chars.next().unwrap();
+ if !is_ident_start(first) {
+ return false;
+ }
+ for ch in chars {
+ if !is_ident_continue(ch) {
+ return false;
+ }
+ }
+ true
+ }
+
+ if !ident_ok(string) {
+ panic!("{:?} is not a valid Ident", string);
+ }
+}
+
+#[track_caller]
+fn validate_ident_raw(string: &str) {
+ validate_ident(string);
+
+ match string {
+ "_" | "super" | "self" | "Self" | "crate" => {
+ panic!("`r#{}` cannot be a raw identifier", string);
+ }
+ _ => {}
+ }
+}
+
+impl PartialEq for Ident {
+ fn eq(&self, other: &Ident) -> bool {
+ self.sym == other.sym && self.raw == other.raw
+ }
+}
+
+impl<T> PartialEq<T> for Ident
+where
+ T: ?Sized + AsRef<str>,
+{
+ fn eq(&self, other: &T) -> bool {
+ let other = other.as_ref();
+ if self.raw {
+ other.starts_with("r#") && *self.sym == other[2..]
+ } else {
+ *self.sym == *other
+ }
+ }
+}
+
+impl Display for Ident {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if self.raw {
+ f.write_str("r#")?;
+ }
+ Display::fmt(&self.sym, f)
+ }
+}
+
+#[allow(clippy::missing_fields_in_debug)]
+impl Debug for Ident {
+ // Ident(proc_macro), Ident(r#union)
+ #[cfg(not(span_locations))]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let mut debug = f.debug_tuple("Ident");
+ debug.field(&format_args!("{}", self));
+ debug.finish()
+ }
+
+ // Ident {
+ // sym: proc_macro,
+ // span: bytes(128..138)
+ // }
+ #[cfg(span_locations)]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let mut debug = f.debug_struct("Ident");
+ debug.field("sym", &format_args!("{}", self));
+ debug_span_field_if_nontrivial(&mut debug, self.span);
+ debug.finish()
+ }
+}
+
+#[derive(Clone)]
+pub(crate) struct Literal {
+ pub(crate) repr: String,
+ span: Span,
+}
+
+macro_rules! suffixed_numbers {
+ ($($name:ident => $kind:ident,)*) => ($(
+ pub fn $name(n: $kind) -> Literal {
+ Literal::_new(format!(concat!("{}", stringify!($kind)), n))
+ }
+ )*)
+}
+
+macro_rules! unsuffixed_numbers {
+ ($($name:ident => $kind:ident,)*) => ($(
+ pub fn $name(n: $kind) -> Literal {
+ Literal::_new(n.to_string())
+ }
+ )*)
+}
+
+impl Literal {
+ pub(crate) fn _new(repr: String) -> Self {
+ Literal {
+ repr,
+ span: Span::call_site(),
+ }
+ }
+
+ pub(crate) unsafe fn from_str_unchecked(repr: &str) -> Self {
+ Literal::_new(repr.to_owned())
+ }
+
+ suffixed_numbers! {
+ u8_suffixed => u8,
+ u16_suffixed => u16,
+ u32_suffixed => u32,
+ u64_suffixed => u64,
+ u128_suffixed => u128,
+ usize_suffixed => usize,
+ i8_suffixed => i8,
+ i16_suffixed => i16,
+ i32_suffixed => i32,
+ i64_suffixed => i64,
+ i128_suffixed => i128,
+ isize_suffixed => isize,
+
+ f32_suffixed => f32,
+ f64_suffixed => f64,
+ }
+
+ unsuffixed_numbers! {
+ u8_unsuffixed => u8,
+ u16_unsuffixed => u16,
+ u32_unsuffixed => u32,
+ u64_unsuffixed => u64,
+ u128_unsuffixed => u128,
+ usize_unsuffixed => usize,
+ i8_unsuffixed => i8,
+ i16_unsuffixed => i16,
+ i32_unsuffixed => i32,
+ i64_unsuffixed => i64,
+ i128_unsuffixed => i128,
+ isize_unsuffixed => isize,
+ }
+
+ pub fn f32_unsuffixed(f: f32) -> Literal {
+ let mut s = f.to_string();
+ if !s.contains('.') {
+ s.push_str(".0");
+ }
+ Literal::_new(s)
+ }
+
+ pub fn f64_unsuffixed(f: f64) -> Literal {
+ let mut s = f.to_string();
+ if !s.contains('.') {
+ s.push_str(".0");
+ }
+ Literal::_new(s)
+ }
+
+ pub fn string(string: &str) -> Literal {
+ let mut repr = String::with_capacity(string.len() + 2);
+ repr.push('"');
+ escape_utf8(string, &mut repr);
+ repr.push('"');
+ Literal::_new(repr)
+ }
+
+ pub fn character(ch: char) -> Literal {
+ let mut repr = String::new();
+ repr.push('\'');
+ if ch == '"' {
+ // escape_debug turns this into '\"' which is unnecessary.
+ repr.push(ch);
+ } else {
+ repr.extend(ch.escape_debug());
+ }
+ repr.push('\'');
+ Literal::_new(repr)
+ }
+
+ pub fn byte_character(byte: u8) -> Literal {
+ let mut repr = "b'".to_string();
+ #[allow(clippy::match_overlapping_arm)]
+ match byte {
+ b'\0' => repr.push_str(r"\0"),
+ b'\t' => repr.push_str(r"\t"),
+ b'\n' => repr.push_str(r"\n"),
+ b'\r' => repr.push_str(r"\r"),
+ b'\'' => repr.push_str(r"\'"),
+ b'\\' => repr.push_str(r"\\"),
+ b'\x20'..=b'\x7E' => repr.push(byte as char),
+ _ => {
+ let _ = write!(repr, r"\x{:02X}", byte);
+ }
+ }
+ repr.push('\'');
+ Literal::_new(repr)
+ }
+
+ pub fn byte_string(bytes: &[u8]) -> Literal {
+ let mut repr = "b\"".to_string();
+ let mut bytes = bytes.iter();
+ while let Some(&b) = bytes.next() {
+ #[allow(clippy::match_overlapping_arm)]
+ match b {
+ b'\0' => repr.push_str(match bytes.as_slice().first() {
+ // circumvent clippy::octal_escapes lint
+ Some(b'0'..=b'7') => r"\x00",
+ _ => r"\0",
+ }),
+ b'\t' => repr.push_str(r"\t"),
+ b'\n' => repr.push_str(r"\n"),
+ b'\r' => repr.push_str(r"\r"),
+ b'"' => repr.push_str("\\\""),
+ b'\\' => repr.push_str(r"\\"),
+ b'\x20'..=b'\x7E' => repr.push(b as char),
+ _ => {
+ let _ = write!(repr, r"\x{:02X}", b);
+ }
+ }
+ }
+ repr.push('"');
+ Literal::_new(repr)
+ }
+
+ pub fn c_string(string: &CStr) -> Literal {
+ let mut repr = "c\"".to_string();
+ let mut bytes = string.to_bytes();
+ while !bytes.is_empty() {
+ let (valid, invalid) = match str::from_utf8(bytes) {
+ Ok(all_valid) => {
+ bytes = b"";
+ (all_valid, bytes)
+ }
+ Err(utf8_error) => {
+ let (valid, rest) = bytes.split_at(utf8_error.valid_up_to());
+ let valid = str::from_utf8(valid).unwrap();
+ let invalid = utf8_error
+ .error_len()
+ .map_or(rest, |error_len| &rest[..error_len]);
+ bytes = &bytes[valid.len() + invalid.len()..];
+ (valid, invalid)
+ }
+ };
+ escape_utf8(valid, &mut repr);
+ for &byte in invalid {
+ let _ = write!(repr, r"\x{:02X}", byte);
+ }
+ }
+ repr.push('"');
+ Literal::_new(repr)
+ }
+
+ pub fn span(&self) -> Span {
+ self.span
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.span = span;
+ }
+
+ pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
+ #[cfg(not(span_locations))]
+ {
+ let _ = range;
+ None
+ }
+
+ #[cfg(span_locations)]
+ {
+ use core::ops::Bound;
+
+ let lo = match range.start_bound() {
+ Bound::Included(start) => {
+ let start = u32::try_from(*start).ok()?;
+ self.span.lo.checked_add(start)?
+ }
+ Bound::Excluded(start) => {
+ let start = u32::try_from(*start).ok()?;
+ self.span.lo.checked_add(start)?.checked_add(1)?
+ }
+ Bound::Unbounded => self.span.lo,
+ };
+ let hi = match range.end_bound() {
+ Bound::Included(end) => {
+ let end = u32::try_from(*end).ok()?;
+ self.span.lo.checked_add(end)?.checked_add(1)?
+ }
+ Bound::Excluded(end) => {
+ let end = u32::try_from(*end).ok()?;
+ self.span.lo.checked_add(end)?
+ }
+ Bound::Unbounded => self.span.hi,
+ };
+ if lo <= hi && hi <= self.span.hi {
+ Some(Span { lo, hi })
+ } else {
+ None
+ }
+ }
+ }
+}
+
+impl FromStr for Literal {
+ type Err = LexError;
+
+ fn from_str(repr: &str) -> Result<Self, Self::Err> {
+ 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)
+ }
+}
+
+impl Debug for Literal {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ let mut debug = fmt.debug_struct("Literal");
+ debug.field("lit", &format_args!("{}", self.repr));
+ debug_span_field_if_nontrivial(&mut debug, self.span);
+ debug.finish()
+ }
+}
+
+fn escape_utf8(string: &str, repr: &mut String) {
+ let mut chars = string.chars();
+ while let Some(ch) = chars.next() {
+ if ch == '\0' {
+ repr.push_str(
+ if chars
+ .as_str()
+ .starts_with(|next| '0' <= next && next <= '7')
+ {
+ // circumvent clippy::octal_escapes lint
+ r"\x00"
+ } else {
+ r"\0"
+ },
+ );
+ } else if ch == '\'' {
+ // escape_debug turns this into "\'" which is unnecessary.
+ repr.push(ch);
+ } else {
+ repr.extend(ch.escape_debug());
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/src/lib.rs b/rust/hw/char/pl011/vendor/proc-macro2/src/lib.rs
new file mode 100644
index 0000000000..d7bfa50f4f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/src/lib.rs
@@ -0,0 +1,1369 @@
+//! [![github]](https://github.com/dtolnay/proc-macro2) [![crates-io]](https://crates.io/crates/proc-macro2) [![docs-rs]](crate)
+//!
+//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
+//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
+//!
+//! <br>
+//!
+//! A wrapper around the procedural macro API of the compiler's [`proc_macro`]
+//! crate. This library serves two purposes:
+//!
+//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/
+//!
+//! - **Bring proc-macro-like functionality to other contexts like build.rs and
+//! main.rs.** Types from `proc_macro` are entirely specific to procedural
+//! macros and cannot ever exist in code outside of a procedural macro.
+//! Meanwhile `proc_macro2` types may exist anywhere including non-macro code.
+//! By developing foundational libraries like [syn] and [quote] against
+//! `proc_macro2` rather than `proc_macro`, the procedural macro ecosystem
+//! becomes easily applicable to many other use cases and we avoid
+//! reimplementing non-macro equivalents of those libraries.
+//!
+//! - **Make procedural macros unit testable.** As a consequence of being
+//! specific to procedural macros, nothing that uses `proc_macro` can be
+//! executed from a unit test. In order for helper libraries or components of
+//! a macro to be testable in isolation, they must be implemented using
+//! `proc_macro2`.
+//!
+//! [syn]: https://github.com/dtolnay/syn
+//! [quote]: https://github.com/dtolnay/quote
+//!
+//! # Usage
+//!
+//! The skeleton of a typical procedural macro typically looks like this:
+//!
+//! ```
+//! extern crate proc_macro;
+//!
+//! # const IGNORE: &str = stringify! {
+//! #[proc_macro_derive(MyDerive)]
+//! # };
+//! # #[cfg(wrap_proc_macro)]
+//! pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+//! let input = proc_macro2::TokenStream::from(input);
+//!
+//! let output: proc_macro2::TokenStream = {
+//! /* transform input */
+//! # input
+//! };
+//!
+//! proc_macro::TokenStream::from(output)
+//! }
+//! ```
+//!
+//! If parsing with [Syn], you'll use [`parse_macro_input!`] instead to
+//! propagate parse errors correctly back to the compiler when parsing fails.
+//!
+//! [`parse_macro_input!`]: https://docs.rs/syn/2.0/syn/macro.parse_macro_input.html
+//!
+//! # Unstable features
+//!
+//! The default feature set of proc-macro2 tracks the most recent stable
+//! compiler API. Functionality in `proc_macro` that is not yet stable is not
+//! exposed by proc-macro2 by default.
+//!
+//! To opt into the additional APIs available in the most recent nightly
+//! compiler, the `procmacro2_semver_exempt` config flag must be passed to
+//! rustc. We will polyfill those nightly-only APIs back to Rust 1.56.0. As
+//! these are unstable APIs that track the nightly compiler, minor versions of
+//! proc-macro2 may make breaking changes to them at any time.
+//!
+//! ```sh
+//! RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build
+//! ```
+//!
+//! Note that this must not only be done for your crate, but for any crate that
+//! depends on your crate. This infectious nature is intentional, as it serves
+//! as a reminder that you are outside of the normal semver guarantees.
+//!
+//! Semver exempt methods are marked as such in the proc-macro2 documentation.
+//!
+//! # Thread-Safety
+//!
+//! Most types in this crate are `!Sync` because the underlying compiler
+//! types make use of thread-local memory, meaning they cannot be accessed from
+//! 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.84")]
+#![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))]
+#![cfg_attr(super_unstable, feature(proc_macro_def_site))]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![deny(unsafe_op_in_unsafe_fn)]
+#![allow(
+ clippy::cast_lossless,
+ clippy::cast_possible_truncation,
+ clippy::checked_conversions,
+ clippy::doc_markdown,
+ clippy::incompatible_msrv,
+ clippy::items_after_statements,
+ clippy::iter_without_into_iter,
+ clippy::let_underscore_untyped,
+ clippy::manual_assert,
+ clippy::manual_range_contains,
+ clippy::missing_safety_doc,
+ clippy::must_use_candidate,
+ clippy::needless_doctest_main,
+ clippy::new_without_default,
+ clippy::return_self_not_must_use,
+ clippy::shadow_unrelated,
+ clippy::trivially_copy_pass_by_ref,
+ clippy::unnecessary_wraps,
+ clippy::unused_self,
+ clippy::used_underscore_binding,
+ clippy::vec_init_then_push
+)]
+
+#[cfg(all(procmacro2_semver_exempt, wrap_proc_macro, not(super_unstable)))]
+compile_error! {"\
+ Something is not right. If you've tried to turn on \
+ procmacro2_semver_exempt, you need to ensure that it \
+ is turned on for the compilation of the proc-macro2 \
+ build script as well.
+"}
+
+#[cfg(all(
+ procmacro2_nightly_testing,
+ feature = "proc-macro",
+ not(proc_macro_span)
+))]
+compile_error! {"\
+ Build script probe failed to compile.
+"}
+
+extern crate alloc;
+
+#[cfg(feature = "proc-macro")]
+extern crate proc_macro;
+
+mod marker;
+mod parse;
+mod rcvec;
+
+#[cfg(wrap_proc_macro)]
+mod detection;
+
+// Public for proc_macro2::fallback::force() and unforce(), but those are quite
+// a niche use case so we omit it from rustdoc.
+#[doc(hidden)]
+pub mod fallback;
+
+pub mod extra;
+
+#[cfg(not(wrap_proc_macro))]
+use crate::fallback as imp;
+#[path = "wrapper.rs"]
+#[cfg(wrap_proc_macro)]
+mod imp;
+
+#[cfg(span_locations)]
+mod location;
+
+use crate::extra::DelimSpan;
+use crate::marker::{ProcMacroAutoTraits, MARKER};
+use core::cmp::Ordering;
+use core::fmt::{self, Debug, Display};
+use core::hash::{Hash, Hasher};
+#[cfg(span_locations)]
+use core::ops::Range;
+use core::ops::RangeBounds;
+use core::str::FromStr;
+use std::error::Error;
+use std::ffi::CStr;
+#[cfg(procmacro2_semver_exempt)]
+use std::path::PathBuf;
+
+#[cfg(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.
+///
+/// This type provides interfaces for iterating over token trees and for
+/// collecting token trees into one stream.
+///
+/// Token stream is both the input and output of `#[proc_macro]`,
+/// `#[proc_macro_attribute]` and `#[proc_macro_derive]` definitions.
+#[derive(Clone)]
+pub struct TokenStream {
+ inner: imp::TokenStream,
+ _marker: ProcMacroAutoTraits,
+}
+
+/// Error returned from `TokenStream::from_str`.
+pub struct LexError {
+ inner: imp::LexError,
+ _marker: ProcMacroAutoTraits,
+}
+
+impl TokenStream {
+ fn _new(inner: imp::TokenStream) -> Self {
+ TokenStream {
+ inner,
+ _marker: MARKER,
+ }
+ }
+
+ fn _new_fallback(inner: fallback::TokenStream) -> Self {
+ TokenStream {
+ inner: inner.into(),
+ _marker: MARKER,
+ }
+ }
+
+ /// Returns an empty `TokenStream` containing no token trees.
+ pub fn new() -> Self {
+ TokenStream::_new(imp::TokenStream::new())
+ }
+
+ /// Checks if this `TokenStream` is empty.
+ pub fn is_empty(&self) -> bool {
+ self.inner.is_empty()
+ }
+}
+
+/// `TokenStream::default()` returns an empty stream,
+/// i.e. this is equivalent with `TokenStream::new()`.
+impl Default for TokenStream {
+ fn default() -> Self {
+ TokenStream::new()
+ }
+}
+
+/// Attempts to break the string into tokens and parse those tokens into a token
+/// stream.
+///
+/// May fail for a number of reasons, for example, if the string contains
+/// unbalanced delimiters or characters not existing in the language.
+///
+/// NOTE: Some errors may cause panics instead of returning `LexError`. We
+/// reserve the right to change these errors into `LexError`s later.
+impl FromStr for TokenStream {
+ type Err = LexError;
+
+ fn from_str(src: &str) -> Result<TokenStream, LexError> {
+ let e = src.parse().map_err(|e| LexError {
+ inner: e,
+ _marker: MARKER,
+ })?;
+ Ok(TokenStream::_new(e))
+ }
+}
+
+#[cfg(feature = "proc-macro")]
+#[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))]
+impl From<proc_macro::TokenStream> for TokenStream {
+ fn from(inner: proc_macro::TokenStream) -> Self {
+ TokenStream::_new(inner.into())
+ }
+}
+
+#[cfg(feature = "proc-macro")]
+#[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))]
+impl From<TokenStream> for proc_macro::TokenStream {
+ fn from(inner: TokenStream) -> Self {
+ inner.inner.into()
+ }
+}
+
+impl From<TokenTree> for TokenStream {
+ fn from(token: TokenTree) -> Self {
+ TokenStream::_new(imp::TokenStream::from(token))
+ }
+}
+
+impl Extend<TokenTree> for TokenStream {
+ fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I) {
+ self.inner.extend(streams);
+ }
+}
+
+impl Extend<TokenStream> for TokenStream {
+ fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
+ self.inner
+ .extend(streams.into_iter().map(|stream| stream.inner));
+ }
+}
+
+/// Collects a number of token trees into a single stream.
+impl FromIterator<TokenTree> for TokenStream {
+ fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
+ TokenStream::_new(streams.into_iter().collect())
+ }
+}
+impl FromIterator<TokenStream> for TokenStream {
+ fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
+ TokenStream::_new(streams.into_iter().map(|i| i.inner).collect())
+ }
+}
+
+/// Prints the token stream as a string that is supposed to be losslessly
+/// convertible back into the same token stream (modulo spans), except for
+/// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative
+/// numeric literals.
+impl Display for TokenStream {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.inner, f)
+ }
+}
+
+/// Prints token in a form convenient for debugging.
+impl Debug for TokenStream {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.inner, f)
+ }
+}
+
+impl LexError {
+ pub fn span(&self) -> Span {
+ Span::_new(self.inner.span())
+ }
+}
+
+impl Debug for LexError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.inner, f)
+ }
+}
+
+impl Display for LexError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.inner, f)
+ }
+}
+
+impl Error for LexError {}
+
+/// The source file of a given `Span`.
+///
+/// This type is semver exempt and not exposed by default.
+#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))]
+#[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))]
+#[derive(Clone, PartialEq, Eq)]
+pub struct SourceFile {
+ inner: imp::SourceFile,
+ _marker: ProcMacroAutoTraits,
+}
+
+#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))]
+impl SourceFile {
+ fn _new(inner: imp::SourceFile) -> Self {
+ SourceFile {
+ inner,
+ _marker: MARKER,
+ }
+ }
+
+ /// Get the path to this source file.
+ ///
+ /// ### Note
+ ///
+ /// If the code span associated with this `SourceFile` was generated by an
+ /// external macro, this may not be an actual path on the filesystem. Use
+ /// [`is_real`] to check.
+ ///
+ /// Also note that even if `is_real` returns `true`, if
+ /// `--remap-path-prefix` was passed on the command line, the path as given
+ /// may not actually be valid.
+ ///
+ /// [`is_real`]: #method.is_real
+ pub fn path(&self) -> PathBuf {
+ self.inner.path()
+ }
+
+ /// Returns `true` if this source file is a real source file, and not
+ /// generated by an external macro's expansion.
+ pub fn is_real(&self) -> bool {
+ self.inner.is_real()
+ }
+}
+
+#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))]
+impl Debug for SourceFile {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.inner, f)
+ }
+}
+
+/// A region of source code, along with macro expansion information.
+#[derive(Copy, Clone)]
+pub struct Span {
+ inner: imp::Span,
+ _marker: ProcMacroAutoTraits,
+}
+
+impl Span {
+ fn _new(inner: imp::Span) -> Self {
+ Span {
+ inner,
+ _marker: MARKER,
+ }
+ }
+
+ fn _new_fallback(inner: fallback::Span) -> Self {
+ Span {
+ inner: inner.into(),
+ _marker: MARKER,
+ }
+ }
+
+ /// The span of the invocation of the current procedural macro.
+ ///
+ /// Identifiers created with this span will be resolved as if they were
+ /// written directly at the macro call location (call-site hygiene) and
+ /// other code at the macro call site will be able to refer to them as well.
+ pub fn call_site() -> Self {
+ Span::_new(imp::Span::call_site())
+ }
+
+ /// The span located at the invocation of the procedural macro, but with
+ /// local variables, labels, and `$crate` resolved at the definition site
+ /// of the macro. This is the same hygiene behavior as `macro_rules`.
+ pub fn mixed_site() -> Self {
+ Span::_new(imp::Span::mixed_site())
+ }
+
+ /// A span that resolves at the macro definition site.
+ ///
+ /// This method is semver exempt and not exposed by default.
+ #[cfg(procmacro2_semver_exempt)]
+ #[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))]
+ pub fn def_site() -> Self {
+ Span::_new(imp::Span::def_site())
+ }
+
+ /// Creates a new span with the same line/column information as `self` but
+ /// that resolves symbols as though it were at `other`.
+ pub fn resolved_at(&self, other: Span) -> Span {
+ Span::_new(self.inner.resolved_at(other.inner))
+ }
+
+ /// Creates a new span with the same name resolution behavior as `self` but
+ /// with the line/column information of `other`.
+ pub fn located_at(&self, other: Span) -> Span {
+ Span::_new(self.inner.located_at(other.inner))
+ }
+
+ /// Convert `proc_macro2::Span` to `proc_macro::Span`.
+ ///
+ /// This method is available when building with a nightly compiler, or when
+ /// building with rustc 1.29+ *without* semver exempt features.
+ ///
+ /// # Panics
+ ///
+ /// Panics if called from outside of a procedural macro. Unlike
+ /// `proc_macro2::Span`, the `proc_macro::Span` type can only exist within
+ /// the context of a procedural macro invocation.
+ #[cfg(wrap_proc_macro)]
+ pub fn unwrap(self) -> proc_macro::Span {
+ self.inner.unwrap()
+ }
+
+ // Soft deprecated. Please use Span::unwrap.
+ #[cfg(wrap_proc_macro)]
+ #[doc(hidden)]
+ pub fn unstable(self) -> proc_macro::Span {
+ self.unwrap()
+ }
+
+ /// The original source file into which this span points.
+ ///
+ /// This method is semver exempt and not exposed by default.
+ #[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))]
+ #[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))]
+ pub fn source_file(&self) -> SourceFile {
+ SourceFile::_new(self.inner.source_file())
+ }
+
+ /// Returns the span's byte position range in the source file.
+ ///
+ /// This method requires the `"span-locations"` feature to be enabled.
+ ///
+ /// When executing in a procedural macro context, the returned range is only
+ /// accurate if compiled with a nightly toolchain. The stable toolchain does
+ /// not have this information available. When executing outside of a
+ /// procedural macro, such as main.rs or build.rs, the byte range is always
+ /// accurate regardless of toolchain.
+ #[cfg(span_locations)]
+ #[cfg_attr(docsrs, doc(cfg(feature = "span-locations")))]
+ pub fn byte_range(&self) -> Range<usize> {
+ self.inner.byte_range()
+ }
+
+ /// Get the starting line/column in the source file for this span.
+ ///
+ /// This method requires the `"span-locations"` feature to be enabled.
+ ///
+ /// When executing in a procedural macro context, the returned line/column
+ /// are only meaningful if compiled with a nightly toolchain. The stable
+ /// toolchain does not have this information available. When executing
+ /// 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(docsrs, doc(cfg(feature = "span-locations")))]
+ pub fn start(&self) -> LineColumn {
+ self.inner.start()
+ }
+
+ /// Get the ending line/column in the source file for this span.
+ ///
+ /// This method requires the `"span-locations"` feature to be enabled.
+ ///
+ /// When executing in a procedural macro context, the returned line/column
+ /// are only meaningful if compiled with a nightly toolchain. The stable
+ /// toolchain does not have this information available. When executing
+ /// 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(docsrs, doc(cfg(feature = "span-locations")))]
+ pub fn end(&self) -> LineColumn {
+ self.inner.end()
+ }
+
+ /// Create a new span encompassing `self` and `other`.
+ ///
+ /// Returns `None` if `self` and `other` are from different files.
+ ///
+ /// Warning: the underlying [`proc_macro::Span::join`] method is
+ /// nightly-only. When called from within a procedural macro not using a
+ /// nightly compiler, this method will always return `None`.
+ ///
+ /// [`proc_macro::Span::join`]: https://doc.rust-lang.org/proc_macro/struct.Span.html#method.join
+ pub fn join(&self, other: Span) -> Option<Span> {
+ self.inner.join(other.inner).map(Span::_new)
+ }
+
+ /// Compares two spans to see if they're equal.
+ ///
+ /// This method is semver exempt and not exposed by default.
+ #[cfg(procmacro2_semver_exempt)]
+ #[cfg_attr(docsrs, doc(cfg(procmacro2_semver_exempt)))]
+ pub fn eq(&self, other: &Span) -> bool {
+ self.inner.eq(&other.inner)
+ }
+
+ /// Returns the source text behind a span. This preserves the original
+ /// source code, including spaces and comments. It only returns a result if
+ /// the span corresponds to real source code.
+ ///
+ /// Note: The observable result of a macro should only rely on the tokens
+ /// and not on this source text. The result of this function is a best
+ /// effort to be used for diagnostics only.
+ pub fn source_text(&self) -> Option<String> {
+ self.inner.source_text()
+ }
+}
+
+/// Prints a span in a form convenient for debugging.
+impl Debug for Span {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.inner, f)
+ }
+}
+
+/// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`).
+#[derive(Clone)]
+pub enum TokenTree {
+ /// A token stream surrounded by bracket delimiters.
+ Group(Group),
+ /// An identifier.
+ Ident(Ident),
+ /// A single punctuation character (`+`, `,`, `$`, etc.).
+ Punct(Punct),
+ /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc.
+ Literal(Literal),
+}
+
+impl TokenTree {
+ /// Returns the span of this tree, delegating to the `span` method of
+ /// the contained token or a delimited stream.
+ pub fn span(&self) -> Span {
+ match self {
+ TokenTree::Group(t) => t.span(),
+ TokenTree::Ident(t) => t.span(),
+ TokenTree::Punct(t) => t.span(),
+ TokenTree::Literal(t) => t.span(),
+ }
+ }
+
+ /// Configures the span for *only this token*.
+ ///
+ /// Note that if this token is a `Group` then this method will not configure
+ /// the span of each of the internal tokens, this will simply delegate to
+ /// the `set_span` method of each variant.
+ pub fn set_span(&mut self, span: Span) {
+ match self {
+ TokenTree::Group(t) => t.set_span(span),
+ TokenTree::Ident(t) => t.set_span(span),
+ TokenTree::Punct(t) => t.set_span(span),
+ TokenTree::Literal(t) => t.set_span(span),
+ }
+ }
+}
+
+impl From<Group> for TokenTree {
+ fn from(g: Group) -> Self {
+ TokenTree::Group(g)
+ }
+}
+
+impl From<Ident> for TokenTree {
+ fn from(g: Ident) -> Self {
+ TokenTree::Ident(g)
+ }
+}
+
+impl From<Punct> for TokenTree {
+ fn from(g: Punct) -> Self {
+ TokenTree::Punct(g)
+ }
+}
+
+impl From<Literal> for TokenTree {
+ fn from(g: Literal) -> Self {
+ TokenTree::Literal(g)
+ }
+}
+
+/// Prints the token tree as a string that is supposed to be losslessly
+/// convertible back into the same token tree (modulo spans), except for
+/// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative
+/// numeric literals.
+impl Display for TokenTree {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ TokenTree::Group(t) => Display::fmt(t, f),
+ TokenTree::Ident(t) => Display::fmt(t, f),
+ TokenTree::Punct(t) => Display::fmt(t, f),
+ TokenTree::Literal(t) => Display::fmt(t, f),
+ }
+ }
+}
+
+/// Prints token tree in a form convenient for debugging.
+impl Debug for TokenTree {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ // Each of these has the name in the struct type in the derived debug,
+ // so don't bother with an extra layer of indirection
+ match self {
+ TokenTree::Group(t) => Debug::fmt(t, f),
+ TokenTree::Ident(t) => {
+ let mut debug = f.debug_struct("Ident");
+ debug.field("sym", &format_args!("{}", t));
+ imp::debug_span_field_if_nontrivial(&mut debug, t.span().inner);
+ debug.finish()
+ }
+ TokenTree::Punct(t) => Debug::fmt(t, f),
+ TokenTree::Literal(t) => Debug::fmt(t, f),
+ }
+ }
+}
+
+/// A delimited token stream.
+///
+/// A `Group` internally contains a `TokenStream` which is surrounded by
+/// `Delimiter`s.
+#[derive(Clone)]
+pub struct Group {
+ inner: imp::Group,
+}
+
+/// Describes how a sequence of token trees is delimited.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Delimiter {
+ /// `( ... )`
+ Parenthesis,
+ /// `{ ... }`
+ Brace,
+ /// `[ ... ]`
+ Bracket,
+ /// `∅ ... ∅`
+ ///
+ /// 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`.
+ /// Invisible delimiters may not survive roundtrip of a token stream through
+ /// a string.
+ ///
+ /// <div class="warning">
+ ///
+ /// 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).
+ ///
+ /// </div>
+ None,
+}
+
+impl Group {
+ fn _new(inner: imp::Group) -> Self {
+ Group { inner }
+ }
+
+ fn _new_fallback(inner: fallback::Group) -> Self {
+ Group {
+ inner: inner.into(),
+ }
+ }
+
+ /// Creates a new `Group` with the given delimiter and token stream.
+ ///
+ /// This constructor will set the span for this group to
+ /// `Span::call_site()`. To change the span you can use the `set_span`
+ /// method below.
+ pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self {
+ Group {
+ inner: imp::Group::new(delimiter, stream.inner),
+ }
+ }
+
+ /// Returns the punctuation used as the delimiter for this group: a set of
+ /// parentheses, square brackets, or curly braces.
+ pub fn delimiter(&self) -> Delimiter {
+ self.inner.delimiter()
+ }
+
+ /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
+ ///
+ /// Note that the returned token stream does not include the delimiter
+ /// returned above.
+ pub fn stream(&self) -> TokenStream {
+ TokenStream::_new(self.inner.stream())
+ }
+
+ /// Returns the span for the delimiters of this token stream, spanning the
+ /// entire `Group`.
+ ///
+ /// ```text
+ /// pub fn span(&self) -> Span {
+ /// ^^^^^^^
+ /// ```
+ pub fn span(&self) -> Span {
+ Span::_new(self.inner.span())
+ }
+
+ /// Returns the span pointing to the opening delimiter of this group.
+ ///
+ /// ```text
+ /// pub fn span_open(&self) -> Span {
+ /// ^
+ /// ```
+ pub fn span_open(&self) -> Span {
+ Span::_new(self.inner.span_open())
+ }
+
+ /// Returns the span pointing to the closing delimiter of this group.
+ ///
+ /// ```text
+ /// pub fn span_close(&self) -> Span {
+ /// ^
+ /// ```
+ pub fn span_close(&self) -> Span {
+ Span::_new(self.inner.span_close())
+ }
+
+ /// Returns an object that holds this group's `span_open()` and
+ /// `span_close()` together (in a more compact representation than holding
+ /// those 2 spans individually).
+ pub fn delim_span(&self) -> DelimSpan {
+ DelimSpan::new(&self.inner)
+ }
+
+ /// Configures the span for this `Group`'s delimiters, but not its internal
+ /// tokens.
+ ///
+ /// This method will **not** set the span of all the internal tokens spanned
+ /// by this group, but rather it will only set the span of the delimiter
+ /// tokens at the level of the `Group`.
+ pub fn set_span(&mut self, span: Span) {
+ self.inner.set_span(span.inner);
+ }
+}
+
+/// Prints the group as a string that should be losslessly convertible back
+/// into the same group (modulo spans), except for possibly `TokenTree::Group`s
+/// with `Delimiter::None` delimiters.
+impl Display for Group {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.inner, formatter)
+ }
+}
+
+impl Debug for Group {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.inner, formatter)
+ }
+}
+
+/// A `Punct` is a single punctuation character like `+`, `-` or `#`.
+///
+/// Multicharacter operators like `+=` are represented as two instances of
+/// `Punct` with different forms of `Spacing` returned.
+#[derive(Clone)]
+pub struct Punct {
+ ch: char,
+ spacing: Spacing,
+ span: Span,
+}
+
+/// Whether a `Punct` is followed immediately by another `Punct` or followed by
+/// another token or whitespace.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Spacing {
+ /// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`.
+ Alone,
+ /// E.g. `+` is `Joint` in `+=` or `'` is `Joint` in `'#`.
+ ///
+ /// Additionally, single quote `'` can join with identifiers to form
+ /// lifetimes `'ident`.
+ Joint,
+}
+
+impl Punct {
+ /// Creates a new `Punct` from the given character and spacing.
+ ///
+ /// The `ch` argument must be a valid punctuation character permitted by the
+ /// language, otherwise the function will panic.
+ ///
+ /// 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(),
+ }
+ }
+
+ /// Returns the value of this punctuation character as `char`.
+ pub fn as_char(&self) -> char {
+ self.ch
+ }
+
+ /// Returns the spacing of this punctuation character, indicating whether
+ /// it's immediately followed by another `Punct` in the token stream, so
+ /// they can potentially be combined into a multicharacter operator
+ /// (`Joint`), or it's followed by some other token or whitespace (`Alone`)
+ /// so the operator has certainly ended.
+ pub fn spacing(&self) -> Spacing {
+ self.spacing
+ }
+
+ /// Returns the span for this punctuation character.
+ pub fn span(&self) -> Span {
+ self.span
+ }
+
+ /// Configure the span for this punctuation character.
+ pub fn set_span(&mut self, span: Span) {
+ self.span = span;
+ }
+}
+
+/// Prints the punctuation character as a string that should be losslessly
+/// convertible back into the same character.
+impl Display for Punct {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.ch, f)
+ }
+}
+
+impl Debug for Punct {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ let mut debug = fmt.debug_struct("Punct");
+ debug.field("char", &self.ch);
+ debug.field("spacing", &self.spacing);
+ imp::debug_span_field_if_nontrivial(&mut debug, self.span.inner);
+ debug.finish()
+ }
+}
+
+/// A word of Rust code, which may be a keyword or legal variable name.
+///
+/// An identifier consists of at least one Unicode code point, the first of
+/// which has the XID_Start property and the rest of which have the XID_Continue
+/// property.
+///
+/// - The empty string is not an identifier. Use `Option<Ident>`.
+/// - A lifetime is not an identifier. Use `syn::Lifetime` instead.
+///
+/// An identifier constructed with `Ident::new` is permitted to be a Rust
+/// keyword, though parsing one through its [`Parse`] implementation rejects
+/// Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the
+/// behaviour of `Ident::new`.
+///
+/// [`Parse`]: https://docs.rs/syn/2.0/syn/parse/trait.Parse.html
+///
+/// # Examples
+///
+/// A new ident can be created from a string using the `Ident::new` function.
+/// A span must be provided explicitly which governs the name resolution
+/// behavior of the resulting identifier.
+///
+/// ```
+/// use proc_macro2::{Ident, Span};
+///
+/// fn main() {
+/// let call_ident = Ident::new("calligraphy", Span::call_site());
+///
+/// println!("{}", call_ident);
+/// }
+/// ```
+///
+/// An ident can be interpolated into a token stream using the `quote!` macro.
+///
+/// ```
+/// use proc_macro2::{Ident, Span};
+/// use quote::quote;
+///
+/// fn main() {
+/// let ident = Ident::new("demo", Span::call_site());
+///
+/// // Create a variable binding whose name is this ident.
+/// let expanded = quote! { let #ident = 10; };
+///
+/// // Create a variable binding with a slightly different name.
+/// let temp_ident = Ident::new(&format!("new_{}", ident), Span::call_site());
+/// let expanded = quote! { let #temp_ident = 10; };
+/// }
+/// ```
+///
+/// A string representation of the ident is available through the `to_string()`
+/// method.
+///
+/// ```
+/// # use proc_macro2::{Ident, Span};
+/// #
+/// # let ident = Ident::new("another_identifier", Span::call_site());
+/// #
+/// // Examine the ident as a string.
+/// let ident_string = ident.to_string();
+/// if ident_string.len() > 60 {
+/// println!("Very long identifier: {}", ident_string)
+/// }
+/// ```
+#[derive(Clone)]
+pub struct Ident {
+ inner: imp::Ident,
+ _marker: ProcMacroAutoTraits,
+}
+
+impl Ident {
+ fn _new(inner: imp::Ident) -> Self {
+ Ident {
+ inner,
+ _marker: MARKER,
+ }
+ }
+
+ /// Creates a new `Ident` with the given `string` as well as the specified
+ /// `span`.
+ ///
+ /// The `string` argument must be a valid identifier permitted by the
+ /// language, otherwise the function will panic.
+ ///
+ /// Note that `span`, currently in rustc, configures the hygiene information
+ /// for this identifier.
+ ///
+ /// As of this time `Span::call_site()` explicitly opts-in to "call-site"
+ /// hygiene meaning that identifiers created with this span will be resolved
+ /// as if they were written directly at the location of the macro call, and
+ /// other code at the macro call site will be able to refer to them as well.
+ ///
+ /// Later spans like `Span::def_site()` will allow to opt-in to
+ /// "definition-site" hygiene meaning that identifiers created with this
+ /// span will be resolved at the location of the macro definition and other
+ /// code at the macro call site will not be able to refer to them.
+ ///
+ /// Due to the current importance of hygiene this constructor, unlike other
+ /// tokens, requires a `Span` to be specified at construction.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the input string is neither a keyword nor a legal variable
+ /// name. If you are not sure whether the string contains an identifier and
+ /// need to handle an error case, use
+ /// <a href="https://docs.rs/syn/2.0/syn/fn.parse_str.html"><code
+ /// style="padding-right:0;">syn::parse_str</code></a><code
+ /// style="padding-left:0;">::<Ident></code>
+ /// rather than `Ident::new`.
+ #[track_caller]
+ pub fn new(string: &str, span: Span) -> Self {
+ Ident::_new(imp::Ident::new_checked(string, span.inner))
+ }
+
+ /// Same as `Ident::new`, but creates a raw identifier (`r#ident`). The
+ /// `string` argument must be a valid identifier permitted by the language
+ /// (including keywords, e.g. `fn`). Keywords which are usable in path
+ /// segments (e.g. `self`, `super`) are not supported, and will cause a
+ /// panic.
+ #[track_caller]
+ pub fn new_raw(string: &str, span: Span) -> Self {
+ Ident::_new(imp::Ident::new_raw_checked(string, span.inner))
+ }
+
+ /// Returns the span of this `Ident`.
+ pub fn span(&self) -> Span {
+ Span::_new(self.inner.span())
+ }
+
+ /// Configures the span of this `Ident`, possibly changing its hygiene
+ /// context.
+ pub fn set_span(&mut self, span: Span) {
+ self.inner.set_span(span.inner);
+ }
+}
+
+impl PartialEq for Ident {
+ fn eq(&self, other: &Ident) -> bool {
+ self.inner == other.inner
+ }
+}
+
+impl<T> PartialEq<T> for Ident
+where
+ T: ?Sized + AsRef<str>,
+{
+ fn eq(&self, other: &T) -> bool {
+ self.inner == other
+ }
+}
+
+impl Eq for Ident {}
+
+impl PartialOrd for Ident {
+ fn partial_cmp(&self, other: &Ident) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for Ident {
+ fn cmp(&self, other: &Ident) -> Ordering {
+ self.to_string().cmp(&other.to_string())
+ }
+}
+
+impl Hash for Ident {
+ fn hash<H: Hasher>(&self, hasher: &mut H) {
+ self.to_string().hash(hasher);
+ }
+}
+
+/// Prints the identifier as a string that should be losslessly convertible back
+/// into the same identifier.
+impl Display for Ident {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.inner, f)
+ }
+}
+
+impl Debug for Ident {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.inner, f)
+ }
+}
+
+/// A literal string (`"hello"`), byte string (`b"hello"`), character (`'a'`),
+/// byte character (`b'a'`), an integer or floating point number with or without
+/// a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
+///
+/// Boolean literals like `true` and `false` do not belong here, they are
+/// `Ident`s.
+#[derive(Clone)]
+pub struct Literal {
+ inner: imp::Literal,
+ _marker: ProcMacroAutoTraits,
+}
+
+macro_rules! suffixed_int_literals {
+ ($($name:ident => $kind:ident,)*) => ($(
+ /// Creates a new suffixed integer literal with the specified value.
+ ///
+ /// This function will create an integer like `1u32` where the integer
+ /// value specified is the first part of the token and the integral is
+ /// also suffixed at the end. Literals created from negative numbers may
+ /// not survive roundtrips through `TokenStream` or strings and may be
+ /// broken into two tokens (`-` and positive literal).
+ ///
+ /// Literals created through this method have the `Span::call_site()`
+ /// span by default, which can be configured with the `set_span` method
+ /// below.
+ pub fn $name(n: $kind) -> Literal {
+ Literal::_new(imp::Literal::$name(n))
+ }
+ )*)
+}
+
+macro_rules! unsuffixed_int_literals {
+ ($($name:ident => $kind:ident,)*) => ($(
+ /// Creates a new unsuffixed integer literal with the specified value.
+ ///
+ /// This function will create an integer like `1` where the integer
+ /// value specified is the first part of the token. No suffix is
+ /// specified on this token, meaning that invocations like
+ /// `Literal::i8_unsuffixed(1)` are equivalent to
+ /// `Literal::u32_unsuffixed(1)`. Literals created from negative numbers
+ /// may not survive roundtrips through `TokenStream` or strings and may
+ /// be broken into two tokens (`-` and positive literal).
+ ///
+ /// Literals created through this method have the `Span::call_site()`
+ /// span by default, which can be configured with the `set_span` method
+ /// below.
+ pub fn $name(n: $kind) -> Literal {
+ Literal::_new(imp::Literal::$name(n))
+ }
+ )*)
+}
+
+impl Literal {
+ fn _new(inner: imp::Literal) -> Self {
+ Literal {
+ inner,
+ _marker: MARKER,
+ }
+ }
+
+ fn _new_fallback(inner: fallback::Literal) -> Self {
+ Literal {
+ inner: inner.into(),
+ _marker: MARKER,
+ }
+ }
+
+ suffixed_int_literals! {
+ u8_suffixed => u8,
+ u16_suffixed => u16,
+ u32_suffixed => u32,
+ u64_suffixed => u64,
+ u128_suffixed => u128,
+ usize_suffixed => usize,
+ i8_suffixed => i8,
+ i16_suffixed => i16,
+ i32_suffixed => i32,
+ i64_suffixed => i64,
+ i128_suffixed => i128,
+ isize_suffixed => isize,
+ }
+
+ unsuffixed_int_literals! {
+ u8_unsuffixed => u8,
+ u16_unsuffixed => u16,
+ u32_unsuffixed => u32,
+ u64_unsuffixed => u64,
+ u128_unsuffixed => u128,
+ usize_unsuffixed => usize,
+ i8_unsuffixed => i8,
+ i16_unsuffixed => i16,
+ i32_unsuffixed => i32,
+ i64_unsuffixed => i64,
+ i128_unsuffixed => i128,
+ isize_unsuffixed => isize,
+ }
+
+ /// Creates a new unsuffixed floating-point literal.
+ ///
+ /// This constructor is similar to those like `Literal::i8_unsuffixed` where
+ /// the float's value is emitted directly into the token but no suffix is
+ /// used, so it may be inferred to be a `f64` later in the compiler.
+ /// Literals created from negative numbers may not survive round-trips
+ /// through `TokenStream` or strings and may be broken into two tokens (`-`
+ /// and positive literal).
+ ///
+ /// # Panics
+ ///
+ /// This function requires that the specified float is finite, for example
+ /// if it is infinity or NaN this function will panic.
+ pub fn f64_unsuffixed(f: f64) -> Literal {
+ assert!(f.is_finite());
+ Literal::_new(imp::Literal::f64_unsuffixed(f))
+ }
+
+ /// Creates a new suffixed floating-point literal.
+ ///
+ /// This constructor will create a literal like `1.0f64` where the value
+ /// specified is the preceding part of the token and `f64` is the suffix of
+ /// the token. This token will always be inferred to be an `f64` in the
+ /// compiler. Literals created from negative numbers may not survive
+ /// round-trips through `TokenStream` or strings and may be broken into two
+ /// tokens (`-` and positive literal).
+ ///
+ /// # Panics
+ ///
+ /// This function requires that the specified float is finite, for example
+ /// if it is infinity or NaN this function will panic.
+ pub fn f64_suffixed(f: f64) -> Literal {
+ assert!(f.is_finite());
+ Literal::_new(imp::Literal::f64_suffixed(f))
+ }
+
+ /// Creates a new unsuffixed floating-point literal.
+ ///
+ /// This constructor is similar to those like `Literal::i8_unsuffixed` where
+ /// the float's value is emitted directly into the token but no suffix is
+ /// used, so it may be inferred to be a `f64` later in the compiler.
+ /// Literals created from negative numbers may not survive round-trips
+ /// through `TokenStream` or strings and may be broken into two tokens (`-`
+ /// and positive literal).
+ ///
+ /// # Panics
+ ///
+ /// This function requires that the specified float is finite, for example
+ /// if it is infinity or NaN this function will panic.
+ pub fn f32_unsuffixed(f: f32) -> Literal {
+ assert!(f.is_finite());
+ Literal::_new(imp::Literal::f32_unsuffixed(f))
+ }
+
+ /// Creates a new suffixed floating-point literal.
+ ///
+ /// This constructor will create a literal like `1.0f32` where the value
+ /// specified is the preceding part of the token and `f32` is the suffix of
+ /// the token. This token will always be inferred to be an `f32` in the
+ /// compiler. Literals created from negative numbers may not survive
+ /// round-trips through `TokenStream` or strings and may be broken into two
+ /// tokens (`-` and positive literal).
+ ///
+ /// # Panics
+ ///
+ /// This function requires that the specified float is finite, for example
+ /// if it is infinity or NaN this function will panic.
+ pub fn f32_suffixed(f: f32) -> Literal {
+ assert!(f.is_finite());
+ Literal::_new(imp::Literal::f32_suffixed(f))
+ }
+
+ /// String literal.
+ pub fn string(string: &str) -> Literal {
+ Literal::_new(imp::Literal::string(string))
+ }
+
+ /// Character literal.
+ pub fn character(ch: char) -> Literal {
+ Literal::_new(imp::Literal::character(ch))
+ }
+
+ /// Byte character literal.
+ pub fn byte_character(byte: u8) -> Literal {
+ Literal::_new(imp::Literal::byte_character(byte))
+ }
+
+ /// Byte string literal.
+ pub fn byte_string(bytes: &[u8]) -> Literal {
+ Literal::_new(imp::Literal::byte_string(bytes))
+ }
+
+ /// C string literal.
+ pub fn c_string(string: &CStr) -> Literal {
+ Literal::_new(imp::Literal::c_string(string))
+ }
+
+ /// Returns the span encompassing this literal.
+ pub fn span(&self) -> Span {
+ Span::_new(self.inner.span())
+ }
+
+ /// Configures the span associated for this literal.
+ pub fn set_span(&mut self, span: Span) {
+ self.inner.set_span(span.inner);
+ }
+
+ /// Returns a `Span` that is a subset of `self.span()` containing only
+ /// the source bytes in range `range`. Returns `None` if the would-be
+ /// trimmed span is outside the bounds of `self`.
+ ///
+ /// Warning: the underlying [`proc_macro::Literal::subspan`] method is
+ /// nightly-only. When called from within a procedural macro not using a
+ /// nightly compiler, this method will always return `None`.
+ ///
+ /// [`proc_macro::Literal::subspan`]: https://doc.rust-lang.org/proc_macro/struct.Literal.html#method.subspan
+ pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
+ self.inner.subspan(range).map(Span::_new)
+ }
+
+ // Intended for the `quote!` macro to use when constructing a proc-macro2
+ // token out of a macro_rules $:literal token, which is already known to be
+ // a valid literal. This avoids reparsing/validating the literal's string
+ // representation. This is not public API other than for quote.
+ #[doc(hidden)]
+ pub unsafe fn from_str_unchecked(repr: &str) -> Self {
+ Literal::_new(unsafe { imp::Literal::from_str_unchecked(repr) })
+ }
+}
+
+impl FromStr for Literal {
+ type Err = LexError;
+
+ fn from_str(repr: &str) -> Result<Self, LexError> {
+ repr.parse().map(Literal::_new).map_err(|inner| LexError {
+ inner,
+ _marker: MARKER,
+ })
+ }
+}
+
+impl Debug for Literal {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.inner, f)
+ }
+}
+
+impl Display for Literal {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.inner, f)
+ }
+}
+
+/// Public implementation details for the `TokenStream` type, such as iterators.
+pub mod token_stream {
+ use crate::marker::{ProcMacroAutoTraits, MARKER};
+ use crate::{imp, TokenTree};
+ use core::fmt::{self, Debug};
+
+ pub use crate::TokenStream;
+
+ /// An iterator over `TokenStream`'s `TokenTree`s.
+ ///
+ /// The iteration is "shallow", e.g. the iterator doesn't recurse into
+ /// delimited groups, and returns whole groups as token trees.
+ #[derive(Clone)]
+ pub struct IntoIter {
+ inner: imp::TokenTreeIter,
+ _marker: ProcMacroAutoTraits,
+ }
+
+ impl Iterator for IntoIter {
+ type Item = TokenTree;
+
+ fn next(&mut self) -> Option<TokenTree> {
+ self.inner.next()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+ }
+
+ impl Debug for IntoIter {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("TokenStream ")?;
+ f.debug_list().entries(self.clone()).finish()
+ }
+ }
+
+ impl IntoIterator for TokenStream {
+ type Item = TokenTree;
+ type IntoIter = IntoIter;
+
+ fn into_iter(self) -> IntoIter {
+ IntoIter {
+ inner: self.inner.into_iter(),
+ _marker: MARKER,
+ }
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/src/location.rs b/rust/hw/char/pl011/vendor/proc-macro2/src/location.rs
new file mode 100644
index 0000000000..7190e2d052
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/src/location.rs
@@ -0,0 +1,29 @@
+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(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
+ /// (inclusive).
+ pub line: usize,
+ /// The 0-indexed column (in UTF-8 characters) in the source file on which
+ /// the span starts or ends (inclusive).
+ pub column: usize,
+}
+
+impl Ord for LineColumn {
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.line
+ .cmp(&other.line)
+ .then(self.column.cmp(&other.column))
+ }
+}
+
+impl PartialOrd for LineColumn {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/src/marker.rs b/rust/hw/char/pl011/vendor/proc-macro2/src/marker.rs
new file mode 100644
index 0000000000..23b94ce6fa
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/src/marker.rs
@@ -0,0 +1,17 @@
+use alloc::rc::Rc;
+use core::marker::PhantomData;
+use core::panic::{RefUnwindSafe, UnwindSafe};
+
+// Zero sized marker with the correct set of autotrait impls we want all proc
+// macro types to have.
+#[derive(Copy, Clone)]
+#[cfg_attr(
+ all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)),
+ derive(PartialEq, Eq)
+)]
+pub(crate) struct ProcMacroAutoTraits(PhantomData<Rc<()>>);
+
+pub(crate) const MARKER: ProcMacroAutoTraits = ProcMacroAutoTraits(PhantomData);
+
+impl UnwindSafe for ProcMacroAutoTraits {}
+impl RefUnwindSafe for ProcMacroAutoTraits {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/src/parse.rs b/rust/hw/char/pl011/vendor/proc-macro2/src/parse.rs
new file mode 100644
index 0000000000..07239bc3ad
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/src/parse.rs
@@ -0,0 +1,996 @@
+use crate::fallback::{
+ self, is_ident_continue, is_ident_start, Group, LexError, Literal, Span, TokenStream,
+ TokenStreamBuilder,
+};
+use crate::{Delimiter, Punct, Spacing, TokenTree};
+use core::char;
+use core::str::{Bytes, CharIndices, Chars};
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub(crate) struct Cursor<'a> {
+ pub rest: &'a str,
+ #[cfg(span_locations)]
+ pub off: u32,
+}
+
+impl<'a> Cursor<'a> {
+ pub fn advance(&self, bytes: usize) -> Cursor<'a> {
+ let (_front, rest) = self.rest.split_at(bytes);
+ Cursor {
+ rest,
+ #[cfg(span_locations)]
+ off: self.off + _front.chars().count() as u32,
+ }
+ }
+
+ pub fn starts_with(&self, s: &str) -> bool {
+ self.rest.starts_with(s)
+ }
+
+ pub fn starts_with_char(&self, ch: char) -> bool {
+ self.rest.starts_with(ch)
+ }
+
+ pub fn starts_with_fn<Pattern>(&self, f: Pattern) -> bool
+ where
+ Pattern: FnMut(char) -> bool,
+ {
+ self.rest.starts_with(f)
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.rest.is_empty()
+ }
+
+ fn len(&self) -> usize {
+ self.rest.len()
+ }
+
+ fn as_bytes(&self) -> &'a [u8] {
+ self.rest.as_bytes()
+ }
+
+ fn bytes(&self) -> Bytes<'a> {
+ self.rest.bytes()
+ }
+
+ fn chars(&self) -> Chars<'a> {
+ self.rest.chars()
+ }
+
+ fn char_indices(&self) -> CharIndices<'a> {
+ self.rest.char_indices()
+ }
+
+ fn parse(&self, tag: &str) -> Result<Cursor<'a>, Reject> {
+ if self.starts_with(tag) {
+ Ok(self.advance(tag.len()))
+ } else {
+ Err(Reject)
+ }
+ }
+}
+
+pub(crate) struct Reject;
+type PResult<'a, O> = Result<(Cursor<'a>, O), Reject>;
+
+fn skip_whitespace(input: Cursor) -> Cursor {
+ let mut s = input;
+
+ while !s.is_empty() {
+ let byte = s.as_bytes()[0];
+ if byte == b'/' {
+ if s.starts_with("//")
+ && (!s.starts_with("///") || s.starts_with("////"))
+ && !s.starts_with("//!")
+ {
+ let (cursor, _) = take_until_newline_or_eof(s);
+ s = cursor;
+ continue;
+ } else if s.starts_with("/**/") {
+ s = s.advance(4);
+ continue;
+ } else if s.starts_with("/*")
+ && (!s.starts_with("/**") || s.starts_with("/***"))
+ && !s.starts_with("/*!")
+ {
+ match block_comment(s) {
+ Ok((rest, _)) => {
+ s = rest;
+ continue;
+ }
+ Err(Reject) => return s,
+ }
+ }
+ }
+ match byte {
+ b' ' | 0x09..=0x0d => {
+ s = s.advance(1);
+ continue;
+ }
+ b if b.is_ascii() => {}
+ _ => {
+ let ch = s.chars().next().unwrap();
+ if is_whitespace(ch) {
+ s = s.advance(ch.len_utf8());
+ continue;
+ }
+ }
+ }
+ return s;
+ }
+ s
+}
+
+fn block_comment(input: Cursor) -> PResult<&str> {
+ if !input.starts_with("/*") {
+ return Err(Reject);
+ }
+
+ let mut depth = 0usize;
+ let bytes = input.as_bytes();
+ let mut i = 0usize;
+ let upper = bytes.len() - 1;
+
+ while i < upper {
+ if bytes[i] == b'/' && bytes[i + 1] == b'*' {
+ depth += 1;
+ i += 1; // eat '*'
+ } else if bytes[i] == b'*' && bytes[i + 1] == b'/' {
+ depth -= 1;
+ if depth == 0 {
+ return Ok((input.advance(i + 2), &input.rest[..i + 2]));
+ }
+ i += 1; // eat '/'
+ }
+ i += 1;
+ }
+
+ Err(Reject)
+}
+
+fn is_whitespace(ch: char) -> bool {
+ // Rust treats left-to-right mark and right-to-left mark as whitespace
+ ch.is_whitespace() || ch == '\u{200e}' || ch == '\u{200f}'
+}
+
+fn word_break(input: Cursor) -> Result<Cursor, Reject> {
+ match input.chars().next() {
+ Some(ch) if is_ident_continue(ch) => Err(Reject),
+ Some(_) | None => Ok(input),
+ }
+}
+
+// Rustc's representation of a macro expansion error in expression position or
+// type position.
+const ERROR: &str = "(/*ERROR*/)";
+
+pub(crate) fn token_stream(mut input: Cursor) -> Result<TokenStream, LexError> {
+ let mut trees = TokenStreamBuilder::new();
+ let mut stack = Vec::new();
+
+ loop {
+ input = skip_whitespace(input);
+
+ if let Ok((rest, ())) = doc_comment(input, &mut trees) {
+ input = rest;
+ continue;
+ }
+
+ #[cfg(span_locations)]
+ let lo = input.off;
+
+ let first = match input.bytes().next() {
+ Some(first) => first,
+ None => match stack.last() {
+ None => return Ok(trees.build()),
+ #[cfg(span_locations)]
+ Some((lo, _frame)) => {
+ return Err(LexError {
+ span: Span { lo: *lo, hi: *lo },
+ })
+ }
+ #[cfg(not(span_locations))]
+ Some(_frame) => return Err(LexError { span: Span {} }),
+ },
+ };
+
+ if let Some(open_delimiter) = match first {
+ b'(' if !input.starts_with(ERROR) => Some(Delimiter::Parenthesis),
+ b'[' => Some(Delimiter::Bracket),
+ b'{' => Some(Delimiter::Brace),
+ _ => None,
+ } {
+ input = input.advance(1);
+ let frame = (open_delimiter, trees);
+ #[cfg(span_locations)]
+ let frame = (lo, frame);
+ stack.push(frame);
+ trees = TokenStreamBuilder::new();
+ } else if let Some(close_delimiter) = match first {
+ b')' => Some(Delimiter::Parenthesis),
+ b']' => Some(Delimiter::Bracket),
+ b'}' => Some(Delimiter::Brace),
+ _ => None,
+ } {
+ let frame = match stack.pop() {
+ Some(frame) => frame,
+ None => return Err(lex_error(input)),
+ };
+ #[cfg(span_locations)]
+ let (lo, frame) = frame;
+ let (open_delimiter, outer) = frame;
+ if open_delimiter != close_delimiter {
+ return Err(lex_error(input));
+ }
+ input = input.advance(1);
+ let mut g = Group::new(open_delimiter, trees.build());
+ g.set_span(Span {
+ #[cfg(span_locations)]
+ lo,
+ #[cfg(span_locations)]
+ hi: input.off,
+ });
+ trees = outer;
+ trees.push_token_from_parser(TokenTree::Group(crate::Group::_new_fallback(g)));
+ } else {
+ let (rest, mut tt) = match leaf_token(input) {
+ Ok((rest, tt)) => (rest, tt),
+ Err(Reject) => return Err(lex_error(input)),
+ };
+ tt.set_span(crate::Span::_new_fallback(Span {
+ #[cfg(span_locations)]
+ lo,
+ #[cfg(span_locations)]
+ hi: rest.off,
+ }));
+ trees.push_token_from_parser(tt);
+ input = rest;
+ }
+ }
+}
+
+fn lex_error(cursor: Cursor) -> LexError {
+ #[cfg(not(span_locations))]
+ let _ = cursor;
+ LexError {
+ span: Span {
+ #[cfg(span_locations)]
+ lo: cursor.off,
+ #[cfg(span_locations)]
+ hi: cursor.off,
+ },
+ }
+}
+
+fn leaf_token(input: Cursor) -> PResult<TokenTree> {
+ if let Ok((input, l)) = literal(input) {
+ // must be parsed before ident
+ Ok((input, TokenTree::Literal(crate::Literal::_new_fallback(l))))
+ } else if let Ok((input, p)) = punct(input) {
+ Ok((input, TokenTree::Punct(p)))
+ } else if let Ok((input, i)) = ident(input) {
+ Ok((input, TokenTree::Ident(i)))
+ } else if input.starts_with(ERROR) {
+ let rest = input.advance(ERROR.len());
+ let repr = crate::Literal::_new_fallback(Literal::_new(ERROR.to_owned()));
+ Ok((rest, TokenTree::Literal(repr)))
+ } else {
+ Err(Reject)
+ }
+}
+
+fn ident(input: Cursor) -> PResult<crate::Ident> {
+ if [
+ "r\"", "r#\"", "r##", "b\"", "b\'", "br\"", "br#", "c\"", "cr\"", "cr#",
+ ]
+ .iter()
+ .any(|prefix| input.starts_with(prefix))
+ {
+ Err(Reject)
+ } else {
+ ident_any(input)
+ }
+}
+
+fn ident_any(input: Cursor) -> PResult<crate::Ident> {
+ let raw = input.starts_with("r#");
+ let rest = input.advance((raw as usize) << 1);
+
+ let (rest, sym) = ident_not_raw(rest)?;
+
+ if !raw {
+ let ident = crate::Ident::_new(crate::imp::Ident::new_unchecked(
+ sym,
+ fallback::Span::call_site(),
+ ));
+ return Ok((rest, ident));
+ }
+
+ match sym {
+ "_" | "super" | "self" | "Self" | "crate" => return Err(Reject),
+ _ => {}
+ }
+
+ let ident = crate::Ident::_new(crate::imp::Ident::new_raw_unchecked(
+ sym,
+ fallback::Span::call_site(),
+ ));
+ Ok((rest, ident))
+}
+
+fn ident_not_raw(input: Cursor) -> PResult<&str> {
+ let mut chars = input.char_indices();
+
+ match chars.next() {
+ Some((_, ch)) if is_ident_start(ch) => {}
+ _ => return Err(Reject),
+ }
+
+ let mut end = input.len();
+ for (i, ch) in chars {
+ if !is_ident_continue(ch) {
+ end = i;
+ break;
+ }
+ }
+
+ Ok((input.advance(end), &input.rest[..end]))
+}
+
+pub(crate) fn literal(input: Cursor) -> PResult<Literal> {
+ let rest = literal_nocapture(input)?;
+ let end = input.len() - rest.len();
+ Ok((rest, Literal::_new(input.rest[..end].to_string())))
+}
+
+fn literal_nocapture(input: Cursor) -> Result<Cursor, Reject> {
+ if let Ok(ok) = string(input) {
+ Ok(ok)
+ } else if let Ok(ok) = byte_string(input) {
+ Ok(ok)
+ } else if let Ok(ok) = c_string(input) {
+ Ok(ok)
+ } else if let Ok(ok) = byte(input) {
+ Ok(ok)
+ } else if let Ok(ok) = character(input) {
+ Ok(ok)
+ } else if let Ok(ok) = float(input) {
+ Ok(ok)
+ } else if let Ok(ok) = int(input) {
+ Ok(ok)
+ } else {
+ Err(Reject)
+ }
+}
+
+fn literal_suffix(input: Cursor) -> Cursor {
+ match ident_not_raw(input) {
+ Ok((input, _)) => input,
+ Err(Reject) => input,
+ }
+}
+
+fn string(input: Cursor) -> Result<Cursor, Reject> {
+ if let Ok(input) = input.parse("\"") {
+ cooked_string(input)
+ } else if let Ok(input) = input.parse("r") {
+ raw_string(input)
+ } else {
+ Err(Reject)
+ }
+}
+
+fn cooked_string(mut input: Cursor) -> Result<Cursor, Reject> {
+ let mut chars = input.char_indices();
+
+ while let Some((i, ch)) = chars.next() {
+ match ch {
+ '"' => {
+ let input = input.advance(i + 1);
+ return Ok(literal_suffix(input));
+ }
+ '\r' => match chars.next() {
+ Some((_, '\n')) => {}
+ _ => break,
+ },
+ '\\' => match chars.next() {
+ Some((_, 'x')) => {
+ backslash_x_char(&mut chars)?;
+ }
+ Some((_, 'n' | 'r' | 't' | '\\' | '\'' | '"' | '0')) => {}
+ Some((_, 'u')) => {
+ backslash_u(&mut chars)?;
+ }
+ Some((newline, ch @ ('\n' | '\r'))) => {
+ input = input.advance(newline + 1);
+ trailing_backslash(&mut input, ch as u8)?;
+ chars = input.char_indices();
+ }
+ _ => break,
+ },
+ _ch => {}
+ }
+ }
+ Err(Reject)
+}
+
+fn raw_string(input: Cursor) -> Result<Cursor, Reject> {
+ let (input, delimiter) = delimiter_of_raw_string(input)?;
+ let mut bytes = input.bytes().enumerate();
+ while let Some((i, byte)) = bytes.next() {
+ match byte {
+ b'"' if input.rest[i + 1..].starts_with(delimiter) => {
+ let rest = input.advance(i + 1 + delimiter.len());
+ return Ok(literal_suffix(rest));
+ }
+ b'\r' => match bytes.next() {
+ Some((_, b'\n')) => {}
+ _ => break,
+ },
+ _ => {}
+ }
+ }
+ Err(Reject)
+}
+
+fn byte_string(input: Cursor) -> Result<Cursor, Reject> {
+ if let Ok(input) = input.parse("b\"") {
+ cooked_byte_string(input)
+ } else if let Ok(input) = input.parse("br") {
+ raw_byte_string(input)
+ } else {
+ Err(Reject)
+ }
+}
+
+fn cooked_byte_string(mut input: Cursor) -> Result<Cursor, Reject> {
+ let mut bytes = input.bytes().enumerate();
+ while let Some((offset, b)) = bytes.next() {
+ match b {
+ b'"' => {
+ let input = input.advance(offset + 1);
+ return Ok(literal_suffix(input));
+ }
+ b'\r' => match bytes.next() {
+ Some((_, b'\n')) => {}
+ _ => break,
+ },
+ b'\\' => match bytes.next() {
+ Some((_, b'x')) => {
+ backslash_x_byte(&mut bytes)?;
+ }
+ Some((_, b'n' | b'r' | b't' | b'\\' | b'0' | b'\'' | b'"')) => {}
+ Some((newline, b @ (b'\n' | b'\r'))) => {
+ input = input.advance(newline + 1);
+ trailing_backslash(&mut input, b)?;
+ bytes = input.bytes().enumerate();
+ }
+ _ => break,
+ },
+ b if b.is_ascii() => {}
+ _ => break,
+ }
+ }
+ Err(Reject)
+}
+
+fn delimiter_of_raw_string(input: Cursor) -> PResult<&str> {
+ for (i, byte) in input.bytes().enumerate() {
+ match byte {
+ b'"' => {
+ if i > 255 {
+ // https://github.com/rust-lang/rust/pull/95251
+ return Err(Reject);
+ }
+ return Ok((input.advance(i + 1), &input.rest[..i]));
+ }
+ b'#' => {}
+ _ => break,
+ }
+ }
+ Err(Reject)
+}
+
+fn raw_byte_string(input: Cursor) -> Result<Cursor, Reject> {
+ let (input, delimiter) = delimiter_of_raw_string(input)?;
+ let mut bytes = input.bytes().enumerate();
+ while let Some((i, byte)) = bytes.next() {
+ match byte {
+ b'"' if input.rest[i + 1..].starts_with(delimiter) => {
+ let rest = input.advance(i + 1 + delimiter.len());
+ return Ok(literal_suffix(rest));
+ }
+ b'\r' => match bytes.next() {
+ Some((_, b'\n')) => {}
+ _ => break,
+ },
+ other => {
+ if !other.is_ascii() {
+ break;
+ }
+ }
+ }
+ }
+ Err(Reject)
+}
+
+fn c_string(input: Cursor) -> Result<Cursor, Reject> {
+ if let Ok(input) = input.parse("c\"") {
+ cooked_c_string(input)
+ } else if let Ok(input) = input.parse("cr") {
+ raw_c_string(input)
+ } else {
+ Err(Reject)
+ }
+}
+
+fn raw_c_string(input: Cursor) -> Result<Cursor, Reject> {
+ let (input, delimiter) = delimiter_of_raw_string(input)?;
+ let mut bytes = input.bytes().enumerate();
+ while let Some((i, byte)) = bytes.next() {
+ match byte {
+ b'"' if input.rest[i + 1..].starts_with(delimiter) => {
+ let rest = input.advance(i + 1 + delimiter.len());
+ return Ok(literal_suffix(rest));
+ }
+ b'\r' => match bytes.next() {
+ Some((_, b'\n')) => {}
+ _ => break,
+ },
+ b'\0' => break,
+ _ => {}
+ }
+ }
+ Err(Reject)
+}
+
+fn cooked_c_string(mut input: Cursor) -> Result<Cursor, Reject> {
+ let mut chars = input.char_indices();
+
+ while let Some((i, ch)) = chars.next() {
+ match ch {
+ '"' => {
+ let input = input.advance(i + 1);
+ return Ok(literal_suffix(input));
+ }
+ '\r' => match chars.next() {
+ Some((_, '\n')) => {}
+ _ => break,
+ },
+ '\\' => match chars.next() {
+ Some((_, 'x')) => {
+ backslash_x_nonzero(&mut chars)?;
+ }
+ Some((_, 'n' | 'r' | 't' | '\\' | '\'' | '"')) => {}
+ Some((_, 'u')) => {
+ if backslash_u(&mut chars)? == '\0' {
+ break;
+ }
+ }
+ Some((newline, ch @ ('\n' | '\r'))) => {
+ input = input.advance(newline + 1);
+ trailing_backslash(&mut input, ch as u8)?;
+ chars = input.char_indices();
+ }
+ _ => break,
+ },
+ '\0' => break,
+ _ch => {}
+ }
+ }
+ Err(Reject)
+}
+
+fn byte(input: Cursor) -> Result<Cursor, Reject> {
+ let input = input.parse("b'")?;
+ let mut bytes = input.bytes().enumerate();
+ let ok = match bytes.next().map(|(_, b)| b) {
+ Some(b'\\') => match bytes.next().map(|(_, b)| b) {
+ Some(b'x') => backslash_x_byte(&mut bytes).is_ok(),
+ Some(b'n' | b'r' | b't' | b'\\' | b'0' | b'\'' | b'"') => true,
+ _ => false,
+ },
+ b => b.is_some(),
+ };
+ if !ok {
+ return Err(Reject);
+ }
+ let (offset, _) = bytes.next().ok_or(Reject)?;
+ if !input.chars().as_str().is_char_boundary(offset) {
+ return Err(Reject);
+ }
+ let input = input.advance(offset).parse("'")?;
+ Ok(literal_suffix(input))
+}
+
+fn character(input: Cursor) -> Result<Cursor, Reject> {
+ let input = input.parse("'")?;
+ let mut chars = input.char_indices();
+ let ok = match chars.next().map(|(_, ch)| ch) {
+ Some('\\') => match chars.next().map(|(_, ch)| ch) {
+ Some('x') => backslash_x_char(&mut chars).is_ok(),
+ Some('u') => backslash_u(&mut chars).is_ok(),
+ Some('n' | 'r' | 't' | '\\' | '0' | '\'' | '"') => true,
+ _ => false,
+ },
+ ch => ch.is_some(),
+ };
+ if !ok {
+ return Err(Reject);
+ }
+ let (idx, _) = chars.next().ok_or(Reject)?;
+ let input = input.advance(idx).parse("'")?;
+ Ok(literal_suffix(input))
+}
+
+macro_rules! next_ch {
+ ($chars:ident @ $pat:pat) => {
+ match $chars.next() {
+ Some((_, ch)) => match ch {
+ $pat => ch,
+ _ => return Err(Reject),
+ },
+ None => return Err(Reject),
+ }
+ };
+}
+
+fn backslash_x_char<I>(chars: &mut I) -> Result<(), Reject>
+where
+ I: Iterator<Item = (usize, char)>,
+{
+ next_ch!(chars @ '0'..='7');
+ next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F');
+ Ok(())
+}
+
+fn backslash_x_byte<I>(chars: &mut I) -> Result<(), Reject>
+where
+ I: Iterator<Item = (usize, u8)>,
+{
+ next_ch!(chars @ b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F');
+ next_ch!(chars @ b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F');
+ Ok(())
+}
+
+fn backslash_x_nonzero<I>(chars: &mut I) -> Result<(), Reject>
+where
+ I: Iterator<Item = (usize, char)>,
+{
+ let first = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F');
+ let second = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F');
+ if first == '0' && second == '0' {
+ Err(Reject)
+ } else {
+ Ok(())
+ }
+}
+
+fn backslash_u<I>(chars: &mut I) -> Result<char, Reject>
+where
+ I: Iterator<Item = (usize, char)>,
+{
+ next_ch!(chars @ '{');
+ let mut value = 0;
+ let mut len = 0;
+ for (_, ch) in chars {
+ let digit = match ch {
+ '0'..='9' => ch as u8 - b'0',
+ 'a'..='f' => 10 + ch as u8 - b'a',
+ 'A'..='F' => 10 + ch as u8 - b'A',
+ '_' if len > 0 => continue,
+ '}' if len > 0 => return char::from_u32(value).ok_or(Reject),
+ _ => break,
+ };
+ if len == 6 {
+ break;
+ }
+ value *= 0x10;
+ value += u32::from(digit);
+ len += 1;
+ }
+ Err(Reject)
+}
+
+fn trailing_backslash(input: &mut Cursor, mut last: u8) -> Result<(), Reject> {
+ let mut whitespace = input.bytes().enumerate();
+ loop {
+ if last == b'\r' && whitespace.next().map_or(true, |(_, b)| b != b'\n') {
+ return Err(Reject);
+ }
+ match whitespace.next() {
+ Some((_, b @ (b' ' | b'\t' | b'\n' | b'\r'))) => {
+ last = b;
+ }
+ Some((offset, _)) => {
+ *input = input.advance(offset);
+ return Ok(());
+ }
+ None => return Err(Reject),
+ }
+ }
+}
+
+fn float(input: Cursor) -> Result<Cursor, Reject> {
+ let mut rest = float_digits(input)?;
+ if let Some(ch) = rest.chars().next() {
+ if is_ident_start(ch) {
+ rest = ident_not_raw(rest)?.0;
+ }
+ }
+ word_break(rest)
+}
+
+fn float_digits(input: Cursor) -> Result<Cursor, Reject> {
+ let mut chars = input.chars().peekable();
+ match chars.next() {
+ Some(ch) if '0' <= ch && ch <= '9' => {}
+ _ => return Err(Reject),
+ }
+
+ let mut len = 1;
+ let mut has_dot = false;
+ let mut has_exp = false;
+ while let Some(&ch) = chars.peek() {
+ match ch {
+ '0'..='9' | '_' => {
+ chars.next();
+ len += 1;
+ }
+ '.' => {
+ if has_dot {
+ break;
+ }
+ chars.next();
+ if chars
+ .peek()
+ .map_or(false, |&ch| ch == '.' || is_ident_start(ch))
+ {
+ return Err(Reject);
+ }
+ len += 1;
+ has_dot = true;
+ }
+ 'e' | 'E' => {
+ chars.next();
+ len += 1;
+ has_exp = true;
+ break;
+ }
+ _ => break,
+ }
+ }
+
+ if !(has_dot || has_exp) {
+ return Err(Reject);
+ }
+
+ if has_exp {
+ let token_before_exp = if has_dot {
+ Ok(input.advance(len - 1))
+ } else {
+ Err(Reject)
+ };
+ let mut has_sign = false;
+ let mut has_exp_value = false;
+ while let Some(&ch) = chars.peek() {
+ match ch {
+ '+' | '-' => {
+ if has_exp_value {
+ break;
+ }
+ if has_sign {
+ return token_before_exp;
+ }
+ chars.next();
+ len += 1;
+ has_sign = true;
+ }
+ '0'..='9' => {
+ chars.next();
+ len += 1;
+ has_exp_value = true;
+ }
+ '_' => {
+ chars.next();
+ len += 1;
+ }
+ _ => break,
+ }
+ }
+ if !has_exp_value {
+ return token_before_exp;
+ }
+ }
+
+ Ok(input.advance(len))
+}
+
+fn int(input: Cursor) -> Result<Cursor, Reject> {
+ let mut rest = digits(input)?;
+ if let Some(ch) = rest.chars().next() {
+ if is_ident_start(ch) {
+ rest = ident_not_raw(rest)?.0;
+ }
+ }
+ word_break(rest)
+}
+
+fn digits(mut input: Cursor) -> Result<Cursor, Reject> {
+ let base = if input.starts_with("0x") {
+ input = input.advance(2);
+ 16
+ } else if input.starts_with("0o") {
+ input = input.advance(2);
+ 8
+ } else if input.starts_with("0b") {
+ input = input.advance(2);
+ 2
+ } else {
+ 10
+ };
+
+ let mut len = 0;
+ let mut empty = true;
+ for b in input.bytes() {
+ match b {
+ b'0'..=b'9' => {
+ let digit = (b - b'0') as u64;
+ if digit >= base {
+ return Err(Reject);
+ }
+ }
+ b'a'..=b'f' => {
+ let digit = 10 + (b - b'a') as u64;
+ if digit >= base {
+ break;
+ }
+ }
+ b'A'..=b'F' => {
+ let digit = 10 + (b - b'A') as u64;
+ if digit >= base {
+ break;
+ }
+ }
+ b'_' => {
+ if empty && base == 10 {
+ return Err(Reject);
+ }
+ len += 1;
+ continue;
+ }
+ _ => break,
+ };
+ len += 1;
+ empty = false;
+ }
+ if empty {
+ Err(Reject)
+ } else {
+ Ok(input.advance(len))
+ }
+}
+
+fn punct(input: Cursor) -> PResult<Punct> {
+ let (rest, ch) = punct_char(input)?;
+ if ch == '\'' {
+ if ident_any(rest)?.0.starts_with_char('\'') {
+ Err(Reject)
+ } else {
+ Ok((rest, Punct::new('\'', Spacing::Joint)))
+ }
+ } else {
+ let kind = match punct_char(rest) {
+ Ok(_) => Spacing::Joint,
+ Err(Reject) => Spacing::Alone,
+ };
+ Ok((rest, Punct::new(ch, kind)))
+ }
+}
+
+fn punct_char(input: Cursor) -> PResult<char> {
+ if input.starts_with("//") || input.starts_with("/*") {
+ // Do not accept `/` of a comment as a punct.
+ return Err(Reject);
+ }
+
+ let mut chars = input.chars();
+ let first = match chars.next() {
+ Some(ch) => ch,
+ None => {
+ return Err(Reject);
+ }
+ };
+ let recognized = "~!@#$%^&*-=+|;:,<.>/?'";
+ if recognized.contains(first) {
+ Ok((input.advance(first.len_utf8()), first))
+ } else {
+ Err(Reject)
+ }
+}
+
+fn doc_comment<'a>(input: Cursor<'a>, trees: &mut TokenStreamBuilder) -> PResult<'a, ()> {
+ #[cfg(span_locations)]
+ let lo = input.off;
+ let (rest, (comment, inner)) = doc_comment_contents(input)?;
+ let fallback_span = Span {
+ #[cfg(span_locations)]
+ lo,
+ #[cfg(span_locations)]
+ hi: rest.off,
+ };
+ let span = crate::Span::_new_fallback(fallback_span);
+
+ let mut scan_for_bare_cr = comment;
+ while let Some(cr) = scan_for_bare_cr.find('\r') {
+ let rest = &scan_for_bare_cr[cr + 1..];
+ if !rest.starts_with('\n') {
+ return Err(Reject);
+ }
+ scan_for_bare_cr = rest;
+ }
+
+ let mut pound = Punct::new('#', Spacing::Alone);
+ pound.set_span(span);
+ trees.push_token_from_parser(TokenTree::Punct(pound));
+
+ if inner {
+ let mut bang = Punct::new('!', Spacing::Alone);
+ bang.set_span(span);
+ trees.push_token_from_parser(TokenTree::Punct(bang));
+ }
+
+ let doc_ident = crate::Ident::_new(crate::imp::Ident::new_unchecked("doc", fallback_span));
+ let mut equal = Punct::new('=', Spacing::Alone);
+ equal.set_span(span);
+ let mut literal = crate::Literal::string(comment);
+ literal.set_span(span);
+ let mut bracketed = TokenStreamBuilder::with_capacity(3);
+ bracketed.push_token_from_parser(TokenTree::Ident(doc_ident));
+ bracketed.push_token_from_parser(TokenTree::Punct(equal));
+ bracketed.push_token_from_parser(TokenTree::Literal(literal));
+ let group = Group::new(Delimiter::Bracket, bracketed.build());
+ let mut group = crate::Group::_new_fallback(group);
+ group.set_span(span);
+ trees.push_token_from_parser(TokenTree::Group(group));
+
+ Ok((rest, ()))
+}
+
+fn doc_comment_contents(input: Cursor) -> PResult<(&str, bool)> {
+ if input.starts_with("//!") {
+ let input = input.advance(3);
+ let (input, s) = take_until_newline_or_eof(input);
+ Ok((input, (s, true)))
+ } else if input.starts_with("/*!") {
+ let (input, s) = block_comment(input)?;
+ Ok((input, (&s[3..s.len() - 2], true)))
+ } else if input.starts_with("///") {
+ let input = input.advance(3);
+ if input.starts_with_char('/') {
+ return Err(Reject);
+ }
+ let (input, s) = take_until_newline_or_eof(input);
+ Ok((input, (s, false)))
+ } else if input.starts_with("/**") && !input.rest[3..].starts_with('*') {
+ let (input, s) = block_comment(input)?;
+ Ok((input, (&s[3..s.len() - 2], false)))
+ } else {
+ Err(Reject)
+ }
+}
+
+fn take_until_newline_or_eof(input: Cursor) -> (Cursor, &str) {
+ let chars = input.char_indices();
+
+ for (i, ch) in chars {
+ if ch == '\n' {
+ return (input.advance(i), &input.rest[..i]);
+ } else if ch == '\r' && input.rest[i + 1..].starts_with('\n') {
+ return (input.advance(i + 1), &input.rest[..i]);
+ }
+ }
+
+ (input.advance(input.len()), input.rest)
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/src/rcvec.rs b/rust/hw/char/pl011/vendor/proc-macro2/src/rcvec.rs
new file mode 100644
index 0000000000..37955afb11
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/src/rcvec.rs
@@ -0,0 +1,145 @@
+use alloc::rc::Rc;
+use alloc::vec;
+use core::mem;
+use core::panic::RefUnwindSafe;
+use core::slice;
+
+pub(crate) struct RcVec<T> {
+ inner: Rc<Vec<T>>,
+}
+
+pub(crate) struct RcVecBuilder<T> {
+ inner: Vec<T>,
+}
+
+pub(crate) struct RcVecMut<'a, T> {
+ inner: &'a mut Vec<T>,
+}
+
+#[derive(Clone)]
+pub(crate) struct RcVecIntoIter<T> {
+ inner: vec::IntoIter<T>,
+}
+
+impl<T> RcVec<T> {
+ pub fn is_empty(&self) -> bool {
+ self.inner.is_empty()
+ }
+
+ pub fn len(&self) -> usize {
+ self.inner.len()
+ }
+
+ pub fn iter(&self) -> slice::Iter<T> {
+ self.inner.iter()
+ }
+
+ pub fn make_mut(&mut self) -> RcVecMut<T>
+ where
+ T: Clone,
+ {
+ RcVecMut {
+ inner: Rc::make_mut(&mut self.inner),
+ }
+ }
+
+ pub fn get_mut(&mut self) -> Option<RcVecMut<T>> {
+ let inner = Rc::get_mut(&mut self.inner)?;
+ Some(RcVecMut { inner })
+ }
+
+ pub fn make_owned(mut self) -> RcVecBuilder<T>
+ where
+ T: Clone,
+ {
+ let vec = if let Some(owned) = Rc::get_mut(&mut self.inner) {
+ mem::take(owned)
+ } else {
+ Vec::clone(&self.inner)
+ };
+ RcVecBuilder { inner: vec }
+ }
+}
+
+impl<T> RcVecBuilder<T> {
+ pub fn new() -> Self {
+ RcVecBuilder { inner: Vec::new() }
+ }
+
+ pub fn with_capacity(cap: usize) -> Self {
+ RcVecBuilder {
+ inner: Vec::with_capacity(cap),
+ }
+ }
+
+ pub fn push(&mut self, element: T) {
+ self.inner.push(element);
+ }
+
+ pub fn extend(&mut self, iter: impl IntoIterator<Item = T>) {
+ self.inner.extend(iter);
+ }
+
+ pub fn as_mut(&mut self) -> RcVecMut<T> {
+ RcVecMut {
+ inner: &mut self.inner,
+ }
+ }
+
+ pub fn build(self) -> RcVec<T> {
+ RcVec {
+ inner: Rc::new(self.inner),
+ }
+ }
+}
+
+impl<'a, T> RcVecMut<'a, T> {
+ pub fn push(&mut self, element: T) {
+ self.inner.push(element);
+ }
+
+ pub fn extend(&mut self, iter: impl IntoIterator<Item = T>) {
+ self.inner.extend(iter);
+ }
+
+ pub fn pop(&mut self) -> Option<T> {
+ self.inner.pop()
+ }
+
+ pub fn as_mut(&mut self) -> RcVecMut<T> {
+ RcVecMut { inner: self.inner }
+ }
+}
+
+impl<T> Clone for RcVec<T> {
+ fn clone(&self) -> Self {
+ RcVec {
+ inner: Rc::clone(&self.inner),
+ }
+ }
+}
+
+impl<T> IntoIterator for RcVecBuilder<T> {
+ type Item = T;
+ type IntoIter = RcVecIntoIter<T>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ RcVecIntoIter {
+ inner: self.inner.into_iter(),
+ }
+ }
+}
+
+impl<T> Iterator for RcVecIntoIter<T> {
+ type Item = T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner.next()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.inner.size_hint()
+ }
+}
+
+impl<T> RefUnwindSafe for RcVec<T> where T: RefUnwindSafe {}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/src/wrapper.rs b/rust/hw/char/pl011/vendor/proc-macro2/src/wrapper.rs
new file mode 100644
index 0000000000..87e348dbb3
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/src/wrapper.rs
@@ -0,0 +1,993 @@
+use crate::detection::inside_proc_macro;
+#[cfg(span_locations)]
+use crate::location::LineColumn;
+use crate::{fallback, 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;
+
+#[derive(Clone)]
+pub(crate) enum TokenStream {
+ Compiler(DeferredTokenStream),
+ Fallback(fallback::TokenStream),
+}
+
+// Work around https://github.com/rust-lang/rust/issues/65080.
+// In `impl Extend<TokenTree> for TokenStream` which is used heavily by quote,
+// we hold on to the appended tokens and do proc_macro::TokenStream::extend as
+// late as possible to batch together consecutive uses of the Extend impl.
+#[derive(Clone)]
+pub(crate) struct DeferredTokenStream {
+ stream: proc_macro::TokenStream,
+ extra: Vec<proc_macro::TokenTree>,
+}
+
+pub(crate) enum LexError {
+ Compiler(proc_macro::LexError),
+ Fallback(fallback::LexError),
+
+ // Rustc was supposed to return a LexError, but it panicked instead.
+ // https://github.com/rust-lang/rust/issues/58736
+ CompilerPanic,
+}
+
+#[cold]
+fn mismatch(line: u32) -> ! {
+ #[cfg(procmacro2_backtrace)]
+ {
+ let backtrace = std::backtrace::Backtrace::force_capture();
+ panic!("compiler/fallback mismatch #{}\n\n{}", line, backtrace)
+ }
+ #[cfg(not(procmacro2_backtrace))]
+ {
+ panic!("compiler/fallback mismatch #{}", line)
+ }
+}
+
+impl DeferredTokenStream {
+ fn new(stream: proc_macro::TokenStream) -> Self {
+ DeferredTokenStream {
+ stream,
+ extra: Vec::new(),
+ }
+ }
+
+ fn is_empty(&self) -> bool {
+ self.stream.is_empty() && self.extra.is_empty()
+ }
+
+ fn evaluate_now(&mut self) {
+ // If-check provides a fast short circuit for the common case of `extra`
+ // being empty, which saves a round trip over the proc macro bridge.
+ // Improves macro expansion time in winrt by 6% in debug mode.
+ if !self.extra.is_empty() {
+ self.stream.extend(self.extra.drain(..));
+ }
+ }
+
+ fn into_token_stream(mut self) -> proc_macro::TokenStream {
+ self.evaluate_now();
+ self.stream
+ }
+}
+
+impl TokenStream {
+ pub fn new() -> Self {
+ if inside_proc_macro() {
+ TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new()))
+ } else {
+ TokenStream::Fallback(fallback::TokenStream::new())
+ }
+ }
+
+ pub fn is_empty(&self) -> bool {
+ match self {
+ TokenStream::Compiler(tts) => tts.is_empty(),
+ TokenStream::Fallback(tts) => tts.is_empty(),
+ }
+ }
+
+ fn unwrap_nightly(self) -> proc_macro::TokenStream {
+ match self {
+ TokenStream::Compiler(s) => s.into_token_stream(),
+ TokenStream::Fallback(_) => mismatch(line!()),
+ }
+ }
+
+ fn unwrap_stable(self) -> fallback::TokenStream {
+ match self {
+ TokenStream::Compiler(_) => mismatch(line!()),
+ TokenStream::Fallback(s) => s,
+ }
+ }
+}
+
+impl FromStr for TokenStream {
+ type Err = LexError;
+
+ fn from_str(src: &str) -> Result<TokenStream, LexError> {
+ 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<proc_macro::TokenStream, LexError> {
+ 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 {
+ TokenStream::Compiler(tts) => Display::fmt(&tts.clone().into_token_stream(), f),
+ TokenStream::Fallback(tts) => Display::fmt(tts, f),
+ }
+ }
+}
+
+impl From<proc_macro::TokenStream> for TokenStream {
+ fn from(inner: proc_macro::TokenStream) -> Self {
+ TokenStream::Compiler(DeferredTokenStream::new(inner))
+ }
+}
+
+impl From<TokenStream> 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(),
+ }
+ }
+}
+
+impl From<fallback::TokenStream> for TokenStream {
+ fn from(inner: fallback::TokenStream) -> Self {
+ TokenStream::Fallback(inner)
+ }
+}
+
+// Assumes inside_proc_macro().
+fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree {
+ match token {
+ TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(),
+ TokenTree::Punct(tt) => {
+ let spacing = match tt.spacing() {
+ Spacing::Joint => proc_macro::Spacing::Joint,
+ Spacing::Alone => proc_macro::Spacing::Alone,
+ };
+ let mut punct = proc_macro::Punct::new(tt.as_char(), spacing);
+ punct.set_span(tt.span().inner.unwrap_nightly());
+ punct.into()
+ }
+ TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(),
+ TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(),
+ }
+}
+
+impl From<TokenTree> for TokenStream {
+ fn from(token: TokenTree) -> Self {
+ if inside_proc_macro() {
+ TokenStream::Compiler(DeferredTokenStream::new(into_compiler_token(token).into()))
+ } else {
+ TokenStream::Fallback(token.into())
+ }
+ }
+}
+
+impl FromIterator<TokenTree> for TokenStream {
+ fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
+ if inside_proc_macro() {
+ TokenStream::Compiler(DeferredTokenStream::new(
+ trees.into_iter().map(into_compiler_token).collect(),
+ ))
+ } else {
+ TokenStream::Fallback(trees.into_iter().collect())
+ }
+ }
+}
+
+impl FromIterator<TokenStream> for TokenStream {
+ fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
+ let mut streams = streams.into_iter();
+ match streams.next() {
+ Some(TokenStream::Compiler(mut first)) => {
+ first.evaluate_now();
+ first.stream.extend(streams.map(|s| match s {
+ TokenStream::Compiler(s) => s.into_token_stream(),
+ TokenStream::Fallback(_) => mismatch(line!()),
+ }));
+ TokenStream::Compiler(first)
+ }
+ Some(TokenStream::Fallback(mut first)) => {
+ first.extend(streams.map(|s| match s {
+ TokenStream::Fallback(s) => s,
+ TokenStream::Compiler(_) => mismatch(line!()),
+ }));
+ TokenStream::Fallback(first)
+ }
+ None => TokenStream::new(),
+ }
+ }
+}
+
+impl Extend<TokenTree> for TokenStream {
+ fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, stream: I) {
+ match self {
+ TokenStream::Compiler(tts) => {
+ // Here is the reason for DeferredTokenStream.
+ for token in stream {
+ tts.extra.push(into_compiler_token(token));
+ }
+ }
+ TokenStream::Fallback(tts) => tts.extend(stream),
+ }
+ }
+}
+
+impl Extend<TokenStream> for TokenStream {
+ fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
+ match self {
+ TokenStream::Compiler(tts) => {
+ tts.evaluate_now();
+ tts.stream
+ .extend(streams.into_iter().map(TokenStream::unwrap_nightly));
+ }
+ TokenStream::Fallback(tts) => {
+ tts.extend(streams.into_iter().map(TokenStream::unwrap_stable));
+ }
+ }
+ }
+}
+
+impl Debug for TokenStream {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ TokenStream::Compiler(tts) => Debug::fmt(&tts.clone().into_token_stream(), f),
+ TokenStream::Fallback(tts) => Debug::fmt(tts, f),
+ }
+ }
+}
+
+impl LexError {
+ pub(crate) fn span(&self) -> Span {
+ match self {
+ LexError::Compiler(_) | LexError::CompilerPanic => Span::call_site(),
+ LexError::Fallback(e) => Span::Fallback(e.span()),
+ }
+ }
+}
+
+impl From<proc_macro::LexError> for LexError {
+ fn from(e: proc_macro::LexError) -> Self {
+ LexError::Compiler(e)
+ }
+}
+
+impl From<fallback::LexError> for LexError {
+ fn from(e: fallback::LexError) -> Self {
+ LexError::Fallback(e)
+ }
+}
+
+impl Debug for LexError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ LexError::Compiler(e) => Debug::fmt(e, f),
+ LexError::Fallback(e) => Debug::fmt(e, f),
+ LexError::CompilerPanic => {
+ let fallback = fallback::LexError::call_site();
+ Debug::fmt(&fallback, f)
+ }
+ }
+ }
+}
+
+impl Display for LexError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ LexError::Compiler(e) => Display::fmt(e, f),
+ LexError::Fallback(e) => Display::fmt(e, f),
+ LexError::CompilerPanic => {
+ let fallback = fallback::LexError::call_site();
+ Display::fmt(&fallback, f)
+ }
+ }
+ }
+}
+
+#[derive(Clone)]
+pub(crate) enum TokenTreeIter {
+ Compiler(proc_macro::token_stream::IntoIter),
+ Fallback(fallback::TokenTreeIter),
+}
+
+impl IntoIterator for TokenStream {
+ type Item = TokenTree;
+ type IntoIter = TokenTreeIter;
+
+ fn into_iter(self) -> TokenTreeIter {
+ match self {
+ TokenStream::Compiler(tts) => {
+ TokenTreeIter::Compiler(tts.into_token_stream().into_iter())
+ }
+ TokenStream::Fallback(tts) => TokenTreeIter::Fallback(tts.into_iter()),
+ }
+ }
+}
+
+impl Iterator for TokenTreeIter {
+ type Item = TokenTree;
+
+ fn next(&mut self) -> Option<TokenTree> {
+ let token = match self {
+ TokenTreeIter::Compiler(iter) => iter.next()?,
+ TokenTreeIter::Fallback(iter) => return iter.next(),
+ };
+ Some(match token {
+ proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(),
+ proc_macro::TokenTree::Punct(tt) => {
+ let spacing = match tt.spacing() {
+ proc_macro::Spacing::Joint => Spacing::Joint,
+ proc_macro::Spacing::Alone => Spacing::Alone,
+ };
+ let mut o = Punct::new(tt.as_char(), spacing);
+ o.set_span(crate::Span::_new(Span::Compiler(tt.span())));
+ o.into()
+ }
+ proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(),
+ proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(),
+ })
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ match self {
+ TokenTreeIter::Compiler(tts) => tts.size_hint(),
+ TokenTreeIter::Fallback(tts) => tts.size_hint(),
+ }
+ }
+}
+
+#[derive(Clone, PartialEq, Eq)]
+#[cfg(super_unstable)]
+pub(crate) enum SourceFile {
+ Compiler(proc_macro::SourceFile),
+ Fallback(fallback::SourceFile),
+}
+
+#[cfg(super_unstable)]
+impl SourceFile {
+ fn nightly(sf: proc_macro::SourceFile) -> Self {
+ SourceFile::Compiler(sf)
+ }
+
+ /// Get the path to this source file as a string.
+ pub fn path(&self) -> PathBuf {
+ match self {
+ SourceFile::Compiler(a) => a.path(),
+ SourceFile::Fallback(a) => a.path(),
+ }
+ }
+
+ pub fn is_real(&self) -> bool {
+ match self {
+ SourceFile::Compiler(a) => a.is_real(),
+ SourceFile::Fallback(a) => a.is_real(),
+ }
+ }
+}
+
+#[cfg(super_unstable)]
+impl Debug for SourceFile {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ SourceFile::Compiler(a) => Debug::fmt(a, f),
+ SourceFile::Fallback(a) => Debug::fmt(a, f),
+ }
+ }
+}
+
+#[derive(Copy, Clone)]
+pub(crate) enum Span {
+ Compiler(proc_macro::Span),
+ Fallback(fallback::Span),
+}
+
+impl Span {
+ pub fn call_site() -> Self {
+ if inside_proc_macro() {
+ Span::Compiler(proc_macro::Span::call_site())
+ } else {
+ Span::Fallback(fallback::Span::call_site())
+ }
+ }
+
+ pub fn mixed_site() -> Self {
+ if inside_proc_macro() {
+ Span::Compiler(proc_macro::Span::mixed_site())
+ } else {
+ Span::Fallback(fallback::Span::mixed_site())
+ }
+ }
+
+ #[cfg(super_unstable)]
+ pub fn def_site() -> Self {
+ if inside_proc_macro() {
+ Span::Compiler(proc_macro::Span::def_site())
+ } else {
+ Span::Fallback(fallback::Span::def_site())
+ }
+ }
+
+ pub 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)),
+ (Span::Compiler(_), Span::Fallback(_)) => mismatch(line!()),
+ (Span::Fallback(_), Span::Compiler(_)) => mismatch(line!()),
+ }
+ }
+
+ pub 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)),
+ (Span::Compiler(_), Span::Fallback(_)) => mismatch(line!()),
+ (Span::Fallback(_), Span::Compiler(_)) => mismatch(line!()),
+ }
+ }
+
+ pub fn unwrap(self) -> proc_macro::Span {
+ match self {
+ Span::Compiler(s) => s,
+ Span::Fallback(_) => panic!("proc_macro::Span is only available in procedural macros"),
+ }
+ }
+
+ #[cfg(super_unstable)]
+ pub fn source_file(&self) -> SourceFile {
+ match self {
+ Span::Compiler(s) => SourceFile::nightly(s.source_file()),
+ Span::Fallback(s) => SourceFile::Fallback(s.source_file()),
+ }
+ }
+
+ #[cfg(span_locations)]
+ pub fn byte_range(&self) -> Range<usize> {
+ match self {
+ #[cfg(proc_macro_span)]
+ Span::Compiler(s) => s.byte_range(),
+ #[cfg(not(proc_macro_span))]
+ Span::Compiler(_) => 0..0,
+ Span::Fallback(s) => s.byte_range(),
+ }
+ }
+
+ #[cfg(span_locations)]
+ pub fn start(&self) -> LineColumn {
+ match self {
+ Span::Compiler(_) => LineColumn { line: 0, column: 0 },
+ Span::Fallback(s) => s.start(),
+ }
+ }
+
+ #[cfg(span_locations)]
+ pub fn end(&self) -> LineColumn {
+ match self {
+ Span::Compiler(_) => LineColumn { line: 0, column: 0 },
+ Span::Fallback(s) => s.end(),
+ }
+ }
+
+ pub fn join(&self, other: Span) -> Option<Span> {
+ let ret = match (self, other) {
+ #[cfg(proc_macro_span)]
+ (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.join(b)?),
+ (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.join(b)?),
+ _ => return None,
+ };
+ Some(ret)
+ }
+
+ #[cfg(super_unstable)]
+ pub 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),
+ _ => false,
+ }
+ }
+
+ pub fn source_text(&self) -> Option<String> {
+ match self {
+ #[cfg(not(no_source_text))]
+ Span::Compiler(s) => s.source_text(),
+ #[cfg(no_source_text)]
+ Span::Compiler(_) => None,
+ Span::Fallback(s) => s.source_text(),
+ }
+ }
+
+ fn unwrap_nightly(self) -> proc_macro::Span {
+ match self {
+ Span::Compiler(s) => s,
+ Span::Fallback(_) => mismatch(line!()),
+ }
+ }
+}
+
+impl From<proc_macro::Span> for crate::Span {
+ fn from(proc_span: proc_macro::Span) -> Self {
+ crate::Span::_new(Span::Compiler(proc_span))
+ }
+}
+
+impl From<fallback::Span> for Span {
+ fn from(inner: fallback::Span) -> Self {
+ Span::Fallback(inner)
+ }
+}
+
+impl Debug for Span {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Span::Compiler(s) => Debug::fmt(s, f),
+ Span::Fallback(s) => Debug::fmt(s, f),
+ }
+ }
+}
+
+pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) {
+ match span {
+ Span::Compiler(s) => {
+ debug.field("span", &s);
+ }
+ Span::Fallback(s) => fallback::debug_span_field_if_nontrivial(debug, s),
+ }
+}
+
+#[derive(Clone)]
+pub(crate) enum Group {
+ Compiler(proc_macro::Group),
+ Fallback(fallback::Group),
+}
+
+impl Group {
+ pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self {
+ match stream {
+ TokenStream::Compiler(tts) => {
+ let delimiter = match delimiter {
+ Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
+ Delimiter::Bracket => proc_macro::Delimiter::Bracket,
+ Delimiter::Brace => proc_macro::Delimiter::Brace,
+ Delimiter::None => proc_macro::Delimiter::None,
+ };
+ Group::Compiler(proc_macro::Group::new(delimiter, tts.into_token_stream()))
+ }
+ TokenStream::Fallback(stream) => {
+ Group::Fallback(fallback::Group::new(delimiter, stream))
+ }
+ }
+ }
+
+ pub fn delimiter(&self) -> Delimiter {
+ match self {
+ Group::Compiler(g) => match g.delimiter() {
+ proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
+ proc_macro::Delimiter::Bracket => Delimiter::Bracket,
+ proc_macro::Delimiter::Brace => Delimiter::Brace,
+ proc_macro::Delimiter::None => Delimiter::None,
+ },
+ Group::Fallback(g) => g.delimiter(),
+ }
+ }
+
+ pub 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 {
+ match self {
+ Group::Compiler(g) => Span::Compiler(g.span()),
+ Group::Fallback(g) => Span::Fallback(g.span()),
+ }
+ }
+
+ pub 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 {
+ 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) {
+ match (self, span) {
+ (Group::Compiler(g), Span::Compiler(s)) => g.set_span(s),
+ (Group::Fallback(g), Span::Fallback(s)) => g.set_span(s),
+ (Group::Compiler(_), Span::Fallback(_)) => mismatch(line!()),
+ (Group::Fallback(_), Span::Compiler(_)) => mismatch(line!()),
+ }
+ }
+
+ fn unwrap_nightly(self) -> proc_macro::Group {
+ match self {
+ Group::Compiler(g) => g,
+ Group::Fallback(_) => mismatch(line!()),
+ }
+ }
+}
+
+impl From<fallback::Group> for Group {
+ fn from(g: fallback::Group) -> Self {
+ Group::Fallback(g)
+ }
+}
+
+impl Display for Group {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Group::Compiler(group) => Display::fmt(group, formatter),
+ Group::Fallback(group) => Display::fmt(group, formatter),
+ }
+ }
+}
+
+impl Debug for Group {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Group::Compiler(group) => Debug::fmt(group, formatter),
+ Group::Fallback(group) => Debug::fmt(group, formatter),
+ }
+ }
+}
+
+#[derive(Clone)]
+pub(crate) enum Ident {
+ Compiler(proc_macro::Ident),
+ Fallback(fallback::Ident),
+}
+
+impl Ident {
+ #[track_caller]
+ pub 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 {
+ 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 {
+ match self {
+ Ident::Compiler(t) => Span::Compiler(t.span()),
+ Ident::Fallback(t) => Span::Fallback(t.span()),
+ }
+ }
+
+ pub 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),
+ (Ident::Compiler(_), Span::Fallback(_)) => mismatch(line!()),
+ (Ident::Fallback(_), Span::Compiler(_)) => mismatch(line!()),
+ }
+ }
+
+ fn unwrap_nightly(self) -> proc_macro::Ident {
+ match self {
+ Ident::Compiler(s) => s,
+ Ident::Fallback(_) => mismatch(line!()),
+ }
+ }
+}
+
+impl PartialEq for Ident {
+ fn eq(&self, other: &Ident) -> bool {
+ match (self, other) {
+ (Ident::Compiler(t), Ident::Compiler(o)) => t.to_string() == o.to_string(),
+ (Ident::Fallback(t), Ident::Fallback(o)) => t == o,
+ (Ident::Compiler(_), Ident::Fallback(_)) => mismatch(line!()),
+ (Ident::Fallback(_), Ident::Compiler(_)) => mismatch(line!()),
+ }
+ }
+}
+
+impl<T> PartialEq<T> for Ident
+where
+ T: ?Sized + AsRef<str>,
+{
+ fn eq(&self, other: &T) -> bool {
+ let other = other.as_ref();
+ match self {
+ Ident::Compiler(t) => t.to_string() == other,
+ Ident::Fallback(t) => t == other,
+ }
+ }
+}
+
+impl Display for Ident {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Ident::Compiler(t) => Display::fmt(t, f),
+ Ident::Fallback(t) => Display::fmt(t, f),
+ }
+ }
+}
+
+impl Debug for Ident {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Ident::Compiler(t) => Debug::fmt(t, f),
+ Ident::Fallback(t) => Debug::fmt(t, f),
+ }
+ }
+}
+
+#[derive(Clone)]
+pub(crate) enum Literal {
+ Compiler(proc_macro::Literal),
+ Fallback(fallback::Literal),
+}
+
+macro_rules! suffixed_numbers {
+ ($($name:ident => $kind:ident,)*) => ($(
+ pub fn $name(n: $kind) -> Literal {
+ if inside_proc_macro() {
+ Literal::Compiler(proc_macro::Literal::$name(n))
+ } else {
+ Literal::Fallback(fallback::Literal::$name(n))
+ }
+ }
+ )*)
+}
+
+macro_rules! unsuffixed_integers {
+ ($($name:ident => $kind:ident,)*) => ($(
+ pub fn $name(n: $kind) -> Literal {
+ if inside_proc_macro() {
+ Literal::Compiler(proc_macro::Literal::$name(n))
+ } else {
+ Literal::Fallback(fallback::Literal::$name(n))
+ }
+ }
+ )*)
+}
+
+impl Literal {
+ pub unsafe fn from_str_unchecked(repr: &str) -> Self {
+ if inside_proc_macro() {
+ Literal::Compiler(proc_macro::Literal::from_str(repr).expect("invalid literal"))
+ } else {
+ Literal::Fallback(unsafe { fallback::Literal::from_str_unchecked(repr) })
+ }
+ }
+
+ suffixed_numbers! {
+ u8_suffixed => u8,
+ u16_suffixed => u16,
+ u32_suffixed => u32,
+ u64_suffixed => u64,
+ u128_suffixed => u128,
+ usize_suffixed => usize,
+ i8_suffixed => i8,
+ i16_suffixed => i16,
+ i32_suffixed => i32,
+ i64_suffixed => i64,
+ i128_suffixed => i128,
+ isize_suffixed => isize,
+
+ f32_suffixed => f32,
+ f64_suffixed => f64,
+ }
+
+ unsuffixed_integers! {
+ u8_unsuffixed => u8,
+ u16_unsuffixed => u16,
+ u32_unsuffixed => u32,
+ u64_unsuffixed => u64,
+ u128_unsuffixed => u128,
+ usize_unsuffixed => usize,
+ i8_unsuffixed => i8,
+ i16_unsuffixed => i16,
+ i32_unsuffixed => i32,
+ i64_unsuffixed => i64,
+ i128_unsuffixed => i128,
+ isize_unsuffixed => isize,
+ }
+
+ pub fn f32_unsuffixed(f: f32) -> Literal {
+ if inside_proc_macro() {
+ Literal::Compiler(proc_macro::Literal::f32_unsuffixed(f))
+ } else {
+ Literal::Fallback(fallback::Literal::f32_unsuffixed(f))
+ }
+ }
+
+ pub fn f64_unsuffixed(f: f64) -> Literal {
+ if inside_proc_macro() {
+ Literal::Compiler(proc_macro::Literal::f64_unsuffixed(f))
+ } else {
+ Literal::Fallback(fallback::Literal::f64_unsuffixed(f))
+ }
+ }
+
+ pub fn string(string: &str) -> Literal {
+ if inside_proc_macro() {
+ Literal::Compiler(proc_macro::Literal::string(string))
+ } else {
+ Literal::Fallback(fallback::Literal::string(string))
+ }
+ }
+
+ pub fn character(ch: char) -> Literal {
+ if inside_proc_macro() {
+ Literal::Compiler(proc_macro::Literal::character(ch))
+ } else {
+ Literal::Fallback(fallback::Literal::character(ch))
+ }
+ }
+
+ pub fn byte_character(byte: u8) -> Literal {
+ if inside_proc_macro() {
+ Literal::Compiler({
+ #[cfg(not(no_literal_byte_character))]
+ {
+ proc_macro::Literal::byte_character(byte)
+ }
+
+ #[cfg(no_literal_byte_character)]
+ {
+ let fallback = fallback::Literal::byte_character(byte);
+ fallback.repr.parse::<proc_macro::Literal>().unwrap()
+ }
+ })
+ } else {
+ Literal::Fallback(fallback::Literal::byte_character(byte))
+ }
+ }
+
+ pub fn byte_string(bytes: &[u8]) -> Literal {
+ if inside_proc_macro() {
+ Literal::Compiler(proc_macro::Literal::byte_string(bytes))
+ } else {
+ Literal::Fallback(fallback::Literal::byte_string(bytes))
+ }
+ }
+
+ pub fn c_string(string: &CStr) -> Literal {
+ if inside_proc_macro() {
+ Literal::Compiler({
+ #[cfg(not(no_literal_c_string))]
+ {
+ proc_macro::Literal::c_string(string)
+ }
+
+ #[cfg(no_literal_c_string)]
+ {
+ let fallback = fallback::Literal::c_string(string);
+ fallback.repr.parse::<proc_macro::Literal>().unwrap()
+ }
+ })
+ } else {
+ Literal::Fallback(fallback::Literal::c_string(string))
+ }
+ }
+
+ pub 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) {
+ match (self, span) {
+ (Literal::Compiler(lit), Span::Compiler(s)) => lit.set_span(s),
+ (Literal::Fallback(lit), Span::Fallback(s)) => lit.set_span(s),
+ (Literal::Compiler(_), Span::Fallback(_)) => mismatch(line!()),
+ (Literal::Fallback(_), Span::Compiler(_)) => mismatch(line!()),
+ }
+ }
+
+ pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
+ match self {
+ #[cfg(proc_macro_span)]
+ Literal::Compiler(lit) => lit.subspan(range).map(Span::Compiler),
+ #[cfg(not(proc_macro_span))]
+ Literal::Compiler(_lit) => None,
+ Literal::Fallback(lit) => lit.subspan(range).map(Span::Fallback),
+ }
+ }
+
+ fn unwrap_nightly(self) -> proc_macro::Literal {
+ match self {
+ Literal::Compiler(s) => s,
+ Literal::Fallback(_) => mismatch(line!()),
+ }
+ }
+}
+
+impl From<fallback::Literal> for Literal {
+ fn from(s: fallback::Literal) -> Self {
+ Literal::Fallback(s)
+ }
+}
+
+impl FromStr for Literal {
+ type Err = LexError;
+
+ fn from_str(repr: &str) -> Result<Self, Self::Err> {
+ 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 {
+ Literal::Compiler(t) => Display::fmt(t, f),
+ Literal::Fallback(t) => Display::fmt(t, f),
+ }
+ }
+}
+
+impl Debug for Literal {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Literal::Compiler(t) => Debug::fmt(t, f),
+ Literal::Fallback(t) => Debug::fmt(t, f),
+ }
+ }
+}
+
+#[cfg(span_locations)]
+pub(crate) fn invalidate_current_thread_spans() {
+ if inside_proc_macro() {
+ panic!(
+ "proc_macro2::extra::invalidate_current_thread_spans is not available in procedural macros"
+ );
+ } else {
+ crate::fallback::invalidate_current_thread_spans();
+ }
+}
--git a/rust/hw/char/pl011/vendor/proc-macro2/tests/comments.rs b/rust/hw/char/pl011/vendor/proc-macro2/tests/comments.rs
new file mode 100644
index 0000000000..4f7236dea9
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/tests/comments.rs
@@ -0,0 +1,105 @@
+#![allow(clippy::assertions_on_result_states)]
+
+use proc_macro2::{Delimiter, Literal, Spacing, TokenStream, TokenTree};
+
+// #[doc = "..."] -> "..."
+fn lit_of_outer_doc_comment(tokens: &TokenStream) -> Literal {
+ lit_of_doc_comment(tokens, false)
+}
+
+// #![doc = "..."] -> "..."
+fn lit_of_inner_doc_comment(tokens: &TokenStream) -> Literal {
+ lit_of_doc_comment(tokens, true)
+}
+
+fn lit_of_doc_comment(tokens: &TokenStream, inner: bool) -> Literal {
+ let mut iter = tokens.clone().into_iter();
+ match iter.next().unwrap() {
+ TokenTree::Punct(punct) => {
+ assert_eq!(punct.as_char(), '#');
+ assert_eq!(punct.spacing(), Spacing::Alone);
+ }
+ _ => panic!("wrong token {:?}", tokens),
+ }
+ if inner {
+ match iter.next().unwrap() {
+ TokenTree::Punct(punct) => {
+ assert_eq!(punct.as_char(), '!');
+ assert_eq!(punct.spacing(), Spacing::Alone);
+ }
+ _ => panic!("wrong token {:?}", tokens),
+ }
+ }
+ iter = match iter.next().unwrap() {
+ TokenTree::Group(group) => {
+ assert_eq!(group.delimiter(), Delimiter::Bracket);
+ assert!(iter.next().is_none(), "unexpected token {:?}", tokens);
+ group.stream().into_iter()
+ }
+ _ => panic!("wrong token {:?}", tokens),
+ };
+ match iter.next().unwrap() {
+ TokenTree::Ident(ident) => assert_eq!(ident.to_string(), "doc"),
+ _ => panic!("wrong token {:?}", tokens),
+ }
+ match iter.next().unwrap() {
+ TokenTree::Punct(punct) => {
+ assert_eq!(punct.as_char(), '=');
+ assert_eq!(punct.spacing(), Spacing::Alone);
+ }
+ _ => panic!("wrong token {:?}", tokens),
+ }
+ match iter.next().unwrap() {
+ TokenTree::Literal(literal) => {
+ assert!(iter.next().is_none(), "unexpected token {:?}", tokens);
+ literal
+ }
+ _ => panic!("wrong token {:?}", tokens),
+ }
+}
+
+#[test]
+fn closed_immediately() {
+ let stream = "/**/".parse::<TokenStream>().unwrap();
+ let tokens = stream.into_iter().collect::<Vec<_>>();
+ assert!(tokens.is_empty(), "not empty -- {:?}", tokens);
+}
+
+#[test]
+fn incomplete() {
+ assert!("/*/".parse::<TokenStream>().is_err());
+}
+
+#[test]
+fn lit() {
+ let stream = "/// doc".parse::<TokenStream>().unwrap();
+ let lit = lit_of_outer_doc_comment(&stream);
+ assert_eq!(lit.to_string(), "\" doc\"");
+
+ let stream = "//! doc".parse::<TokenStream>().unwrap();
+ let lit = lit_of_inner_doc_comment(&stream);
+ assert_eq!(lit.to_string(), "\" doc\"");
+
+ let stream = "/** doc */".parse::<TokenStream>().unwrap();
+ let lit = lit_of_outer_doc_comment(&stream);
+ assert_eq!(lit.to_string(), "\" doc \"");
+
+ let stream = "/*! doc */".parse::<TokenStream>().unwrap();
+ let lit = lit_of_inner_doc_comment(&stream);
+ assert_eq!(lit.to_string(), "\" doc \"");
+}
+
+#[test]
+fn carriage_return() {
+ let stream = "///\r\n".parse::<TokenStream>().unwrap();
+ let lit = lit_of_outer_doc_comment(&stream);
+ assert_eq!(lit.to_string(), "\"\"");
+
+ let stream = "/**\r\n*/".parse::<TokenStream>().unwrap();
+ let lit = lit_of_outer_doc_comment(&stream);
+ assert_eq!(lit.to_string(), "\"\\r\\n\"");
+
+ "///\r".parse::<TokenStream>().unwrap_err();
+ "///\r \n".parse::<TokenStream>().unwrap_err();
+ "/**\r \n*/".parse::<TokenStream>().unwrap_err();
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/tests/features.rs b/rust/hw/char/pl011/vendor/proc-macro2/tests/features.rs
new file mode 100644
index 0000000000..073f6e60fb
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/tests/features.rs
@@ -0,0 +1,8 @@
+#[test]
+#[ignore]
+fn make_sure_no_proc_macro() {
+ assert!(
+ !cfg!(feature = "proc-macro"),
+ "still compiled with proc_macro?"
+ );
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/tests/marker.rs b/rust/hw/char/pl011/vendor/proc-macro2/tests/marker.rs
new file mode 100644
index 0000000000..99f64c068f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/tests/marker.rs
@@ -0,0 +1,100 @@
+#![allow(clippy::extra_unused_type_parameters)]
+
+use proc_macro2::{
+ Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree,
+};
+
+macro_rules! assert_impl {
+ ($ty:ident is $($marker:ident) and +) => {
+ #[test]
+ #[allow(non_snake_case)]
+ fn $ty() {
+ fn assert_implemented<T: $($marker +)+>() {}
+ assert_implemented::<$ty>();
+ }
+ };
+
+ ($ty:ident is not $($marker:ident) or +) => {
+ #[test]
+ #[allow(non_snake_case)]
+ fn $ty() {
+ $(
+ {
+ // Implemented for types that implement $marker.
+ #[allow(dead_code)]
+ trait IsNotImplemented {
+ fn assert_not_implemented() {}
+ }
+ impl<T: $marker> IsNotImplemented for T {}
+
+ // Implemented for the type being tested.
+ trait IsImplemented {
+ fn assert_not_implemented() {}
+ }
+ impl IsImplemented for $ty {}
+
+ // If $ty does not implement $marker, there is no ambiguity
+ // in the following trait method call.
+ <$ty>::assert_not_implemented();
+ }
+ )+
+ }
+ };
+}
+
+assert_impl!(Delimiter is Send and Sync);
+assert_impl!(Spacing is Send and Sync);
+
+assert_impl!(Group is not Send or Sync);
+assert_impl!(Ident is not Send or Sync);
+assert_impl!(LexError is not Send or Sync);
+assert_impl!(Literal is not Send or Sync);
+assert_impl!(Punct is not Send or Sync);
+assert_impl!(Span is not Send or Sync);
+assert_impl!(TokenStream is not Send or Sync);
+assert_impl!(TokenTree is not Send or Sync);
+
+#[cfg(procmacro2_semver_exempt)]
+mod semver_exempt {
+ use proc_macro2::{LineColumn, SourceFile};
+
+ assert_impl!(LineColumn is Send and Sync);
+
+ assert_impl!(SourceFile is not Send or Sync);
+}
+
+mod unwind_safe {
+ use proc_macro2::{
+ Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree,
+ };
+ #[cfg(procmacro2_semver_exempt)]
+ use proc_macro2::{LineColumn, SourceFile};
+ use std::panic::{RefUnwindSafe, UnwindSafe};
+
+ macro_rules! assert_unwind_safe {
+ ($($types:ident)*) => {
+ $(
+ assert_impl!($types is UnwindSafe and RefUnwindSafe);
+ )*
+ };
+ }
+
+ assert_unwind_safe! {
+ Delimiter
+ Group
+ Ident
+ LexError
+ Literal
+ Punct
+ Spacing
+ Span
+ TokenStream
+ TokenTree
+ }
+
+ #[cfg(procmacro2_semver_exempt)]
+ assert_unwind_safe! {
+ LineColumn
+ SourceFile
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/tests/test.rs b/rust/hw/char/pl011/vendor/proc-macro2/tests/test.rs
new file mode 100644
index 0000000000..0d7c88d3df
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/tests/test.rs
@@ -0,0 +1,905 @@
+#![allow(
+ clippy::assertions_on_result_states,
+ clippy::items_after_statements,
+ clippy::needless_pass_by_value,
+ clippy::needless_raw_string_hashes,
+ clippy::non_ascii_literal,
+ clippy::octal_escapes
+)]
+
+use proc_macro2::{Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
+use std::ffi::CStr;
+use std::iter;
+use std::str::{self, FromStr};
+
+#[test]
+fn idents() {
+ assert_eq!(
+ Ident::new("String", Span::call_site()).to_string(),
+ "String"
+ );
+ assert_eq!(Ident::new("fn", Span::call_site()).to_string(), "fn");
+ assert_eq!(Ident::new("_", Span::call_site()).to_string(), "_");
+}
+
+#[test]
+fn raw_idents() {
+ assert_eq!(
+ Ident::new_raw("String", Span::call_site()).to_string(),
+ "r#String"
+ );
+ assert_eq!(Ident::new_raw("fn", Span::call_site()).to_string(), "r#fn");
+}
+
+#[test]
+#[should_panic(expected = "`r#_` cannot be a raw identifier")]
+fn ident_raw_underscore() {
+ Ident::new_raw("_", Span::call_site());
+}
+
+#[test]
+#[should_panic(expected = "`r#super` cannot be a raw identifier")]
+fn ident_raw_reserved() {
+ Ident::new_raw("super", Span::call_site());
+}
+
+#[test]
+#[should_panic(expected = "Ident is not allowed to be empty; use Option<Ident>")]
+fn ident_empty() {
+ Ident::new("", Span::call_site());
+}
+
+#[test]
+#[should_panic(expected = "Ident cannot be a number; use Literal instead")]
+fn ident_number() {
+ Ident::new("255", Span::call_site());
+}
+
+#[test]
+#[should_panic(expected = "\"a#\" is not a valid Ident")]
+fn ident_invalid() {
+ Ident::new("a#", Span::call_site());
+}
+
+#[test]
+#[should_panic(expected = "not a valid Ident")]
+fn raw_ident_empty() {
+ Ident::new("r#", Span::call_site());
+}
+
+#[test]
+#[should_panic(expected = "not a valid Ident")]
+fn raw_ident_number() {
+ Ident::new("r#255", Span::call_site());
+}
+
+#[test]
+#[should_panic(expected = "\"r#a#\" is not a valid Ident")]
+fn raw_ident_invalid() {
+ Ident::new("r#a#", Span::call_site());
+}
+
+#[test]
+#[should_panic(expected = "not a valid Ident")]
+fn lifetime_empty() {
+ Ident::new("'", Span::call_site());
+}
+
+#[test]
+#[should_panic(expected = "not a valid Ident")]
+fn lifetime_number() {
+ Ident::new("'255", Span::call_site());
+}
+
+#[test]
+#[should_panic(expected = r#""'a#" is not a valid Ident"#)]
+fn lifetime_invalid() {
+ Ident::new("'a#", Span::call_site());
+}
+
+#[test]
+fn literal_string() {
+ #[track_caller]
+ fn assert(literal: Literal, expected: &str) {
+ assert_eq!(literal.to_string(), expected.trim());
+ }
+
+ assert(Literal::string(""), r#" "" "#);
+ assert(Literal::string("aA"), r#" "aA" "#);
+ assert(Literal::string("\t"), r#" "\t" "#);
+ assert(Literal::string("❤"), r#" "❤" "#);
+ assert(Literal::string("'"), r#" "'" "#);
+ assert(Literal::string("\""), r#" "\"" "#);
+ assert(Literal::string("\0"), r#" "\0" "#);
+ assert(Literal::string("\u{1}"), r#" "\u{1}" "#);
+ assert(
+ Literal::string("a\00b\07c\08d\0e\0"),
+ r#" "a\x000b\x007c\08d\0e\0" "#,
+ );
+
+ "\"\\\r\n x\"".parse::<TokenStream>().unwrap();
+ "\"\\\r\n \rx\"".parse::<TokenStream>().unwrap_err();
+}
+
+#[test]
+fn literal_raw_string() {
+ "r\"\r\n\"".parse::<TokenStream>().unwrap();
+
+ fn raw_string_literal_with_hashes(n: usize) -> String {
+ let mut literal = String::new();
+ literal.push('r');
+ literal.extend(iter::repeat('#').take(n));
+ literal.push('"');
+ literal.push('"');
+ literal.extend(iter::repeat('#').take(n));
+ literal
+ }
+
+ raw_string_literal_with_hashes(255)
+ .parse::<TokenStream>()
+ .unwrap();
+
+ // https://github.com/rust-lang/rust/pull/95251
+ raw_string_literal_with_hashes(256)
+ .parse::<TokenStream>()
+ .unwrap_err();
+}
+
+#[test]
+fn literal_byte_character() {
+ #[track_caller]
+ fn assert(literal: Literal, expected: &str) {
+ assert_eq!(literal.to_string(), expected.trim());
+ }
+
+ assert(Literal::byte_character(b'a'), r#" b'a' "#);
+ assert(Literal::byte_character(b'\0'), r#" b'\0' "#);
+ assert(Literal::byte_character(b'\t'), r#" b'\t' "#);
+ assert(Literal::byte_character(b'\n'), r#" b'\n' "#);
+ assert(Literal::byte_character(b'\r'), r#" b'\r' "#);
+ assert(Literal::byte_character(b'\''), r#" b'\'' "#);
+ assert(Literal::byte_character(b'\\'), r#" b'\\' "#);
+ assert(Literal::byte_character(b'\x1f'), r#" b'\x1F' "#);
+ assert(Literal::byte_character(b'"'), r#" b'"' "#);
+}
+
+#[test]
+fn literal_byte_string() {
+ #[track_caller]
+ fn assert(literal: Literal, expected: &str) {
+ assert_eq!(literal.to_string(), expected.trim());
+ }
+
+ assert(Literal::byte_string(b""), r#" b"" "#);
+ assert(Literal::byte_string(b"\0"), r#" b"\0" "#);
+ assert(Literal::byte_string(b"\t"), r#" b"\t" "#);
+ assert(Literal::byte_string(b"\n"), r#" b"\n" "#);
+ assert(Literal::byte_string(b"\r"), r#" b"\r" "#);
+ assert(Literal::byte_string(b"\""), r#" b"\"" "#);
+ assert(Literal::byte_string(b"\\"), r#" b"\\" "#);
+ assert(Literal::byte_string(b"\x1f"), r#" b"\x1F" "#);
+ assert(Literal::byte_string(b"'"), r#" b"'" "#);
+ assert(
+ Literal::byte_string(b"a\00b\07c\08d\0e\0"),
+ r#" b"a\x000b\x007c\08d\0e\0" "#,
+ );
+
+ "b\"\\\r\n x\"".parse::<TokenStream>().unwrap();
+ "b\"\\\r\n \rx\"".parse::<TokenStream>().unwrap_err();
+ "b\"\\\r\n \u{a0}x\"".parse::<TokenStream>().unwrap_err();
+ "br\"\u{a0}\"".parse::<TokenStream>().unwrap_err();
+}
+
+#[test]
+fn literal_c_string() {
+ #[track_caller]
+ fn assert(literal: Literal, expected: &str) {
+ assert_eq!(literal.to_string(), expected.trim());
+ }
+
+ assert(Literal::c_string(<&CStr>::default()), r#" c"" "#);
+ assert(
+ Literal::c_string(CStr::from_bytes_with_nul(b"aA\0").unwrap()),
+ r#" c"aA" "#,
+ );
+ assert(
+ Literal::c_string(CStr::from_bytes_with_nul(b"aA\0").unwrap()),
+ r#" c"aA" "#,
+ );
+ assert(
+ Literal::c_string(CStr::from_bytes_with_nul(b"\t\0").unwrap()),
+ r#" c"\t" "#,
+ );
+ assert(
+ Literal::c_string(CStr::from_bytes_with_nul(b"\xE2\x9D\xA4\0").unwrap()),
+ r#" c"❤" "#,
+ );
+ assert(
+ Literal::c_string(CStr::from_bytes_with_nul(b"'\0").unwrap()),
+ r#" c"'" "#,
+ );
+ assert(
+ Literal::c_string(CStr::from_bytes_with_nul(b"\"\0").unwrap()),
+ r#" c"\"" "#,
+ );
+ assert(
+ Literal::c_string(CStr::from_bytes_with_nul(b"\x7F\xFF\xFE\xCC\xB3\0").unwrap()),
+ r#" c"\u{7f}\xFF\xFE\u{333}" "#,
+ );
+
+ let strings = r###"
+ c"hello\x80我叫\u{1F980}" // from the RFC
+ cr"\"
+ cr##"Hello "world"!"##
+ c"\t\n\r\"\\"
+ "###;
+
+ let mut tokens = strings.parse::<TokenStream>().unwrap().into_iter();
+
+ for expected in &[
+ r#"c"hello\x80我叫\u{1F980}""#,
+ r#"cr"\""#,
+ r###"cr##"Hello "world"!"##"###,
+ r#"c"\t\n\r\"\\""#,
+ ] {
+ match tokens.next().unwrap() {
+ TokenTree::Literal(literal) => {
+ assert_eq!(literal.to_string(), *expected);
+ }
+ unexpected => panic!("unexpected token: {:?}", unexpected),
+ }
+ }
+
+ if let Some(unexpected) = tokens.next() {
+ panic!("unexpected token: {:?}", unexpected);
+ }
+
+ for invalid in &[r#"c"\0""#, r#"c"\x00""#, r#"c"\u{0}""#, "c\"\0\""] {
+ if let Ok(unexpected) = invalid.parse::<TokenStream>() {
+ panic!("unexpected token: {:?}", unexpected);
+ }
+ }
+}
+
+#[test]
+fn literal_character() {
+ #[track_caller]
+ fn assert(literal: Literal, expected: &str) {
+ assert_eq!(literal.to_string(), expected.trim());
+ }
+
+ assert(Literal::character('a'), r#" 'a' "#);
+ assert(Literal::character('\t'), r#" '\t' "#);
+ assert(Literal::character('❤'), r#" '❤' "#);
+ assert(Literal::character('\''), r#" '\'' "#);
+ assert(Literal::character('"'), r#" '"' "#);
+ assert(Literal::character('\0'), r#" '\0' "#);
+ assert(Literal::character('\u{1}'), r#" '\u{1}' "#);
+}
+
+#[test]
+fn literal_integer() {
+ #[track_caller]
+ fn assert(literal: Literal, expected: &str) {
+ assert_eq!(literal.to_string(), expected);
+ }
+
+ assert(Literal::u8_suffixed(10), "10u8");
+ assert(Literal::u16_suffixed(10), "10u16");
+ assert(Literal::u32_suffixed(10), "10u32");
+ assert(Literal::u64_suffixed(10), "10u64");
+ assert(Literal::u128_suffixed(10), "10u128");
+ assert(Literal::usize_suffixed(10), "10usize");
+
+ assert(Literal::i8_suffixed(10), "10i8");
+ assert(Literal::i16_suffixed(10), "10i16");
+ assert(Literal::i32_suffixed(10), "10i32");
+ assert(Literal::i64_suffixed(10), "10i64");
+ assert(Literal::i128_suffixed(10), "10i128");
+ assert(Literal::isize_suffixed(10), "10isize");
+
+ assert(Literal::u8_unsuffixed(10), "10");
+ assert(Literal::u16_unsuffixed(10), "10");
+ assert(Literal::u32_unsuffixed(10), "10");
+ assert(Literal::u64_unsuffixed(10), "10");
+ assert(Literal::u128_unsuffixed(10), "10");
+ assert(Literal::usize_unsuffixed(10), "10");
+
+ assert(Literal::i8_unsuffixed(10), "10");
+ assert(Literal::i16_unsuffixed(10), "10");
+ assert(Literal::i32_unsuffixed(10), "10");
+ assert(Literal::i64_unsuffixed(10), "10");
+ assert(Literal::i128_unsuffixed(10), "10");
+ assert(Literal::isize_unsuffixed(10), "10");
+
+ assert(Literal::i32_suffixed(-10), "-10i32");
+ assert(Literal::i32_unsuffixed(-10), "-10");
+}
+
+#[test]
+fn literal_float() {
+ #[track_caller]
+ fn assert(literal: Literal, expected: &str) {
+ assert_eq!(literal.to_string(), expected);
+ }
+
+ assert(Literal::f32_suffixed(10.0), "10f32");
+ assert(Literal::f32_suffixed(-10.0), "-10f32");
+ assert(Literal::f64_suffixed(10.0), "10f64");
+ assert(Literal::f64_suffixed(-10.0), "-10f64");
+
+ assert(Literal::f32_unsuffixed(10.0), "10.0");
+ assert(Literal::f32_unsuffixed(-10.0), "-10.0");
+ assert(Literal::f64_unsuffixed(10.0), "10.0");
+ assert(Literal::f64_unsuffixed(-10.0), "-10.0");
+
+ assert(
+ Literal::f64_unsuffixed(1e100),
+ "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0",
+ );
+}
+
+#[test]
+fn literal_suffix() {
+ fn token_count(p: &str) -> usize {
+ p.parse::<TokenStream>().unwrap().into_iter().count()
+ }
+
+ assert_eq!(token_count("999u256"), 1);
+ assert_eq!(token_count("999r#u256"), 3);
+ assert_eq!(token_count("1."), 1);
+ assert_eq!(token_count("1.f32"), 3);
+ assert_eq!(token_count("1.0_0"), 1);
+ assert_eq!(token_count("1._0"), 3);
+ assert_eq!(token_count("1._m"), 3);
+ assert_eq!(token_count("\"\"s"), 1);
+ assert_eq!(token_count("r\"\"r"), 1);
+ assert_eq!(token_count("r#\"\"#r"), 1);
+ assert_eq!(token_count("b\"\"b"), 1);
+ assert_eq!(token_count("br\"\"br"), 1);
+ assert_eq!(token_count("br#\"\"#br"), 1);
+ assert_eq!(token_count("c\"\"c"), 1);
+ assert_eq!(token_count("cr\"\"cr"), 1);
+ assert_eq!(token_count("cr#\"\"#cr"), 1);
+ assert_eq!(token_count("'c'c"), 1);
+ assert_eq!(token_count("b'b'b"), 1);
+ assert_eq!(token_count("0E"), 1);
+ assert_eq!(token_count("0o0A"), 1);
+ assert_eq!(token_count("0E--0"), 4);
+ assert_eq!(token_count("0.0ECMA"), 1);
+}
+
+#[test]
+fn literal_iter_negative() {
+ let negative_literal = Literal::i32_suffixed(-3);
+ let tokens = TokenStream::from(TokenTree::Literal(negative_literal));
+ let mut iter = tokens.into_iter();
+ match iter.next().unwrap() {
+ TokenTree::Punct(punct) => {
+ assert_eq!(punct.as_char(), '-');
+ assert_eq!(punct.spacing(), Spacing::Alone);
+ }
+ unexpected => panic!("unexpected token {:?}", unexpected),
+ }
+ match iter.next().unwrap() {
+ TokenTree::Literal(literal) => {
+ assert_eq!(literal.to_string(), "3i32");
+ }
+ unexpected => panic!("unexpected token {:?}", unexpected),
+ }
+ assert!(iter.next().is_none());
+}
+
+#[test]
+fn literal_parse() {
+ assert!("1".parse::<Literal>().is_ok());
+ assert!("-1".parse::<Literal>().is_ok());
+ assert!("-1u12".parse::<Literal>().is_ok());
+ assert!("1.0".parse::<Literal>().is_ok());
+ assert!("-1.0".parse::<Literal>().is_ok());
+ assert!("-1.0f12".parse::<Literal>().is_ok());
+ assert!("'a'".parse::<Literal>().is_ok());
+ assert!("\"\n\"".parse::<Literal>().is_ok());
+ assert!("0 1".parse::<Literal>().is_err());
+ assert!(" 0".parse::<Literal>().is_err());
+ assert!("0 ".parse::<Literal>().is_err());
+ assert!("/* comment */0".parse::<Literal>().is_err());
+ assert!("0/* comment */".parse::<Literal>().is_err());
+ assert!("0// comment".parse::<Literal>().is_err());
+ assert!("- 1".parse::<Literal>().is_err());
+ assert!("- 1.0".parse::<Literal>().is_err());
+ assert!("-\"\"".parse::<Literal>().is_err());
+}
+
+#[test]
+fn literal_span() {
+ let positive = "0.1".parse::<Literal>().unwrap();
+ let negative = "-0.1".parse::<Literal>().unwrap();
+ let subspan = positive.subspan(1..2);
+
+ #[cfg(not(span_locations))]
+ {
+ let _ = negative;
+ assert!(subspan.is_none());
+ }
+
+ #[cfg(span_locations)]
+ {
+ assert_eq!(positive.span().start().column, 0);
+ assert_eq!(positive.span().end().column, 3);
+ assert_eq!(negative.span().start().column, 0);
+ assert_eq!(negative.span().end().column, 4);
+ assert_eq!(subspan.unwrap().source_text().unwrap(), ".");
+ }
+
+ assert!(positive.subspan(1..4).is_none());
+}
+
+#[cfg(span_locations)]
+#[test]
+fn source_text() {
+ let input = " 𓀕 a z ";
+ let mut tokens = input
+ .parse::<proc_macro2::TokenStream>()
+ .unwrap()
+ .into_iter();
+
+ let first = tokens.next().unwrap();
+ assert_eq!("𓀕", first.span().source_text().unwrap());
+
+ let second = tokens.next().unwrap();
+ let third = tokens.next().unwrap();
+ assert_eq!("z", third.span().source_text().unwrap());
+ assert_eq!("a", second.span().source_text().unwrap());
+}
+
+#[test]
+fn roundtrip() {
+ fn roundtrip(p: &str) {
+ println!("parse: {}", p);
+ let s = p.parse::<TokenStream>().unwrap().to_string();
+ println!("first: {}", s);
+ let s2 = s.parse::<TokenStream>().unwrap().to_string();
+ assert_eq!(s, s2);
+ }
+ roundtrip("a");
+ roundtrip("<<");
+ roundtrip("<<=");
+ roundtrip(
+ "
+ 1
+ 1.0
+ 1f32
+ 2f64
+ 1usize
+ 4isize
+ 4e10
+ 1_000
+ 1_0i32
+ 8u8
+ 9
+ 0
+ 0xffffffffffffffffffffffffffffffff
+ 1x
+ 1u80
+ 1f320
+ ",
+ );
+ roundtrip("'a");
+ roundtrip("'_");
+ roundtrip("'static");
+ roundtrip(r"'\u{10__FFFF}'");
+ roundtrip("\"\\u{10_F0FF__}foo\\u{1_0_0_0__}\"");
+}
+
+#[test]
+fn fail() {
+ fn fail(p: &str) {
+ if let Ok(s) = p.parse::<TokenStream>() {
+ panic!("should have failed to parse: {}\n{:#?}", p, s);
+ }
+ }
+ fail("' static");
+ fail("r#1");
+ fail("r#_");
+ fail("\"\\u{0000000}\""); // overlong unicode escape (rust allows at most 6 hex digits)
+ fail("\"\\u{999999}\""); // outside of valid range of char
+ fail("\"\\u{_0}\""); // leading underscore
+ fail("\"\\u{}\""); // empty
+ fail("b\"\r\""); // bare carriage return in byte string
+ fail("r\"\r\""); // bare carriage return in raw string
+ fail("\"\\\r \""); // backslash carriage return
+ fail("'aa'aa");
+ fail("br##\"\"#");
+ fail("cr##\"\"#");
+ fail("\"\\\n\u{85}\r\"");
+}
+
+#[cfg(span_locations)]
+#[test]
+fn span_test() {
+ check_spans(
+ "\
+/// This is a document comment
+testing 123
+{
+ testing 234
+}",
+ &[
+ (1, 0, 1, 30), // #
+ (1, 0, 1, 30), // [ ... ]
+ (1, 0, 1, 30), // doc
+ (1, 0, 1, 30), // =
+ (1, 0, 1, 30), // "This is..."
+ (2, 0, 2, 7), // testing
+ (2, 8, 2, 11), // 123
+ (3, 0, 5, 1), // { ... }
+ (4, 2, 4, 9), // testing
+ (4, 10, 4, 13), // 234
+ ],
+ );
+}
+
+#[cfg(procmacro2_semver_exempt)]
+#[test]
+fn default_span() {
+ let start = Span::call_site().start();
+ assert_eq!(start.line, 1);
+ assert_eq!(start.column, 0);
+ let end = Span::call_site().end();
+ assert_eq!(end.line, 1);
+ assert_eq!(end.column, 0);
+ let source_file = Span::call_site().source_file();
+ assert_eq!(source_file.path().to_string_lossy(), "<unspecified>");
+ assert!(!source_file.is_real());
+}
+
+#[cfg(procmacro2_semver_exempt)]
+#[test]
+fn span_join() {
+ let source1 = "aaa\nbbb"
+ .parse::<TokenStream>()
+ .unwrap()
+ .into_iter()
+ .collect::<Vec<_>>();
+ let source2 = "ccc\nddd"
+ .parse::<TokenStream>()
+ .unwrap()
+ .into_iter()
+ .collect::<Vec<_>>();
+
+ assert!(source1[0].span().source_file() != source2[0].span().source_file());
+ assert_eq!(
+ source1[0].span().source_file(),
+ source1[1].span().source_file()
+ );
+
+ let joined1 = source1[0].span().join(source1[1].span());
+ let joined2 = source1[0].span().join(source2[0].span());
+ assert!(joined1.is_some());
+ assert!(joined2.is_none());
+
+ let start = joined1.unwrap().start();
+ let end = joined1.unwrap().end();
+ assert_eq!(start.line, 1);
+ assert_eq!(start.column, 0);
+ assert_eq!(end.line, 2);
+ assert_eq!(end.column, 3);
+
+ assert_eq!(
+ joined1.unwrap().source_file(),
+ source1[0].span().source_file()
+ );
+}
+
+#[test]
+fn no_panic() {
+ let s = str::from_utf8(b"b\'\xc2\x86 \x00\x00\x00^\"").unwrap();
+ assert!(s.parse::<TokenStream>().is_err());
+}
+
+#[test]
+fn punct_before_comment() {
+ let mut tts = TokenStream::from_str("~// comment").unwrap().into_iter();
+ match tts.next().unwrap() {
+ TokenTree::Punct(tt) => {
+ assert_eq!(tt.as_char(), '~');
+ assert_eq!(tt.spacing(), Spacing::Alone);
+ }
+ wrong => panic!("wrong token {:?}", wrong),
+ }
+}
+
+#[test]
+fn joint_last_token() {
+ // This test verifies that we match the behavior of libproc_macro *not* in
+ // the range nightly-2020-09-06 through nightly-2020-09-10, in which this
+ // behavior was temporarily broken.
+ // See https://github.com/rust-lang/rust/issues/76399
+
+ let joint_punct = Punct::new(':', Spacing::Joint);
+ let stream = TokenStream::from(TokenTree::Punct(joint_punct));
+ let punct = match stream.into_iter().next().unwrap() {
+ TokenTree::Punct(punct) => punct,
+ _ => unreachable!(),
+ };
+ assert_eq!(punct.spacing(), Spacing::Joint);
+}
+
+#[test]
+fn raw_identifier() {
+ let mut tts = TokenStream::from_str("r#dyn").unwrap().into_iter();
+ match tts.next().unwrap() {
+ TokenTree::Ident(raw) => assert_eq!("r#dyn", raw.to_string()),
+ wrong => panic!("wrong token {:?}", wrong),
+ }
+ assert!(tts.next().is_none());
+}
+
+#[test]
+fn test_debug_ident() {
+ let ident = Ident::new("proc_macro", Span::call_site());
+
+ #[cfg(not(span_locations))]
+ let expected = "Ident(proc_macro)";
+
+ #[cfg(span_locations)]
+ let expected = "Ident { sym: proc_macro }";
+
+ assert_eq!(expected, format!("{:?}", ident));
+}
+
+#[test]
+fn test_debug_tokenstream() {
+ let tts = TokenStream::from_str("[a + 1]").unwrap();
+
+ #[cfg(not(span_locations))]
+ let expected = "\
+TokenStream [
+ Group {
+ delimiter: Bracket,
+ stream: TokenStream [
+ Ident {
+ sym: a,
+ },
+ Punct {
+ char: '+',
+ spacing: Alone,
+ },
+ Literal {
+ lit: 1,
+ },
+ ],
+ },
+]\
+ ";
+
+ #[cfg(not(span_locations))]
+ let expected_before_trailing_commas = "\
+TokenStream [
+ Group {
+ delimiter: Bracket,
+ stream: TokenStream [
+ Ident {
+ sym: a
+ },
+ Punct {
+ char: '+',
+ spacing: Alone
+ },
+ Literal {
+ lit: 1
+ }
+ ]
+ }
+]\
+ ";
+
+ #[cfg(span_locations)]
+ let expected = "\
+TokenStream [
+ Group {
+ delimiter: Bracket,
+ stream: TokenStream [
+ Ident {
+ sym: a,
+ span: bytes(2..3),
+ },
+ Punct {
+ char: '+',
+ spacing: Alone,
+ span: bytes(4..5),
+ },
+ Literal {
+ lit: 1,
+ span: bytes(6..7),
+ },
+ ],
+ span: bytes(1..8),
+ },
+]\
+ ";
+
+ #[cfg(span_locations)]
+ let expected_before_trailing_commas = "\
+TokenStream [
+ Group {
+ delimiter: Bracket,
+ stream: TokenStream [
+ Ident {
+ sym: a,
+ span: bytes(2..3)
+ },
+ Punct {
+ char: '+',
+ spacing: Alone,
+ span: bytes(4..5)
+ },
+ Literal {
+ lit: 1,
+ span: bytes(6..7)
+ }
+ ],
+ span: bytes(1..8)
+ }
+]\
+ ";
+
+ let actual = format!("{:#?}", tts);
+ if actual.ends_with(",\n]") {
+ assert_eq!(expected, actual);
+ } else {
+ assert_eq!(expected_before_trailing_commas, actual);
+ }
+}
+
+#[test]
+fn default_tokenstream_is_empty() {
+ let default_token_stream = <TokenStream as Default>::default();
+
+ assert!(default_token_stream.is_empty());
+}
+
+#[test]
+fn tokenstream_size_hint() {
+ let tokens = "a b (c d) e".parse::<TokenStream>().unwrap();
+
+ assert_eq!(tokens.into_iter().size_hint(), (4, Some(4)));
+}
+
+#[test]
+fn tuple_indexing() {
+ // This behavior may change depending on https://github.com/rust-lang/rust/pull/71322
+ let mut tokens = "tuple.0.0".parse::<TokenStream>().unwrap().into_iter();
+ assert_eq!("tuple", tokens.next().unwrap().to_string());
+ assert_eq!(".", tokens.next().unwrap().to_string());
+ assert_eq!("0.0", tokens.next().unwrap().to_string());
+ assert!(tokens.next().is_none());
+}
+
+#[cfg(span_locations)]
+#[test]
+fn non_ascii_tokens() {
+ check_spans("// abc", &[]);
+ check_spans("// ábc", &[]);
+ check_spans("// abc x", &[]);
+ check_spans("// ábc x", &[]);
+ check_spans("/* abc */ x", &[(1, 10, 1, 11)]);
+ check_spans("/* ábc */ x", &[(1, 10, 1, 11)]);
+ check_spans("/* ab\nc */ x", &[(2, 5, 2, 6)]);
+ check_spans("/* áb\nc */ x", &[(2, 5, 2, 6)]);
+ check_spans("/*** abc */ x", &[(1, 12, 1, 13)]);
+ check_spans("/*** ábc */ x", &[(1, 12, 1, 13)]);
+ check_spans(r#""abc""#, &[(1, 0, 1, 5)]);
+ check_spans(r#""ábc""#, &[(1, 0, 1, 5)]);
+ check_spans(r##"r#"abc"#"##, &[(1, 0, 1, 8)]);
+ check_spans(r##"r#"ábc"#"##, &[(1, 0, 1, 8)]);
+ check_spans("r#\"a\nc\"#", &[(1, 0, 2, 3)]);
+ check_spans("r#\"á\nc\"#", &[(1, 0, 2, 3)]);
+ check_spans("'a'", &[(1, 0, 1, 3)]);
+ check_spans("'á'", &[(1, 0, 1, 3)]);
+ check_spans("//! abc", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]);
+ check_spans("//! ábc", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]);
+ check_spans("//! abc\n", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]);
+ check_spans("//! ábc\n", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]);
+ check_spans("/*! abc */", &[(1, 0, 1, 10), (1, 0, 1, 10), (1, 0, 1, 10)]);
+ check_spans("/*! ábc */", &[(1, 0, 1, 10), (1, 0, 1, 10), (1, 0, 1, 10)]);
+ check_spans("/*! a\nc */", &[(1, 0, 2, 4), (1, 0, 2, 4), (1, 0, 2, 4)]);
+ check_spans("/*! á\nc */", &[(1, 0, 2, 4), (1, 0, 2, 4), (1, 0, 2, 4)]);
+ check_spans("abc", &[(1, 0, 1, 3)]);
+ check_spans("ábc", &[(1, 0, 1, 3)]);
+ check_spans("ábć", &[(1, 0, 1, 3)]);
+ check_spans("abc// foo", &[(1, 0, 1, 3)]);
+ check_spans("ábc// foo", &[(1, 0, 1, 3)]);
+ check_spans("ábć// foo", &[(1, 0, 1, 3)]);
+ check_spans("b\"a\\\n c\"", &[(1, 0, 2, 3)]);
+}
+
+#[cfg(span_locations)]
+fn check_spans(p: &str, mut lines: &[(usize, usize, usize, usize)]) {
+ let ts = p.parse::<TokenStream>().unwrap();
+ check_spans_internal(ts, &mut lines);
+ assert!(lines.is_empty(), "leftover ranges: {:?}", lines);
+}
+
+#[cfg(span_locations)]
+fn check_spans_internal(ts: TokenStream, lines: &mut &[(usize, usize, usize, usize)]) {
+ for i in ts {
+ if let Some((&(sline, scol, eline, ecol), rest)) = lines.split_first() {
+ *lines = rest;
+
+ let start = i.span().start();
+ assert_eq!(start.line, sline, "sline did not match for {}", i);
+ assert_eq!(start.column, scol, "scol did not match for {}", i);
+
+ let end = i.span().end();
+ assert_eq!(end.line, eline, "eline did not match for {}", i);
+ assert_eq!(end.column, ecol, "ecol did not match for {}", i);
+
+ if let TokenTree::Group(g) = i {
+ check_spans_internal(g.stream().clone(), lines);
+ }
+ }
+ }
+}
+
+#[test]
+fn whitespace() {
+ // space, horizontal tab, vertical tab, form feed, carriage return, line
+ // feed, non-breaking space, left-to-right mark, right-to-left mark
+ let various_spaces = " \t\u{b}\u{c}\r\n\u{a0}\u{200e}\u{200f}";
+ let tokens = various_spaces.parse::<TokenStream>().unwrap();
+ assert_eq!(tokens.into_iter().count(), 0);
+
+ let lone_carriage_returns = " \r \r\r\n ";
+ lone_carriage_returns.parse::<TokenStream>().unwrap();
+}
+
+#[test]
+fn byte_order_mark() {
+ let string = "\u{feff}foo";
+ let tokens = string.parse::<TokenStream>().unwrap();
+ match tokens.into_iter().next().unwrap() {
+ TokenTree::Ident(ident) => assert_eq!(ident, "foo"),
+ _ => unreachable!(),
+ }
+
+ let string = "foo\u{feff}";
+ string.parse::<TokenStream>().unwrap_err();
+}
+
+#[cfg(span_locations)]
+fn create_span() -> proc_macro2::Span {
+ let tts: TokenStream = "1".parse().unwrap();
+ match tts.into_iter().next().unwrap() {
+ TokenTree::Literal(literal) => literal.span(),
+ _ => unreachable!(),
+ }
+}
+
+#[cfg(span_locations)]
+#[test]
+fn test_invalidate_current_thread_spans() {
+ let actual = format!("{:#?}", create_span());
+ assert_eq!(actual, "bytes(1..2)");
+ let actual = format!("{:#?}", create_span());
+ assert_eq!(actual, "bytes(3..4)");
+
+ proc_macro2::extra::invalidate_current_thread_spans();
+
+ let actual = format!("{:#?}", create_span());
+ // Test that span offsets have been reset after the call
+ // to invalidate_current_thread_spans()
+ assert_eq!(actual, "bytes(1..2)");
+}
+
+#[cfg(span_locations)]
+#[test]
+#[should_panic(expected = "Invalid span with no related FileInfo!")]
+fn test_use_span_after_invalidation() {
+ let span = create_span();
+
+ proc_macro2::extra::invalidate_current_thread_spans();
+
+ span.source_text();
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/tests/test_fmt.rs b/rust/hw/char/pl011/vendor/proc-macro2/tests/test_fmt.rs
new file mode 100644
index 0000000000..86a4c38763
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/tests/test_fmt.rs
@@ -0,0 +1,28 @@
+#![allow(clippy::from_iter_instead_of_collect)]
+
+use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
+use std::iter;
+
+#[test]
+fn test_fmt_group() {
+ let ident = Ident::new("x", Span::call_site());
+ let inner = TokenStream::from_iter(iter::once(TokenTree::Ident(ident)));
+ let parens_empty = Group::new(Delimiter::Parenthesis, TokenStream::new());
+ let parens_nonempty = Group::new(Delimiter::Parenthesis, inner.clone());
+ let brackets_empty = Group::new(Delimiter::Bracket, TokenStream::new());
+ let brackets_nonempty = Group::new(Delimiter::Bracket, inner.clone());
+ let braces_empty = Group::new(Delimiter::Brace, TokenStream::new());
+ let braces_nonempty = Group::new(Delimiter::Brace, inner.clone());
+ let none_empty = Group::new(Delimiter::None, TokenStream::new());
+ let none_nonempty = Group::new(Delimiter::None, inner);
+
+ // Matches libproc_macro.
+ assert_eq!("()", parens_empty.to_string());
+ assert_eq!("(x)", parens_nonempty.to_string());
+ assert_eq!("[]", brackets_empty.to_string());
+ assert_eq!("[x]", brackets_nonempty.to_string());
+ assert_eq!("{ }", braces_empty.to_string());
+ assert_eq!("{ x }", braces_nonempty.to_string());
+ assert_eq!("", none_empty.to_string());
+ assert_eq!("x", none_nonempty.to_string());
+}
diff --git a/rust/hw/char/pl011/vendor/proc-macro2/tests/test_size.rs b/rust/hw/char/pl011/vendor/proc-macro2/tests/test_size.rs
new file mode 100644
index 0000000000..7b0739023a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/proc-macro2/tests/test_size.rs
@@ -0,0 +1,73 @@
+#![cfg(not(randomize_layout))]
+
+extern crate proc_macro;
+
+use std::mem;
+
+#[rustversion::attr(before(1.64), ignore)]
+#[test]
+fn test_proc_macro_size() {
+ assert_eq!(mem::size_of::<proc_macro::Span>(), 4);
+ assert_eq!(mem::size_of::<Option<proc_macro::Span>>(), 4);
+ assert_eq!(mem::size_of::<proc_macro::Group>(), 20);
+ assert_eq!(mem::size_of::<proc_macro::Ident>(), 12);
+ assert_eq!(mem::size_of::<proc_macro::Punct>(), 8);
+ assert_eq!(mem::size_of::<proc_macro::Literal>(), 16);
+ assert_eq!(mem::size_of::<proc_macro::TokenStream>(), 4);
+}
+
+#[cfg_attr(not(all(not(wrap_proc_macro), not(span_locations))), ignore)]
+#[test]
+fn test_proc_macro2_fallback_size_without_locations() {
+ assert_eq!(mem::size_of::<proc_macro2::Span>(), 0);
+ assert_eq!(mem::size_of::<Option<proc_macro2::Span>>(), 1);
+ assert_eq!(mem::size_of::<proc_macro2::Group>(), 16);
+ assert_eq!(mem::size_of::<proc_macro2::Ident>(), 24);
+ assert_eq!(mem::size_of::<proc_macro2::Punct>(), 8);
+ assert_eq!(mem::size_of::<proc_macro2::Literal>(), 24);
+ assert_eq!(mem::size_of::<proc_macro2::TokenStream>(), 8);
+}
+
+#[cfg_attr(not(all(not(wrap_proc_macro), span_locations)), ignore)]
+#[test]
+fn test_proc_macro2_fallback_size_with_locations() {
+ assert_eq!(mem::size_of::<proc_macro2::Span>(), 8);
+ assert_eq!(mem::size_of::<Option<proc_macro2::Span>>(), 12);
+ assert_eq!(mem::size_of::<proc_macro2::Group>(), 24);
+ assert_eq!(mem::size_of::<proc_macro2::Ident>(), 32);
+ assert_eq!(mem::size_of::<proc_macro2::Punct>(), 16);
+ assert_eq!(mem::size_of::<proc_macro2::Literal>(), 32);
+ assert_eq!(mem::size_of::<proc_macro2::TokenStream>(), 8);
+}
+
+#[rustversion::attr(before(1.71), ignore)]
+#[rustversion::attr(
+ since(1.71),
+ cfg_attr(not(all(wrap_proc_macro, not(span_locations))), ignore)
+)]
+#[test]
+fn test_proc_macro2_wrapper_size_without_locations() {
+ assert_eq!(mem::size_of::<proc_macro2::Span>(), 4);
+ assert_eq!(mem::size_of::<Option<proc_macro2::Span>>(), 8);
+ assert_eq!(mem::size_of::<proc_macro2::Group>(), 24);
+ assert_eq!(mem::size_of::<proc_macro2::Ident>(), 24);
+ assert_eq!(mem::size_of::<proc_macro2::Punct>(), 12);
+ assert_eq!(mem::size_of::<proc_macro2::Literal>(), 24);
+ assert_eq!(mem::size_of::<proc_macro2::TokenStream>(), 32);
+}
+
+#[rustversion::attr(before(1.65), ignore)]
+#[rustversion::attr(
+ since(1.65),
+ cfg_attr(not(all(wrap_proc_macro, span_locations)), ignore)
+)]
+#[test]
+fn test_proc_macro2_wrapper_size_with_locations() {
+ assert_eq!(mem::size_of::<proc_macro2::Span>(), 12);
+ assert_eq!(mem::size_of::<Option<proc_macro2::Span>>(), 12);
+ assert_eq!(mem::size_of::<proc_macro2::Group>(), 32);
+ assert_eq!(mem::size_of::<proc_macro2::Ident>(), 32);
+ assert_eq!(mem::size_of::<proc_macro2::Punct>(), 20);
+ assert_eq!(mem::size_of::<proc_macro2::Literal>(), 32);
+ assert_eq!(mem::size_of::<proc_macro2::TokenStream>(), 32);
+}
diff --git a/rust/hw/char/pl011/vendor/quote/.cargo-checksum.json b/rust/hw/char/pl011/vendor/quote/.cargo-checksum.json
new file mode 100644
index 0000000000..dcfc52a21e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"0a98ab1241e7b64caa29c6ff868e2e96e0f74c1ef8b265727f1863a960fa322c","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"626e7079eab0baacf0fcaf3e244f407b2014ebaeca45905d72e8fb8bed18aaea","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/ext.rs":"9881576cac3e476a4bf04f9b601cf9a53b79399fb0ca9634e8b861ac91709843","src/format.rs":"c595015418f35e6992e710441b9999f09b2afe4678b138039d670d100c0bdd86","src/ident_fragment.rs":"0b3e6c2129e55910fd2d240e1e7efba6f1796801d24352d1c0bfbceb0e8b678f","src/lib.rs":"abbc178821e46d0bcd224904a7542ac4582d189f57cd4daf02a54fd772e52a55","src/runtime.rs":"7f37326edaeac2c42ed806b447eeba12e36dd4b1bc25fbf52f8eb23140f3be7a","src/spanned.rs":"3ccf5120593f35787442c0a37d243e802c5262e7f8b35aed503873008ec035c5","src/to_tokens.rs":"1c76311fcc82098e630056d71fd6f3929194ee31b0840e2aa643ed7e78026e3e","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/test.rs":"3be80741f84a707376c230d9cf70ce9537caa359691d8d4c34968e28175e4ad7","tests/ui/does-not-have-iter-interpolated-dup.rs":"ad13eea21d4cdd2ab6c082f633392e1ff20fb0d1af5f2177041e0bf7f30da695","tests/ui/does-not-have-iter-interpolated-dup.stderr":"90a4bdb9267535f5d2785940148338d6b7d905548051d2c9c5dcbd58f2c11d8e","tests/ui/does-not-have-iter-interpolated.rs":"83a5b3f240651adcbe4b6e51076d76d653ad439b37442cf4054f1fd3c073f3b7","tests/ui/does-not-have-iter-interpolated.stderr":"ae7c2739554c862b331705e82781aa4687a4375210cef6ae899a4be4a4ec2d97","tests/ui/does-not-have-iter-separated.rs":"fe413c48331d5e3a7ae5fef6a5892a90c72f610d54595879eb49d0a94154ba3f","tests/ui/does-not-have-iter-separated.stderr":"03fd560979ebcd5aa6f83858bc2c3c01ba6546c16335101275505304895c1ae9","tests/ui/does-not-have-iter.rs":"09dc9499d861b63cebb0848b855b78e2dc9497bfde37ba6339f3625ae009a62f","tests/ui/does-not-have-iter.stderr":"d6da483c29e232ced72059bbdf05d31afb1df9e02954edaa9cfaea1ec6df72dc","tests/ui/not-quotable.rs":"5759d0884943417609f28faadc70254a3e2fd3d9bd6ff7297a3fb70a77fafd8a","tests/ui/not-quotable.stderr":"1b5ad13712a35f2f25a159c003956762941b111d540b20ad6a258cdb079a9c95","tests/ui/not-repeatable.rs":"a4b115c04e4e41049a05f5b69450503fbffeba031218b4189cb931839f7f9a9c","tests/ui/not-repeatable.stderr":"bbfb702638374001061251f81d63476851ac28ed743f13db9d65e30dd9bdcf52","tests/ui/wrong-type-span.rs":"6195e35ea844c0c52ba1cff5d790c3a371af6915d137d377834ad984229ef9ea","tests/ui/wrong-type-span.stderr":"cad072e40e0ecc04f375122ae41aede2f0da2a9244492b3fcf70249e59d1b128"},"package":"0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/quote/Cargo.toml b/rust/hw/char/pl011/vendor/quote/Cargo.toml
new file mode 100644
index 0000000000..5b521762bc
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/Cargo.toml
@@ -0,0 +1,50 @@
+# 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 = "2018"
+rust-version = "1.56"
+name = "quote"
+version = "1.0.36"
+authors = ["David Tolnay <dtolnay@gmail.com>"]
+autobenches = false
+description = "Quasi-quoting macro quote!(...)"
+documentation = "https://docs.rs/quote/"
+readme = "README.md"
+keywords = [
+ "macros",
+ "syn",
+]
+categories = ["development-tools::procedural-macro-helpers"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/dtolnay/quote"
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--generate-link-to-definition"]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+doc-scrape-examples = false
+
+[dependencies.proc-macro2]
+version = "1.0.74"
+default-features = false
+
+[dev-dependencies.rustversion]
+version = "1.0"
+
+[dev-dependencies.trybuild]
+version = "1.0.66"
+features = ["diff"]
+
+[features]
+default = ["proc-macro"]
+proc-macro = ["proc-macro2/proc-macro"]
diff --git a/rust/hw/char/pl011/vendor/quote/LICENSE-APACHE b/rust/hw/char/pl011/vendor/quote/LICENSE-APACHE
new file mode 100644
index 0000000000..1b5ec8b78e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/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/rust/hw/char/pl011/vendor/quote/LICENSE-MIT b/rust/hw/char/pl011/vendor/quote/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/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/rust/hw/char/pl011/vendor/quote/README.md b/rust/hw/char/pl011/vendor/quote/README.md
new file mode 100644
index 0000000000..bfc91a9753
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/README.md
@@ -0,0 +1,272 @@
+Rust Quasi-Quoting
+==================
+
+[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/quote-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/quote)
+[<img alt="crates.io" src="https://img.shields.io/crates/v/quote.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/quote)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-quote-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/quote)
+[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/quote/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/quote/actions?query=branch%3Amaster)
+
+This crate provides the [`quote!`] macro for turning Rust syntax tree data
+structures into tokens of source code.
+
+[`quote!`]: https://docs.rs/quote/1.0/quote/macro.quote.html
+
+Procedural macros in Rust receive a stream of tokens as input, execute arbitrary
+Rust code to determine how to manipulate those tokens, and produce a stream of
+tokens to hand back to the compiler to compile into the caller's crate.
+Quasi-quoting is a solution to one piece of that — producing tokens to
+return to the compiler.
+
+The idea of quasi-quoting is that we write *code* that we treat as *data*.
+Within the `quote!` macro, we can write what looks like code to our text editor
+or IDE. We get all the benefits of the editor's brace matching, syntax
+highlighting, indentation, and maybe autocompletion. But rather than compiling
+that as code into the current crate, we can treat it as data, pass it around,
+mutate it, and eventually hand it back to the compiler as tokens to compile into
+the macro caller's crate.
+
+This crate is motivated by the procedural macro use case, but is a
+general-purpose Rust quasi-quoting library and is not specific to procedural
+macros.
+
+```toml
+[dependencies]
+quote = "1.0"
+```
+
+*Version requirement: Quote supports rustc 1.56 and up.*<br>
+[*Release notes*](https://github.com/dtolnay/quote/releases)
+
+<br>
+
+## Syntax
+
+The quote crate provides a [`quote!`] macro within which you can write Rust code
+that gets packaged into a [`TokenStream`] and can be treated as data. You should
+think of `TokenStream` as representing a fragment of Rust source code.
+
+[`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html
+
+Within the `quote!` macro, interpolation is done with `#var`. Any type
+implementing the [`quote::ToTokens`] trait can be interpolated. This includes
+most Rust primitive types as well as most of the syntax tree types from [`syn`].
+
+[`quote::ToTokens`]: https://docs.rs/quote/1.0/quote/trait.ToTokens.html
+[`syn`]: https://github.com/dtolnay/syn
+
+```rust
+let tokens = quote! {
+ struct SerializeWith #generics #where_clause {
+ value: &'a #field_ty,
+ phantom: core::marker::PhantomData<#item_ty>,
+ }
+
+ impl #generics serde::Serialize for SerializeWith #generics #where_clause {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ #path(self.value, serializer)
+ }
+ }
+
+ SerializeWith {
+ value: #value,
+ phantom: core::marker::PhantomData::<#item_ty>,
+ }
+};
+```
+
+<br>
+
+## Repetition
+
+Repetition is done using `#(...)*` or `#(...),*` similar to `macro_rules!`. This
+iterates through the elements of any variable interpolated within the repetition
+and inserts a copy of the repetition body for each one. The variables in an
+interpolation may be anything that implements `IntoIterator`, including `Vec` or
+a pre-existing iterator.
+
+- `#(#var)*` — no separators
+- `#(#var),*` — the character before the asterisk is used as a separator
+- `#( struct #var; )*` — the repetition can contain other things
+- `#( #k => println!("{}", #v), )*` — even multiple interpolations
+
+Note that there is a difference between `#(#var ,)*` and `#(#var),*`—the latter
+does not produce a trailing comma. This matches the behavior of delimiters in
+`macro_rules!`.
+
+<br>
+
+## Returning tokens to the compiler
+
+The `quote!` macro evaluates to an expression of type
+`proc_macro2::TokenStream`. Meanwhile Rust procedural macros are expected to
+return the type `proc_macro::TokenStream`.
+
+The difference between the two types is that `proc_macro` types are entirely
+specific to procedural macros and cannot ever exist in code outside of a
+procedural macro, while `proc_macro2` types may exist anywhere including tests
+and non-macro code like main.rs and build.rs. This is why even the procedural
+macro ecosystem is largely built around `proc_macro2`, because that ensures the
+libraries are unit testable and accessible in non-macro contexts.
+
+There is a [`From`]-conversion in both directions so returning the output of
+`quote!` from a procedural macro usually looks like `tokens.into()` or
+`proc_macro::TokenStream::from(tokens)`.
+
+[`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
+
+<br>
+
+## Examples
+
+### Combining quoted fragments
+
+Usually you don't end up constructing an entire final `TokenStream` in one
+piece. Different parts may come from different helper functions. The tokens
+produced by `quote!` themselves implement `ToTokens` and so can be interpolated
+into later `quote!` invocations to build up a final result.
+
+```rust
+let type_definition = quote! {...};
+let methods = quote! {...};
+
+let tokens = quote! {
+ #type_definition
+ #methods
+};
+```
+
+### Constructing identifiers
+
+Suppose we have an identifier `ident` which came from somewhere in a macro
+input and we need to modify it in some way for the macro output. Let's consider
+prepending the identifier with an underscore.
+
+Simply interpolating the identifier next to an underscore will not have the
+behavior of concatenating them. The underscore and the identifier will continue
+to be two separate tokens as if you had written `_ x`.
+
+```rust
+// incorrect
+quote! {
+ let mut _#ident = 0;
+}
+```
+
+The solution is to build a new identifier token with the correct value. As this
+is such a common case, the `format_ident!` macro provides a convenient utility
+for doing so correctly.
+
+```rust
+let varname = format_ident!("_{}", ident);
+quote! {
+ let mut #varname = 0;
+}
+```
+
+Alternatively, the APIs provided by Syn and proc-macro2 can be used to directly
+build the identifier. This is roughly equivalent to the above, but will not
+handle `ident` being a raw identifier.
+
+```rust
+let concatenated = format!("_{}", ident);
+let varname = syn::Ident::new(&concatenated, ident.span());
+quote! {
+ let mut #varname = 0;
+}
+```
+
+### Making method calls
+
+Let's say our macro requires some type specified in the macro input to have a
+constructor called `new`. We have the type in a variable called `field_type` of
+type `syn::Type` and want to invoke the constructor.
+
+```rust
+// incorrect
+quote! {
+ let value = #field_type::new();
+}
+```
+
+This works only sometimes. If `field_type` is `String`, the expanded code
+contains `String::new()` which is fine. But if `field_type` is something like
+`Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid syntax.
+Ordinarily in handwritten Rust we would write `Vec::<i32>::new()` but for macros
+often the following is more convenient.
+
+```rust
+quote! {
+ let value = <#field_type>::new();
+}
+```
+
+This expands to `<Vec<i32>>::new()` which behaves correctly.
+
+A similar pattern is appropriate for trait methods.
+
+```rust
+quote! {
+ let value = <#field_type as core::default::Default>::default();
+}
+```
+
+<br>
+
+## Hygiene
+
+Any interpolated tokens preserve the `Span` information provided by their
+`ToTokens` implementation. Tokens that originate within a `quote!` invocation
+are spanned with [`Span::call_site()`].
+
+[`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site
+
+A different span can be provided explicitly through the [`quote_spanned!`]
+macro.
+
+[`quote_spanned!`]: https://docs.rs/quote/1.0/quote/macro.quote_spanned.html
+
+<br>
+
+## Non-macro code generators
+
+When using `quote` in a build.rs or main.rs and writing the output out to a
+file, consider having the code generator pass the tokens through [prettyplease]
+before writing. This way if an error occurs in the generated code it is
+convenient for a human to read and debug.
+
+Be aware that no kind of hygiene or span information is retained when tokens are
+written to a file; the conversion from tokens to source code is lossy.
+
+Example usage in build.rs:
+
+```rust
+let output = quote! { ... };
+let syntax_tree = syn::parse2(output).unwrap();
+let formatted = prettyplease::unparse(&syntax_tree);
+
+let out_dir = env::var_os("OUT_DIR").unwrap();
+let dest_path = Path::new(&out_dir).join("out.rs");
+fs::write(dest_path, formatted).unwrap();
+```
+
+[prettyplease]: https://github.com/dtolnay/prettyplease
+
+<br>
+
+#### License
+
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
+
+<br>
+
+<sub>
+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.
+</sub>
diff --git a/rust/hw/char/pl011/vendor/quote/meson.build b/rust/hw/char/pl011/vendor/quote/meson.build
new file mode 100644
index 0000000000..11b83932f6
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/meson.build
@@ -0,0 +1,17 @@
+_quote_rs = static_library(
+ 'quote',
+ files('src/lib.rs'),
+ gnu_symbol_visibility: 'hidden',
+ rust_abi: 'rust',
+ rust_args: rust_args + [
+ '--edition', '2021',
+ '--cfg', 'feature="proc-macro"',
+ ],
+ dependencies: [
+ dep_proc_macro2,
+ ],
+)
+
+dep_quote = declare_dependency(
+ link_with: _quote_rs,
+)
diff --git a/rust/hw/char/pl011/vendor/quote/rust-toolchain.toml b/rust/hw/char/pl011/vendor/quote/rust-toolchain.toml
new file mode 100644
index 0000000000..20fe888c30
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/rust-toolchain.toml
@@ -0,0 +1,2 @@
+[toolchain]
+components = ["rust-src"]
diff --git a/rust/hw/char/pl011/vendor/quote/src/ext.rs b/rust/hw/char/pl011/vendor/quote/src/ext.rs
new file mode 100644
index 0000000000..92c2315b18
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/src/ext.rs
@@ -0,0 +1,110 @@
+use super::ToTokens;
+use core::iter;
+use proc_macro2::{TokenStream, TokenTree};
+
+/// TokenStream extension trait with methods for appending tokens.
+///
+/// This trait is sealed and cannot be implemented outside of the `quote` crate.
+pub trait TokenStreamExt: private::Sealed {
+ /// For use by `ToTokens` implementations.
+ ///
+ /// Appends the token specified to this list of tokens.
+ fn append<U>(&mut self, token: U)
+ where
+ U: Into<TokenTree>;
+
+ /// For use by `ToTokens` implementations.
+ ///
+ /// ```
+ /// # use quote::{quote, TokenStreamExt, ToTokens};
+ /// # use proc_macro2::TokenStream;
+ /// #
+ /// struct X;
+ ///
+ /// impl ToTokens for X {
+ /// fn to_tokens(&self, tokens: &mut TokenStream) {
+ /// tokens.append_all(&[true, false]);
+ /// }
+ /// }
+ ///
+ /// let tokens = quote!(#X);
+ /// assert_eq!(tokens.to_string(), "true false");
+ /// ```
+ fn append_all<I>(&mut self, iter: I)
+ where
+ I: IntoIterator,
+ I::Item: ToTokens;
+
+ /// For use by `ToTokens` implementations.
+ ///
+ /// Appends all of the items in the iterator `I`, separated by the tokens
+ /// `U`.
+ fn append_separated<I, U>(&mut self, iter: I, op: U)
+ where
+ I: IntoIterator,
+ I::Item: ToTokens,
+ U: ToTokens;
+
+ /// For use by `ToTokens` implementations.
+ ///
+ /// Appends all tokens in the iterator `I`, appending `U` after each
+ /// element, including after the last element of the iterator.
+ fn append_terminated<I, U>(&mut self, iter: I, term: U)
+ where
+ I: IntoIterator,
+ I::Item: ToTokens,
+ U: ToTokens;
+}
+
+impl TokenStreamExt for TokenStream {
+ fn append<U>(&mut self, token: U)
+ where
+ U: Into<TokenTree>,
+ {
+ self.extend(iter::once(token.into()));
+ }
+
+ fn append_all<I>(&mut self, iter: I)
+ where
+ I: IntoIterator,
+ I::Item: ToTokens,
+ {
+ for token in iter {
+ token.to_tokens(self);
+ }
+ }
+
+ fn append_separated<I, U>(&mut self, iter: I, op: U)
+ where
+ I: IntoIterator,
+ I::Item: ToTokens,
+ U: ToTokens,
+ {
+ for (i, token) in iter.into_iter().enumerate() {
+ if i > 0 {
+ op.to_tokens(self);
+ }
+ token.to_tokens(self);
+ }
+ }
+
+ fn append_terminated<I, U>(&mut self, iter: I, term: U)
+ where
+ I: IntoIterator,
+ I::Item: ToTokens,
+ U: ToTokens,
+ {
+ for token in iter {
+ token.to_tokens(self);
+ term.to_tokens(self);
+ }
+ }
+}
+
+mod private {
+ use proc_macro2::TokenStream;
+
+ pub trait Sealed {}
+
+ impl Sealed for TokenStream {}
+}
diff --git a/rust/hw/char/pl011/vendor/quote/src/format.rs b/rust/hw/char/pl011/vendor/quote/src/format.rs
new file mode 100644
index 0000000000..3cddbd2819
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/src/format.rs
@@ -0,0 +1,168 @@
+/// Formatting macro for constructing `Ident`s.
+///
+/// <br>
+///
+/// # Syntax
+///
+/// Syntax is copied from the [`format!`] macro, supporting both positional and
+/// named arguments.
+///
+/// Only a limited set of formatting traits are supported. The current mapping
+/// of format types to traits is:
+///
+/// * `{}` ⇒ [`IdentFragment`]
+/// * `{:o}` ⇒ [`Octal`](std::fmt::Octal)
+/// * `{:x}` ⇒ [`LowerHex`](std::fmt::LowerHex)
+/// * `{:X}` ⇒ [`UpperHex`](std::fmt::UpperHex)
+/// * `{:b}` ⇒ [`Binary`](std::fmt::Binary)
+///
+/// See [`std::fmt`] for more information.
+///
+/// <br>
+///
+/// # IdentFragment
+///
+/// Unlike `format!`, this macro uses the [`IdentFragment`] formatting trait by
+/// default. This trait is like `Display`, with a few differences:
+///
+/// * `IdentFragment` is only implemented for a limited set of types, such as
+/// unsigned integers and strings.
+/// * [`Ident`] arguments will have their `r#` prefixes stripped, if present.
+///
+/// [`IdentFragment`]: crate::IdentFragment
+/// [`Ident`]: proc_macro2::Ident
+///
+/// <br>
+///
+/// # Hygiene
+///
+/// The [`Span`] of the first `Ident` argument is used as the span of the final
+/// identifier, falling back to [`Span::call_site`] when no identifiers are
+/// provided.
+///
+/// ```
+/// # use quote::format_ident;
+/// # let ident = format_ident!("Ident");
+/// // If `ident` is an Ident, the span of `my_ident` will be inherited from it.
+/// let my_ident = format_ident!("My{}{}", ident, "IsCool");
+/// assert_eq!(my_ident, "MyIdentIsCool");
+/// ```
+///
+/// Alternatively, the span can be overridden by passing the `span` named
+/// argument.
+///
+/// ```
+/// # use quote::format_ident;
+/// # const IGNORE_TOKENS: &'static str = stringify! {
+/// let my_span = /* ... */;
+/// # };
+/// # let my_span = proc_macro2::Span::call_site();
+/// format_ident!("MyIdent", span = my_span);
+/// ```
+///
+/// [`Span`]: proc_macro2::Span
+/// [`Span::call_site`]: proc_macro2::Span::call_site
+///
+/// <p><br></p>
+///
+/// # Panics
+///
+/// This method will panic if the resulting formatted string is not a valid
+/// identifier.
+///
+/// <br>
+///
+/// # Examples
+///
+/// Composing raw and non-raw identifiers:
+/// ```
+/// # use quote::format_ident;
+/// let my_ident = format_ident!("My{}", "Ident");
+/// assert_eq!(my_ident, "MyIdent");
+///
+/// let raw = format_ident!("r#Raw");
+/// assert_eq!(raw, "r#Raw");
+///
+/// let my_ident_raw = format_ident!("{}Is{}", my_ident, raw);
+/// assert_eq!(my_ident_raw, "MyIdentIsRaw");
+/// ```
+///
+/// Integer formatting options:
+/// ```
+/// # use quote::format_ident;
+/// let num: u32 = 10;
+///
+/// let decimal = format_ident!("Id_{}", num);
+/// assert_eq!(decimal, "Id_10");
+///
+/// let octal = format_ident!("Id_{:o}", num);
+/// assert_eq!(octal, "Id_12");
+///
+/// let binary = format_ident!("Id_{:b}", num);
+/// assert_eq!(binary, "Id_1010");
+///
+/// let lower_hex = format_ident!("Id_{:x}", num);
+/// assert_eq!(lower_hex, "Id_a");
+///
+/// let upper_hex = format_ident!("Id_{:X}", num);
+/// assert_eq!(upper_hex, "Id_A");
+/// ```
+#[macro_export]
+macro_rules! format_ident {
+ ($fmt:expr) => {
+ $crate::format_ident_impl!([
+ $crate::__private::Option::None,
+ $fmt
+ ])
+ };
+
+ ($fmt:expr, $($rest:tt)*) => {
+ $crate::format_ident_impl!([
+ $crate::__private::Option::None,
+ $fmt
+ ] $($rest)*)
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! format_ident_impl {
+ // Final state
+ ([$span:expr, $($fmt:tt)*]) => {
+ $crate::__private::mk_ident(
+ &$crate::__private::format!($($fmt)*),
+ $span,
+ )
+ };
+
+ // Span argument
+ ([$old:expr, $($fmt:tt)*] span = $span:expr) => {
+ $crate::format_ident_impl!([$old, $($fmt)*] span = $span,)
+ };
+ ([$old:expr, $($fmt:tt)*] span = $span:expr, $($rest:tt)*) => {
+ $crate::format_ident_impl!([
+ $crate::__private::Option::Some::<$crate::__private::Span>($span),
+ $($fmt)*
+ ] $($rest)*)
+ };
+
+ // Named argument
+ ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr) => {
+ $crate::format_ident_impl!([$span, $($fmt)*] $name = $arg,)
+ };
+ ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr, $($rest:tt)*) => {
+ match $crate::__private::IdentFragmentAdapter(&$arg) {
+ arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, $name = arg] $($rest)*),
+ }
+ };
+
+ // Positional argument
+ ([$span:expr, $($fmt:tt)*] $arg:expr) => {
+ $crate::format_ident_impl!([$span, $($fmt)*] $arg,)
+ };
+ ([$span:expr, $($fmt:tt)*] $arg:expr, $($rest:tt)*) => {
+ match $crate::__private::IdentFragmentAdapter(&$arg) {
+ arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, arg] $($rest)*),
+ }
+ };
+}
diff --git a/rust/hw/char/pl011/vendor/quote/src/ident_fragment.rs b/rust/hw/char/pl011/vendor/quote/src/ident_fragment.rs
new file mode 100644
index 0000000000..6c2a9a87ac
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/src/ident_fragment.rs
@@ -0,0 +1,88 @@
+use alloc::borrow::Cow;
+use core::fmt;
+use proc_macro2::{Ident, Span};
+
+/// Specialized formatting trait used by `format_ident!`.
+///
+/// [`Ident`] arguments formatted using this trait will have their `r#` prefix
+/// stripped, if present.
+///
+/// See [`format_ident!`] for more information.
+///
+/// [`format_ident!`]: crate::format_ident
+pub trait IdentFragment {
+ /// Format this value as an identifier fragment.
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result;
+
+ /// Span associated with this `IdentFragment`.
+ ///
+ /// If non-`None`, may be inherited by formatted identifiers.
+ fn span(&self) -> Option<Span> {
+ None
+ }
+}
+
+impl<T: IdentFragment + ?Sized> IdentFragment for &T {
+ fn span(&self) -> Option<Span> {
+ <T as IdentFragment>::span(*self)
+ }
+
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ IdentFragment::fmt(*self, f)
+ }
+}
+
+impl<T: IdentFragment + ?Sized> IdentFragment for &mut T {
+ fn span(&self) -> Option<Span> {
+ <T as IdentFragment>::span(*self)
+ }
+
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ IdentFragment::fmt(*self, f)
+ }
+}
+
+impl IdentFragment for Ident {
+ fn span(&self) -> Option<Span> {
+ Some(self.span())
+ }
+
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let id = self.to_string();
+ if let Some(id) = id.strip_prefix("r#") {
+ fmt::Display::fmt(id, f)
+ } else {
+ fmt::Display::fmt(&id[..], f)
+ }
+ }
+}
+
+impl<T> IdentFragment for Cow<'_, T>
+where
+ T: IdentFragment + ToOwned + ?Sized,
+{
+ fn span(&self) -> Option<Span> {
+ T::span(self)
+ }
+
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ T::fmt(self, f)
+ }
+}
+
+// Limited set of types which this is implemented for, as we want to avoid types
+// which will often include non-identifier characters in their `Display` impl.
+macro_rules! ident_fragment_display {
+ ($($T:ty),*) => {
+ $(
+ impl IdentFragment for $T {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(self, f)
+ }
+ }
+ )*
+ };
+}
+
+ident_fragment_display!(bool, str, String, char);
+ident_fragment_display!(u8, u16, u32, u64, u128, usize);
diff --git a/rust/hw/char/pl011/vendor/quote/src/lib.rs b/rust/hw/char/pl011/vendor/quote/src/lib.rs
new file mode 100644
index 0000000000..4d198cb2e7
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/src/lib.rs
@@ -0,0 +1,1464 @@
+//! [![github]](https://github.com/dtolnay/quote) [![crates-io]](https://crates.io/crates/quote) [![docs-rs]](https://docs.rs/quote)
+//!
+//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
+//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
+//!
+//! <br>
+//!
+//! This crate provides the [`quote!`] macro for turning Rust syntax tree data
+//! structures into tokens of source code.
+//!
+//! [`quote!`]: macro.quote.html
+//!
+//! Procedural macros in Rust receive a stream of tokens as input, execute
+//! arbitrary Rust code to determine how to manipulate those tokens, and produce
+//! a stream of tokens to hand back to the compiler to compile into the caller's
+//! crate. Quasi-quoting is a solution to one piece of that — producing
+//! tokens to return to the compiler.
+//!
+//! The idea of quasi-quoting is that we write *code* that we treat as *data*.
+//! Within the `quote!` macro, we can write what looks like code to our text
+//! editor or IDE. We get all the benefits of the editor's brace matching,
+//! syntax highlighting, indentation, and maybe autocompletion. But rather than
+//! compiling that as code into the current crate, we can treat it as data, pass
+//! it around, mutate it, and eventually hand it back to the compiler as tokens
+//! to compile into the macro caller's crate.
+//!
+//! This crate is motivated by the procedural macro use case, but is a
+//! general-purpose Rust quasi-quoting library and is not specific to procedural
+//! macros.
+//!
+//! ```toml
+//! [dependencies]
+//! quote = "1.0"
+//! ```
+//!
+//! <br>
+//!
+//! # Example
+//!
+//! The following quasi-quoted block of code is something you might find in [a]
+//! procedural macro having to do with data structure serialization. The `#var`
+//! syntax performs interpolation of runtime variables into the quoted tokens.
+//! Check out the documentation of the [`quote!`] macro for more detail about
+//! the syntax. See also the [`quote_spanned!`] macro which is important for
+//! implementing hygienic procedural macros.
+//!
+//! [a]: https://serde.rs/
+//! [`quote_spanned!`]: macro.quote_spanned.html
+//!
+//! ```
+//! # use quote::quote;
+//! #
+//! # let generics = "";
+//! # let where_clause = "";
+//! # let field_ty = "";
+//! # let item_ty = "";
+//! # let path = "";
+//! # let value = "";
+//! #
+//! let tokens = quote! {
+//! struct SerializeWith #generics #where_clause {
+//! value: &'a #field_ty,
+//! phantom: core::marker::PhantomData<#item_ty>,
+//! }
+//!
+//! impl #generics serde::Serialize for SerializeWith #generics #where_clause {
+//! fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+//! where
+//! S: serde::Serializer,
+//! {
+//! #path(self.value, serializer)
+//! }
+//! }
+//!
+//! SerializeWith {
+//! value: #value,
+//! phantom: core::marker::PhantomData::<#item_ty>,
+//! }
+//! };
+//! ```
+//!
+//! <br>
+//!
+//! # Non-macro code generators
+//!
+//! When using `quote` in a build.rs or main.rs and writing the output out to a
+//! file, consider having the code generator pass the tokens through
+//! [prettyplease] before writing. This way if an error occurs in the generated
+//! code it is convenient for a human to read and debug.
+//!
+//! [prettyplease]: https://github.com/dtolnay/prettyplease
+
+// Quote types in rustdoc of other crates get linked to here.
+#![doc(html_root_url = "https://docs.rs/quote/1.0.36")]
+#![allow(
+ clippy::doc_markdown,
+ clippy::missing_errors_doc,
+ clippy::missing_panics_doc,
+ clippy::module_name_repetitions,
+ // false positive https://github.com/rust-lang/rust-clippy/issues/6983
+ clippy::wrong_self_convention,
+)]
+
+extern crate alloc;
+
+#[cfg(feature = "proc-macro")]
+extern crate proc_macro;
+
+mod ext;
+mod format;
+mod ident_fragment;
+mod to_tokens;
+
+// Not public API.
+#[doc(hidden)]
+#[path = "runtime.rs"]
+pub mod __private;
+
+pub use crate::ext::TokenStreamExt;
+pub use crate::ident_fragment::IdentFragment;
+pub use crate::to_tokens::ToTokens;
+
+// Not public API.
+#[doc(hidden)]
+pub mod spanned;
+
+macro_rules! __quote {
+ ($quote:item) => {
+ /// The whole point.
+ ///
+ /// Performs variable interpolation against the input and produces it as
+ /// [`proc_macro2::TokenStream`].
+ ///
+ /// Note: for returning tokens to the compiler in a procedural macro, use
+ /// `.into()` on the result to convert to [`proc_macro::TokenStream`].
+ ///
+ /// [`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html
+ ///
+ /// <br>
+ ///
+ /// # Interpolation
+ ///
+ /// Variable interpolation is done with `#var` (similar to `$var` in
+ /// `macro_rules!` macros). This grabs the `var` variable that is currently in
+ /// scope and inserts it in that location in the output tokens. Any type
+ /// implementing the [`ToTokens`] trait can be interpolated. This includes most
+ /// Rust primitive types as well as most of the syntax tree types from the [Syn]
+ /// crate.
+ ///
+ /// [`ToTokens`]: trait.ToTokens.html
+ /// [Syn]: https://github.com/dtolnay/syn
+ ///
+ /// Repetition is done using `#(...)*` or `#(...),*` again similar to
+ /// `macro_rules!`. This iterates through the elements of any variable
+ /// interpolated within the repetition and inserts a copy of the repetition body
+ /// for each one. The variables in an interpolation may be a `Vec`, slice,
+ /// `BTreeSet`, or any `Iterator`.
+ ///
+ /// - `#(#var)*` — no separators
+ /// - `#(#var),*` — the character before the asterisk is used as a separator
+ /// - `#( struct #var; )*` — the repetition can contain other tokens
+ /// - `#( #k => println!("{}", #v), )*` — even multiple interpolations
+ ///
+ /// <br>
+ ///
+ /// # Hygiene
+ ///
+ /// Any interpolated tokens preserve the `Span` information provided by their
+ /// `ToTokens` implementation. Tokens that originate within the `quote!`
+ /// invocation are spanned with [`Span::call_site()`].
+ ///
+ /// [`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site
+ ///
+ /// A different span can be provided through the [`quote_spanned!`] macro.
+ ///
+ /// [`quote_spanned!`]: macro.quote_spanned.html
+ ///
+ /// <br>
+ ///
+ /// # Return type
+ ///
+ /// The macro evaluates to an expression of type `proc_macro2::TokenStream`.
+ /// Meanwhile Rust procedural macros are expected to return the type
+ /// `proc_macro::TokenStream`.
+ ///
+ /// The difference between the two types is that `proc_macro` types are entirely
+ /// specific to procedural macros and cannot ever exist in code outside of a
+ /// procedural macro, while `proc_macro2` types may exist anywhere including
+ /// tests and non-macro code like main.rs and build.rs. This is why even the
+ /// procedural macro ecosystem is largely built around `proc_macro2`, because
+ /// that ensures the libraries are unit testable and accessible in non-macro
+ /// contexts.
+ ///
+ /// There is a [`From`]-conversion in both directions so returning the output of
+ /// `quote!` from a procedural macro usually looks like `tokens.into()` or
+ /// `proc_macro::TokenStream::from(tokens)`.
+ ///
+ /// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
+ ///
+ /// <br>
+ ///
+ /// # Examples
+ ///
+ /// ### Procedural macro
+ ///
+ /// The structure of a basic procedural macro is as follows. Refer to the [Syn]
+ /// crate for further useful guidance on using `quote!` as part of a procedural
+ /// macro.
+ ///
+ /// [Syn]: https://github.com/dtolnay/syn
+ ///
+ /// ```
+ /// # #[cfg(any())]
+ /// extern crate proc_macro;
+ /// # extern crate proc_macro2;
+ ///
+ /// # #[cfg(any())]
+ /// use proc_macro::TokenStream;
+ /// # use proc_macro2::TokenStream;
+ /// use quote::quote;
+ ///
+ /// # const IGNORE_TOKENS: &'static str = stringify! {
+ /// #[proc_macro_derive(HeapSize)]
+ /// # };
+ /// pub fn derive_heap_size(input: TokenStream) -> TokenStream {
+ /// // Parse the input and figure out what implementation to generate...
+ /// # const IGNORE_TOKENS: &'static str = stringify! {
+ /// let name = /* ... */;
+ /// let expr = /* ... */;
+ /// # };
+ /// #
+ /// # let name = 0;
+ /// # let expr = 0;
+ ///
+ /// let expanded = quote! {
+ /// // The generated impl.
+ /// impl heapsize::HeapSize for #name {
+ /// fn heap_size_of_children(&self) -> usize {
+ /// #expr
+ /// }
+ /// }
+ /// };
+ ///
+ /// // Hand the output tokens back to the compiler.
+ /// TokenStream::from(expanded)
+ /// }
+ /// ```
+ ///
+ /// <p><br></p>
+ ///
+ /// ### Combining quoted fragments
+ ///
+ /// Usually you don't end up constructing an entire final `TokenStream` in one
+ /// piece. Different parts may come from different helper functions. The tokens
+ /// produced by `quote!` themselves implement `ToTokens` and so can be
+ /// interpolated into later `quote!` invocations to build up a final result.
+ ///
+ /// ```
+ /// # use quote::quote;
+ /// #
+ /// let type_definition = quote! {...};
+ /// let methods = quote! {...};
+ ///
+ /// let tokens = quote! {
+ /// #type_definition
+ /// #methods
+ /// };
+ /// ```
+ ///
+ /// <p><br></p>
+ ///
+ /// ### Constructing identifiers
+ ///
+ /// Suppose we have an identifier `ident` which came from somewhere in a macro
+ /// input and we need to modify it in some way for the macro output. Let's
+ /// consider prepending the identifier with an underscore.
+ ///
+ /// Simply interpolating the identifier next to an underscore will not have the
+ /// behavior of concatenating them. The underscore and the identifier will
+ /// continue to be two separate tokens as if you had written `_ x`.
+ ///
+ /// ```
+ /// # use proc_macro2::{self as syn, Span};
+ /// # use quote::quote;
+ /// #
+ /// # let ident = syn::Ident::new("i", Span::call_site());
+ /// #
+ /// // incorrect
+ /// quote! {
+ /// let mut _#ident = 0;
+ /// }
+ /// # ;
+ /// ```
+ ///
+ /// The solution is to build a new identifier token with the correct value. As
+ /// this is such a common case, the [`format_ident!`] macro provides a
+ /// convenient utility for doing so correctly.
+ ///
+ /// ```
+ /// # use proc_macro2::{Ident, Span};
+ /// # use quote::{format_ident, quote};
+ /// #
+ /// # let ident = Ident::new("i", Span::call_site());
+ /// #
+ /// let varname = format_ident!("_{}", ident);
+ /// quote! {
+ /// let mut #varname = 0;
+ /// }
+ /// # ;
+ /// ```
+ ///
+ /// Alternatively, the APIs provided by Syn and proc-macro2 can be used to
+ /// directly build the identifier. This is roughly equivalent to the above, but
+ /// will not handle `ident` being a raw identifier.
+ ///
+ /// ```
+ /// # use proc_macro2::{self as syn, Span};
+ /// # use quote::quote;
+ /// #
+ /// # let ident = syn::Ident::new("i", Span::call_site());
+ /// #
+ /// let concatenated = format!("_{}", ident);
+ /// let varname = syn::Ident::new(&concatenated, ident.span());
+ /// quote! {
+ /// let mut #varname = 0;
+ /// }
+ /// # ;
+ /// ```
+ ///
+ /// <p><br></p>
+ ///
+ /// ### Making method calls
+ ///
+ /// Let's say our macro requires some type specified in the macro input to have
+ /// a constructor called `new`. We have the type in a variable called
+ /// `field_type` of type `syn::Type` and want to invoke the constructor.
+ ///
+ /// ```
+ /// # use quote::quote;
+ /// #
+ /// # let field_type = quote!(...);
+ /// #
+ /// // incorrect
+ /// quote! {
+ /// let value = #field_type::new();
+ /// }
+ /// # ;
+ /// ```
+ ///
+ /// This works only sometimes. If `field_type` is `String`, the expanded code
+ /// contains `String::new()` which is fine. But if `field_type` is something
+ /// like `Vec<i32>` then the expanded code is `Vec<i32>::new()` which is invalid
+ /// syntax. Ordinarily in handwritten Rust we would write `Vec::<i32>::new()`
+ /// but for macros often the following is more convenient.
+ ///
+ /// ```
+ /// # use quote::quote;
+ /// #
+ /// # let field_type = quote!(...);
+ /// #
+ /// quote! {
+ /// let value = <#field_type>::new();
+ /// }
+ /// # ;
+ /// ```
+ ///
+ /// This expands to `<Vec<i32>>::new()` which behaves correctly.
+ ///
+ /// A similar pattern is appropriate for trait methods.
+ ///
+ /// ```
+ /// # use quote::quote;
+ /// #
+ /// # let field_type = quote!(...);
+ /// #
+ /// quote! {
+ /// let value = <#field_type as core::default::Default>::default();
+ /// }
+ /// # ;
+ /// ```
+ ///
+ /// <p><br></p>
+ ///
+ /// ### Interpolating text inside of doc comments
+ ///
+ /// Neither doc comments nor string literals get interpolation behavior in
+ /// quote:
+ ///
+ /// ```compile_fail
+ /// quote! {
+ /// /// try to interpolate: #ident
+ /// ///
+ /// /// ...
+ /// }
+ /// ```
+ ///
+ /// ```compile_fail
+ /// quote! {
+ /// #[doc = "try to interpolate: #ident"]
+ /// }
+ /// ```
+ ///
+ /// Instead the best way to build doc comments that involve variables is by
+ /// formatting the doc string literal outside of quote.
+ ///
+ /// ```rust
+ /// # use proc_macro2::{Ident, Span};
+ /// # use quote::quote;
+ /// #
+ /// # const IGNORE: &str = stringify! {
+ /// let msg = format!(...);
+ /// # };
+ /// #
+ /// # let ident = Ident::new("var", Span::call_site());
+ /// # let msg = format!("try to interpolate: {}", ident);
+ /// quote! {
+ /// #[doc = #msg]
+ /// ///
+ /// /// ...
+ /// }
+ /// # ;
+ /// ```
+ ///
+ /// <p><br></p>
+ ///
+ /// ### Indexing into a tuple struct
+ ///
+ /// When interpolating indices of a tuple or tuple struct, we need them not to
+ /// appears suffixed as integer literals by interpolating them as [`syn::Index`]
+ /// instead.
+ ///
+ /// [`syn::Index`]: https://docs.rs/syn/2.0/syn/struct.Index.html
+ ///
+ /// ```compile_fail
+ /// let i = 0usize..self.fields.len();
+ ///
+ /// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ...
+ /// // which is not valid syntax
+ /// quote! {
+ /// 0 #( + self.#i.heap_size() )*
+ /// }
+ /// ```
+ ///
+ /// ```
+ /// # use proc_macro2::{Ident, TokenStream};
+ /// # use quote::quote;
+ /// #
+ /// # mod syn {
+ /// # use proc_macro2::{Literal, TokenStream};
+ /// # use quote::{ToTokens, TokenStreamExt};
+ /// #
+ /// # pub struct Index(usize);
+ /// #
+ /// # impl From<usize> for Index {
+ /// # fn from(i: usize) -> Self {
+ /// # Index(i)
+ /// # }
+ /// # }
+ /// #
+ /// # impl ToTokens for Index {
+ /// # fn to_tokens(&self, tokens: &mut TokenStream) {
+ /// # tokens.append(Literal::usize_unsuffixed(self.0));
+ /// # }
+ /// # }
+ /// # }
+ /// #
+ /// # struct Struct {
+ /// # fields: Vec<Ident>,
+ /// # }
+ /// #
+ /// # impl Struct {
+ /// # fn example(&self) -> TokenStream {
+ /// let i = (0..self.fields.len()).map(syn::Index::from);
+ ///
+ /// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ...
+ /// quote! {
+ /// 0 #( + self.#i.heap_size() )*
+ /// }
+ /// # }
+ /// # }
+ /// ```
+ $quote
+ };
+}
+
+#[cfg(doc)]
+__quote![
+ #[macro_export]
+ macro_rules! quote {
+ ($($tt:tt)*) => {
+ ...
+ };
+ }
+];
+
+#[cfg(not(doc))]
+__quote![
+ #[macro_export]
+ macro_rules! quote {
+ () => {
+ $crate::__private::TokenStream::new()
+ };
+
+ // Special case rule for a single tt, for performance.
+ ($tt:tt) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ $crate::quote_token!{$tt _s}
+ _s
+ }};
+
+ // Special case rules for two tts, for performance.
+ (# $var:ident) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ $crate::ToTokens::to_tokens(&$var, &mut _s);
+ _s
+ }};
+ ($tt1:tt $tt2:tt) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ $crate::quote_token!{$tt1 _s}
+ $crate::quote_token!{$tt2 _s}
+ _s
+ }};
+
+ // Rule for any other number of tokens.
+ ($($tt:tt)*) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ $crate::quote_each_token!{_s $($tt)*}
+ _s
+ }};
+ }
+];
+
+macro_rules! __quote_spanned {
+ ($quote_spanned:item) => {
+ /// Same as `quote!`, but applies a given span to all tokens originating within
+ /// the macro invocation.
+ ///
+ /// <br>
+ ///
+ /// # Syntax
+ ///
+ /// A span expression of type [`Span`], followed by `=>`, followed by the tokens
+ /// to quote. The span expression should be brief — use a variable for
+ /// anything more than a few characters. There should be no space before the
+ /// `=>` token.
+ ///
+ /// [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html
+ ///
+ /// ```
+ /// # use proc_macro2::Span;
+ /// # use quote::quote_spanned;
+ /// #
+ /// # const IGNORE_TOKENS: &'static str = stringify! {
+ /// let span = /* ... */;
+ /// # };
+ /// # let span = Span::call_site();
+ /// # let init = 0;
+ ///
+ /// // On one line, use parentheses.
+ /// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init)));
+ ///
+ /// // On multiple lines, place the span at the top and use braces.
+ /// let tokens = quote_spanned! {span=>
+ /// Box::into_raw(Box::new(#init))
+ /// };
+ /// ```
+ ///
+ /// The lack of space before the `=>` should look jarring to Rust programmers
+ /// and this is intentional. The formatting is designed to be visibly
+ /// off-balance and draw the eye a particular way, due to the span expression
+ /// being evaluated in the context of the procedural macro and the remaining
+ /// tokens being evaluated in the generated code.
+ ///
+ /// <br>
+ ///
+ /// # Hygiene
+ ///
+ /// Any interpolated tokens preserve the `Span` information provided by their
+ /// `ToTokens` implementation. Tokens that originate within the `quote_spanned!`
+ /// invocation are spanned with the given span argument.
+ ///
+ /// <br>
+ ///
+ /// # Example
+ ///
+ /// The following procedural macro code uses `quote_spanned!` to assert that a
+ /// particular Rust type implements the [`Sync`] trait so that references can be
+ /// safely shared between threads.
+ ///
+ /// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
+ ///
+ /// ```
+ /// # use quote::{quote_spanned, TokenStreamExt, ToTokens};
+ /// # use proc_macro2::{Span, TokenStream};
+ /// #
+ /// # struct Type;
+ /// #
+ /// # impl Type {
+ /// # fn span(&self) -> Span {
+ /// # Span::call_site()
+ /// # }
+ /// # }
+ /// #
+ /// # impl ToTokens for Type {
+ /// # fn to_tokens(&self, _tokens: &mut TokenStream) {}
+ /// # }
+ /// #
+ /// # let ty = Type;
+ /// # let call_site = Span::call_site();
+ /// #
+ /// let ty_span = ty.span();
+ /// let assert_sync = quote_spanned! {ty_span=>
+ /// struct _AssertSync where #ty: Sync;
+ /// };
+ /// ```
+ ///
+ /// If the assertion fails, the user will see an error like the following. The
+ /// input span of their type is highlighted in the error.
+ ///
+ /// ```text
+ /// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied
+ /// --> src/main.rs:10:21
+ /// |
+ /// 10 | static ref PTR: *const () = &();
+ /// | ^^^^^^^^^ `*const ()` cannot be shared between threads safely
+ /// ```
+ ///
+ /// In this example it is important for the where-clause to be spanned with the
+ /// line/column information of the user's input type so that error messages are
+ /// placed appropriately by the compiler.
+ $quote_spanned
+ };
+}
+
+#[cfg(doc)]
+__quote_spanned![
+ #[macro_export]
+ macro_rules! quote_spanned {
+ ($span:expr=> $($tt:tt)*) => {
+ ...
+ };
+ }
+];
+
+#[cfg(not(doc))]
+__quote_spanned![
+ #[macro_export]
+ macro_rules! quote_spanned {
+ ($span:expr=>) => {{
+ let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
+ $crate::__private::TokenStream::new()
+ }};
+
+ // Special case rule for a single tt, for performance.
+ ($span:expr=> $tt:tt) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
+ $crate::quote_token_spanned!{$tt _s _span}
+ _s
+ }};
+
+ // Special case rules for two tts, for performance.
+ ($span:expr=> # $var:ident) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
+ $crate::ToTokens::to_tokens(&$var, &mut _s);
+ _s
+ }};
+ ($span:expr=> $tt1:tt $tt2:tt) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
+ $crate::quote_token_spanned!{$tt1 _s _span}
+ $crate::quote_token_spanned!{$tt2 _s _span}
+ _s
+ }};
+
+ // Rule for any other number of tokens.
+ ($span:expr=> $($tt:tt)*) => {{
+ let mut _s = $crate::__private::TokenStream::new();
+ let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
+ $crate::quote_each_token_spanned!{_s _span $($tt)*}
+ _s
+ }};
+ }
+];
+
+// Extract the names of all #metavariables and pass them to the $call macro.
+//
+// in: pounded_var_names!(then!(...) a #b c #( #d )* #e)
+// out: then!(... b);
+// then!(... d);
+// then!(... e);
+#[macro_export]
+#[doc(hidden)]
+macro_rules! pounded_var_names {
+ ($call:ident! $extra:tt $($tts:tt)*) => {
+ $crate::pounded_var_names_with_context!{$call! $extra
+ (@ $($tts)*)
+ ($($tts)* @)
+ }
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! pounded_var_names_with_context {
+ ($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => {
+ $(
+ $crate::pounded_var_with_context!{$call! $extra $b1 $curr}
+ )*
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! pounded_var_with_context {
+ ($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => {
+ $crate::pounded_var_names!{$call! $extra $($inner)*}
+ };
+
+ ($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => {
+ $crate::pounded_var_names!{$call! $extra $($inner)*}
+ };
+
+ ($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => {
+ $crate::pounded_var_names!{$call! $extra $($inner)*}
+ };
+
+ ($call:ident!($($extra:tt)*) # $var:ident) => {
+ $crate::$call!($($extra)* $var);
+ };
+
+ ($call:ident! $extra:tt $b1:tt $curr:tt) => {};
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_bind_into_iter {
+ ($has_iter:ident $var:ident) => {
+ // `mut` may be unused if $var occurs multiple times in the list.
+ #[allow(unused_mut)]
+ let (mut $var, i) = $var.quote_into_iter();
+ let $has_iter = $has_iter | i;
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_bind_next_or_break {
+ ($var:ident) => {
+ let $var = match $var.next() {
+ Some(_x) => $crate::__private::RepInterp(_x),
+ None => break,
+ };
+ };
+}
+
+// The obvious way to write this macro is as a tt muncher. This implementation
+// does something more complex for two reasons.
+//
+// - With a tt muncher it's easy to hit Rust's built-in recursion_limit, which
+// this implementation avoids because it isn't tail recursive.
+//
+// - Compile times for a tt muncher are quadratic relative to the length of
+// the input. This implementation is linear, so it will be faster
+// (potentially much faster) for big inputs. However, the constant factors
+// of this implementation are higher than that of a tt muncher, so it is
+// somewhat slower than a tt muncher if there are many invocations with
+// short inputs.
+//
+// An invocation like this:
+//
+// quote_each_token!(_s a b c d e f g h i j);
+//
+// expands to this:
+//
+// quote_tokens_with_context!(_s
+// (@ @ @ @ @ @ a b c d e f g h i j)
+// (@ @ @ @ @ a b c d e f g h i j @)
+// (@ @ @ @ a b c d e f g h i j @ @)
+// (@ @ @ (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) @ @ @)
+// (@ @ a b c d e f g h i j @ @ @ @)
+// (@ a b c d e f g h i j @ @ @ @ @)
+// (a b c d e f g h i j @ @ @ @ @ @)
+// );
+//
+// which gets transposed and expanded to this:
+//
+// quote_token_with_context!(_s @ @ @ @ @ @ a);
+// quote_token_with_context!(_s @ @ @ @ @ a b);
+// quote_token_with_context!(_s @ @ @ @ a b c);
+// quote_token_with_context!(_s @ @ @ (a) b c d);
+// quote_token_with_context!(_s @ @ a (b) c d e);
+// quote_token_with_context!(_s @ a b (c) d e f);
+// quote_token_with_context!(_s a b c (d) e f g);
+// quote_token_with_context!(_s b c d (e) f g h);
+// quote_token_with_context!(_s c d e (f) g h i);
+// quote_token_with_context!(_s d e f (g) h i j);
+// quote_token_with_context!(_s e f g (h) i j @);
+// quote_token_with_context!(_s f g h (i) j @ @);
+// quote_token_with_context!(_s g h i (j) @ @ @);
+// quote_token_with_context!(_s h i j @ @ @ @);
+// quote_token_with_context!(_s i j @ @ @ @ @);
+// quote_token_with_context!(_s j @ @ @ @ @ @);
+//
+// Without having used muncher-style recursion, we get one invocation of
+// quote_token_with_context for each original tt, with three tts of context on
+// either side. This is enough for the longest possible interpolation form (a
+// repetition with separator, as in `# (#var) , *`) to be fully represented with
+// the first or last tt in the middle.
+//
+// The middle tt (surrounded by parentheses) is the tt being processed.
+//
+// - When it is a `#`, quote_token_with_context can do an interpolation. The
+// interpolation kind will depend on the three subsequent tts.
+//
+// - When it is within a later part of an interpolation, it can be ignored
+// because the interpolation has already been done.
+//
+// - When it is not part of an interpolation it can be pushed as a single
+// token into the output.
+//
+// - When the middle token is an unparenthesized `@`, that call is one of the
+// first 3 or last 3 calls of quote_token_with_context and does not
+// correspond to one of the original input tokens, so turns into nothing.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_each_token {
+ ($tokens:ident $($tts:tt)*) => {
+ $crate::quote_tokens_with_context!{$tokens
+ (@ @ @ @ @ @ $($tts)*)
+ (@ @ @ @ @ $($tts)* @)
+ (@ @ @ @ $($tts)* @ @)
+ (@ @ @ $(($tts))* @ @ @)
+ (@ @ $($tts)* @ @ @ @)
+ (@ $($tts)* @ @ @ @ @)
+ ($($tts)* @ @ @ @ @ @)
+ }
+ };
+}
+
+// See the explanation on quote_each_token.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_each_token_spanned {
+ ($tokens:ident $span:ident $($tts:tt)*) => {
+ $crate::quote_tokens_with_context_spanned!{$tokens $span
+ (@ @ @ @ @ @ $($tts)*)
+ (@ @ @ @ @ $($tts)* @)
+ (@ @ @ @ $($tts)* @ @)
+ (@ @ @ $(($tts))* @ @ @)
+ (@ @ $($tts)* @ @ @ @)
+ (@ $($tts)* @ @ @ @ @)
+ ($($tts)* @ @ @ @ @ @)
+ }
+ };
+}
+
+// See the explanation on quote_each_token.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_tokens_with_context {
+ ($tokens:ident
+ ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*)
+ ($($curr:tt)*)
+ ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)
+ ) => {
+ $(
+ $crate::quote_token_with_context!{$tokens $b3 $b2 $b1 $curr $a1 $a2 $a3}
+ )*
+ };
+}
+
+// See the explanation on quote_each_token.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_tokens_with_context_spanned {
+ ($tokens:ident $span:ident
+ ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*)
+ ($($curr:tt)*)
+ ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)
+ ) => {
+ $(
+ $crate::quote_token_with_context_spanned!{$tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3}
+ )*
+ };
+}
+
+// See the explanation on quote_each_token.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_token_with_context {
+ // Unparenthesized `@` indicates this call does not correspond to one of the
+ // original input tokens. Ignore it.
+ ($tokens:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {};
+
+ // A repetition with no separator.
+ ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
+ use $crate::__private::ext::*;
+ let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
+ $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
+ let _: $crate::__private::HasIterator = has_iter;
+ // This is `while true` instead of `loop` because if there are no
+ // iterators used inside of this repetition then the body would not
+ // contain any `break`, so the compiler would emit unreachable code
+ // warnings on anything below the loop. We use has_iter to detect and
+ // fail to compile when there are no iterators, so here we just work
+ // around the unneeded extra warning.
+ while true {
+ $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
+ $crate::quote_each_token!{$tokens $($inner)*}
+ }
+ }};
+ // ... and one step later.
+ ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
+ // ... and one step later.
+ ($tokens:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};
+
+ // A repetition with separator.
+ ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{
+ use $crate::__private::ext::*;
+ let mut _i = 0usize;
+ let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
+ $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
+ let _: $crate::__private::HasIterator = has_iter;
+ while true {
+ $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
+ if _i > 0 {
+ $crate::quote_token!{$sep $tokens}
+ }
+ _i += 1;
+ $crate::quote_each_token!{$tokens $($inner)*}
+ }
+ }};
+ // ... and one step later.
+ ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
+ // ... and one step later.
+ ($tokens:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};
+ // (A special case for `#(var)**`, where the first `*` is treated as the
+ // repetition symbol and the second `*` is treated as an ordinary token.)
+ ($tokens:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {
+ // https://github.com/dtolnay/quote/issues/130
+ $crate::quote_token!{* $tokens}
+ };
+ // ... and one step later.
+ ($tokens:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
+
+ // A non-repetition interpolation.
+ ($tokens:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => {
+ $crate::ToTokens::to_tokens(&$var, &mut $tokens);
+ };
+ // ... and one step later.
+ ($tokens:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {};
+
+ // An ordinary token, not part of any interpolation.
+ ($tokens:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => {
+ $crate::quote_token!{$curr $tokens}
+ };
+}
+
+// See the explanation on quote_each_token, and on the individual rules of
+// quote_token_with_context.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_token_with_context_spanned {
+ ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {};
+
+ ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
+ use $crate::__private::ext::*;
+ let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
+ $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
+ let _: $crate::__private::HasIterator = has_iter;
+ while true {
+ $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
+ $crate::quote_each_token_spanned!{$tokens $span $($inner)*}
+ }
+ }};
+ ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
+ ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};
+
+ ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{
+ use $crate::__private::ext::*;
+ let mut _i = 0usize;
+ let has_iter = $crate::__private::ThereIsNoIteratorInRepetition;
+ $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*}
+ let _: $crate::__private::HasIterator = has_iter;
+ while true {
+ $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*}
+ if _i > 0 {
+ $crate::quote_token_spanned!{$sep $tokens $span}
+ }
+ _i += 1;
+ $crate::quote_each_token_spanned!{$tokens $span $($inner)*}
+ }
+ }};
+ ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
+ ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};
+ ($tokens:ident $span:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {
+ // https://github.com/dtolnay/quote/issues/130
+ $crate::quote_token_spanned!{* $tokens $span}
+ };
+ ($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
+
+ ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => {
+ $crate::ToTokens::to_tokens(&$var, &mut $tokens);
+ };
+ ($tokens:ident $span:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {};
+
+ ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => {
+ $crate::quote_token_spanned!{$curr $tokens $span}
+ };
+}
+
+// These rules are ordered by approximate token frequency, at least for the
+// first 10 or so, to improve compile times. Having `ident` first is by far the
+// most important because it's typically 2-3x more common than the next most
+// common token.
+//
+// Separately, we put the token being matched in the very front so that failing
+// rules may fail to match as quickly as possible.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_token {
+ ($ident:ident $tokens:ident) => {
+ $crate::__private::push_ident(&mut $tokens, stringify!($ident));
+ };
+
+ (:: $tokens:ident) => {
+ $crate::__private::push_colon2(&mut $tokens);
+ };
+
+ (( $($inner:tt)* ) $tokens:ident) => {
+ $crate::__private::push_group(
+ &mut $tokens,
+ $crate::__private::Delimiter::Parenthesis,
+ $crate::quote!($($inner)*),
+ );
+ };
+
+ ([ $($inner:tt)* ] $tokens:ident) => {
+ $crate::__private::push_group(
+ &mut $tokens,
+ $crate::__private::Delimiter::Bracket,
+ $crate::quote!($($inner)*),
+ );
+ };
+
+ ({ $($inner:tt)* } $tokens:ident) => {
+ $crate::__private::push_group(
+ &mut $tokens,
+ $crate::__private::Delimiter::Brace,
+ $crate::quote!($($inner)*),
+ );
+ };
+
+ (# $tokens:ident) => {
+ $crate::__private::push_pound(&mut $tokens);
+ };
+
+ (, $tokens:ident) => {
+ $crate::__private::push_comma(&mut $tokens);
+ };
+
+ (. $tokens:ident) => {
+ $crate::__private::push_dot(&mut $tokens);
+ };
+
+ (; $tokens:ident) => {
+ $crate::__private::push_semi(&mut $tokens);
+ };
+
+ (: $tokens:ident) => {
+ $crate::__private::push_colon(&mut $tokens);
+ };
+
+ (+ $tokens:ident) => {
+ $crate::__private::push_add(&mut $tokens);
+ };
+
+ (+= $tokens:ident) => {
+ $crate::__private::push_add_eq(&mut $tokens);
+ };
+
+ (& $tokens:ident) => {
+ $crate::__private::push_and(&mut $tokens);
+ };
+
+ (&& $tokens:ident) => {
+ $crate::__private::push_and_and(&mut $tokens);
+ };
+
+ (&= $tokens:ident) => {
+ $crate::__private::push_and_eq(&mut $tokens);
+ };
+
+ (@ $tokens:ident) => {
+ $crate::__private::push_at(&mut $tokens);
+ };
+
+ (! $tokens:ident) => {
+ $crate::__private::push_bang(&mut $tokens);
+ };
+
+ (^ $tokens:ident) => {
+ $crate::__private::push_caret(&mut $tokens);
+ };
+
+ (^= $tokens:ident) => {
+ $crate::__private::push_caret_eq(&mut $tokens);
+ };
+
+ (/ $tokens:ident) => {
+ $crate::__private::push_div(&mut $tokens);
+ };
+
+ (/= $tokens:ident) => {
+ $crate::__private::push_div_eq(&mut $tokens);
+ };
+
+ (.. $tokens:ident) => {
+ $crate::__private::push_dot2(&mut $tokens);
+ };
+
+ (... $tokens:ident) => {
+ $crate::__private::push_dot3(&mut $tokens);
+ };
+
+ (..= $tokens:ident) => {
+ $crate::__private::push_dot_dot_eq(&mut $tokens);
+ };
+
+ (= $tokens:ident) => {
+ $crate::__private::push_eq(&mut $tokens);
+ };
+
+ (== $tokens:ident) => {
+ $crate::__private::push_eq_eq(&mut $tokens);
+ };
+
+ (>= $tokens:ident) => {
+ $crate::__private::push_ge(&mut $tokens);
+ };
+
+ (> $tokens:ident) => {
+ $crate::__private::push_gt(&mut $tokens);
+ };
+
+ (<= $tokens:ident) => {
+ $crate::__private::push_le(&mut $tokens);
+ };
+
+ (< $tokens:ident) => {
+ $crate::__private::push_lt(&mut $tokens);
+ };
+
+ (*= $tokens:ident) => {
+ $crate::__private::push_mul_eq(&mut $tokens);
+ };
+
+ (!= $tokens:ident) => {
+ $crate::__private::push_ne(&mut $tokens);
+ };
+
+ (| $tokens:ident) => {
+ $crate::__private::push_or(&mut $tokens);
+ };
+
+ (|= $tokens:ident) => {
+ $crate::__private::push_or_eq(&mut $tokens);
+ };
+
+ (|| $tokens:ident) => {
+ $crate::__private::push_or_or(&mut $tokens);
+ };
+
+ (? $tokens:ident) => {
+ $crate::__private::push_question(&mut $tokens);
+ };
+
+ (-> $tokens:ident) => {
+ $crate::__private::push_rarrow(&mut $tokens);
+ };
+
+ (<- $tokens:ident) => {
+ $crate::__private::push_larrow(&mut $tokens);
+ };
+
+ (% $tokens:ident) => {
+ $crate::__private::push_rem(&mut $tokens);
+ };
+
+ (%= $tokens:ident) => {
+ $crate::__private::push_rem_eq(&mut $tokens);
+ };
+
+ (=> $tokens:ident) => {
+ $crate::__private::push_fat_arrow(&mut $tokens);
+ };
+
+ (<< $tokens:ident) => {
+ $crate::__private::push_shl(&mut $tokens);
+ };
+
+ (<<= $tokens:ident) => {
+ $crate::__private::push_shl_eq(&mut $tokens);
+ };
+
+ (>> $tokens:ident) => {
+ $crate::__private::push_shr(&mut $tokens);
+ };
+
+ (>>= $tokens:ident) => {
+ $crate::__private::push_shr_eq(&mut $tokens);
+ };
+
+ (* $tokens:ident) => {
+ $crate::__private::push_star(&mut $tokens);
+ };
+
+ (- $tokens:ident) => {
+ $crate::__private::push_sub(&mut $tokens);
+ };
+
+ (-= $tokens:ident) => {
+ $crate::__private::push_sub_eq(&mut $tokens);
+ };
+
+ ($lifetime:lifetime $tokens:ident) => {
+ $crate::__private::push_lifetime(&mut $tokens, stringify!($lifetime));
+ };
+
+ (_ $tokens:ident) => {
+ $crate::__private::push_underscore(&mut $tokens);
+ };
+
+ ($other:tt $tokens:ident) => {
+ $crate::__private::parse(&mut $tokens, stringify!($other));
+ };
+}
+
+// See the comment above `quote_token!` about the rule ordering.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_token_spanned {
+ ($ident:ident $tokens:ident $span:ident) => {
+ $crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident));
+ };
+
+ (:: $tokens:ident $span:ident) => {
+ $crate::__private::push_colon2_spanned(&mut $tokens, $span);
+ };
+
+ (( $($inner:tt)* ) $tokens:ident $span:ident) => {
+ $crate::__private::push_group_spanned(
+ &mut $tokens,
+ $span,
+ $crate::__private::Delimiter::Parenthesis,
+ $crate::quote_spanned!($span=> $($inner)*),
+ );
+ };
+
+ ([ $($inner:tt)* ] $tokens:ident $span:ident) => {
+ $crate::__private::push_group_spanned(
+ &mut $tokens,
+ $span,
+ $crate::__private::Delimiter::Bracket,
+ $crate::quote_spanned!($span=> $($inner)*),
+ );
+ };
+
+ ({ $($inner:tt)* } $tokens:ident $span:ident) => {
+ $crate::__private::push_group_spanned(
+ &mut $tokens,
+ $span,
+ $crate::__private::Delimiter::Brace,
+ $crate::quote_spanned!($span=> $($inner)*),
+ );
+ };
+
+ (# $tokens:ident $span:ident) => {
+ $crate::__private::push_pound_spanned(&mut $tokens, $span);
+ };
+
+ (, $tokens:ident $span:ident) => {
+ $crate::__private::push_comma_spanned(&mut $tokens, $span);
+ };
+
+ (. $tokens:ident $span:ident) => {
+ $crate::__private::push_dot_spanned(&mut $tokens, $span);
+ };
+
+ (; $tokens:ident $span:ident) => {
+ $crate::__private::push_semi_spanned(&mut $tokens, $span);
+ };
+
+ (: $tokens:ident $span:ident) => {
+ $crate::__private::push_colon_spanned(&mut $tokens, $span);
+ };
+
+ (+ $tokens:ident $span:ident) => {
+ $crate::__private::push_add_spanned(&mut $tokens, $span);
+ };
+
+ (+= $tokens:ident $span:ident) => {
+ $crate::__private::push_add_eq_spanned(&mut $tokens, $span);
+ };
+
+ (& $tokens:ident $span:ident) => {
+ $crate::__private::push_and_spanned(&mut $tokens, $span);
+ };
+
+ (&& $tokens:ident $span:ident) => {
+ $crate::__private::push_and_and_spanned(&mut $tokens, $span);
+ };
+
+ (&= $tokens:ident $span:ident) => {
+ $crate::__private::push_and_eq_spanned(&mut $tokens, $span);
+ };
+
+ (@ $tokens:ident $span:ident) => {
+ $crate::__private::push_at_spanned(&mut $tokens, $span);
+ };
+
+ (! $tokens:ident $span:ident) => {
+ $crate::__private::push_bang_spanned(&mut $tokens, $span);
+ };
+
+ (^ $tokens:ident $span:ident) => {
+ $crate::__private::push_caret_spanned(&mut $tokens, $span);
+ };
+
+ (^= $tokens:ident $span:ident) => {
+ $crate::__private::push_caret_eq_spanned(&mut $tokens, $span);
+ };
+
+ (/ $tokens:ident $span:ident) => {
+ $crate::__private::push_div_spanned(&mut $tokens, $span);
+ };
+
+ (/= $tokens:ident $span:ident) => {
+ $crate::__private::push_div_eq_spanned(&mut $tokens, $span);
+ };
+
+ (.. $tokens:ident $span:ident) => {
+ $crate::__private::push_dot2_spanned(&mut $tokens, $span);
+ };
+
+ (... $tokens:ident $span:ident) => {
+ $crate::__private::push_dot3_spanned(&mut $tokens, $span);
+ };
+
+ (..= $tokens:ident $span:ident) => {
+ $crate::__private::push_dot_dot_eq_spanned(&mut $tokens, $span);
+ };
+
+ (= $tokens:ident $span:ident) => {
+ $crate::__private::push_eq_spanned(&mut $tokens, $span);
+ };
+
+ (== $tokens:ident $span:ident) => {
+ $crate::__private::push_eq_eq_spanned(&mut $tokens, $span);
+ };
+
+ (>= $tokens:ident $span:ident) => {
+ $crate::__private::push_ge_spanned(&mut $tokens, $span);
+ };
+
+ (> $tokens:ident $span:ident) => {
+ $crate::__private::push_gt_spanned(&mut $tokens, $span);
+ };
+
+ (<= $tokens:ident $span:ident) => {
+ $crate::__private::push_le_spanned(&mut $tokens, $span);
+ };
+
+ (< $tokens:ident $span:ident) => {
+ $crate::__private::push_lt_spanned(&mut $tokens, $span);
+ };
+
+ (*= $tokens:ident $span:ident) => {
+ $crate::__private::push_mul_eq_spanned(&mut $tokens, $span);
+ };
+
+ (!= $tokens:ident $span:ident) => {
+ $crate::__private::push_ne_spanned(&mut $tokens, $span);
+ };
+
+ (| $tokens:ident $span:ident) => {
+ $crate::__private::push_or_spanned(&mut $tokens, $span);
+ };
+
+ (|= $tokens:ident $span:ident) => {
+ $crate::__private::push_or_eq_spanned(&mut $tokens, $span);
+ };
+
+ (|| $tokens:ident $span:ident) => {
+ $crate::__private::push_or_or_spanned(&mut $tokens, $span);
+ };
+
+ (? $tokens:ident $span:ident) => {
+ $crate::__private::push_question_spanned(&mut $tokens, $span);
+ };
+
+ (-> $tokens:ident $span:ident) => {
+ $crate::__private::push_rarrow_spanned(&mut $tokens, $span);
+ };
+
+ (<- $tokens:ident $span:ident) => {
+ $crate::__private::push_larrow_spanned(&mut $tokens, $span);
+ };
+
+ (% $tokens:ident $span:ident) => {
+ $crate::__private::push_rem_spanned(&mut $tokens, $span);
+ };
+
+ (%= $tokens:ident $span:ident) => {
+ $crate::__private::push_rem_eq_spanned(&mut $tokens, $span);
+ };
+
+ (=> $tokens:ident $span:ident) => {
+ $crate::__private::push_fat_arrow_spanned(&mut $tokens, $span);
+ };
+
+ (<< $tokens:ident $span:ident) => {
+ $crate::__private::push_shl_spanned(&mut $tokens, $span);
+ };
+
+ (<<= $tokens:ident $span:ident) => {
+ $crate::__private::push_shl_eq_spanned(&mut $tokens, $span);
+ };
+
+ (>> $tokens:ident $span:ident) => {
+ $crate::__private::push_shr_spanned(&mut $tokens, $span);
+ };
+
+ (>>= $tokens:ident $span:ident) => {
+ $crate::__private::push_shr_eq_spanned(&mut $tokens, $span);
+ };
+
+ (* $tokens:ident $span:ident) => {
+ $crate::__private::push_star_spanned(&mut $tokens, $span);
+ };
+
+ (- $tokens:ident $span:ident) => {
+ $crate::__private::push_sub_spanned(&mut $tokens, $span);
+ };
+
+ (-= $tokens:ident $span:ident) => {
+ $crate::__private::push_sub_eq_spanned(&mut $tokens, $span);
+ };
+
+ ($lifetime:lifetime $tokens:ident $span:ident) => {
+ $crate::__private::push_lifetime_spanned(&mut $tokens, $span, stringify!($lifetime));
+ };
+
+ (_ $tokens:ident $span:ident) => {
+ $crate::__private::push_underscore_spanned(&mut $tokens, $span);
+ };
+
+ ($other:tt $tokens:ident $span:ident) => {
+ $crate::__private::parse_spanned(&mut $tokens, $span, stringify!($other));
+ };
+}
diff --git a/rust/hw/char/pl011/vendor/quote/src/runtime.rs b/rust/hw/char/pl011/vendor/quote/src/runtime.rs
new file mode 100644
index 0000000000..eff044a957
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/src/runtime.rs
@@ -0,0 +1,530 @@
+use self::get_span::{GetSpan, GetSpanBase, GetSpanInner};
+use crate::{IdentFragment, ToTokens, TokenStreamExt};
+use core::fmt;
+use core::iter;
+use core::ops::BitOr;
+use proc_macro2::{Group, Ident, Punct, Spacing, TokenTree};
+
+#[doc(hidden)]
+pub use alloc::format;
+#[doc(hidden)]
+pub use core::option::Option;
+
+#[doc(hidden)]
+pub type Delimiter = proc_macro2::Delimiter;
+#[doc(hidden)]
+pub type Span = proc_macro2::Span;
+#[doc(hidden)]
+pub type TokenStream = proc_macro2::TokenStream;
+
+#[doc(hidden)]
+pub struct HasIterator; // True
+#[doc(hidden)]
+pub struct ThereIsNoIteratorInRepetition; // False
+
+impl BitOr<ThereIsNoIteratorInRepetition> for ThereIsNoIteratorInRepetition {
+ type Output = ThereIsNoIteratorInRepetition;
+ fn bitor(self, _rhs: ThereIsNoIteratorInRepetition) -> ThereIsNoIteratorInRepetition {
+ ThereIsNoIteratorInRepetition
+ }
+}
+
+impl BitOr<ThereIsNoIteratorInRepetition> for HasIterator {
+ type Output = HasIterator;
+ fn bitor(self, _rhs: ThereIsNoIteratorInRepetition) -> HasIterator {
+ HasIterator
+ }
+}
+
+impl BitOr<HasIterator> for ThereIsNoIteratorInRepetition {
+ type Output = HasIterator;
+ fn bitor(self, _rhs: HasIterator) -> HasIterator {
+ HasIterator
+ }
+}
+
+impl BitOr<HasIterator> for HasIterator {
+ type Output = HasIterator;
+ fn bitor(self, _rhs: HasIterator) -> HasIterator {
+ HasIterator
+ }
+}
+
+/// Extension traits used by the implementation of `quote!`. These are defined
+/// in separate traits, rather than as a single trait due to ambiguity issues.
+///
+/// These traits expose a `quote_into_iter` method which should allow calling
+/// whichever impl happens to be applicable. Calling that method repeatedly on
+/// the returned value should be idempotent.
+#[doc(hidden)]
+pub mod ext {
+ use super::RepInterp;
+ use super::{HasIterator as HasIter, ThereIsNoIteratorInRepetition as DoesNotHaveIter};
+ use crate::ToTokens;
+ use alloc::collections::btree_set::{self, BTreeSet};
+ use core::slice;
+
+ /// Extension trait providing the `quote_into_iter` method on iterators.
+ #[doc(hidden)]
+ pub trait RepIteratorExt: Iterator + Sized {
+ fn quote_into_iter(self) -> (Self, HasIter) {
+ (self, HasIter)
+ }
+ }
+
+ impl<T: Iterator> RepIteratorExt for T {}
+
+ /// Extension trait providing the `quote_into_iter` method for
+ /// non-iterable types. These types interpolate the same value in each
+ /// iteration of the repetition.
+ #[doc(hidden)]
+ pub trait RepToTokensExt {
+ /// Pretend to be an iterator for the purposes of `quote_into_iter`.
+ /// This allows repeated calls to `quote_into_iter` to continue
+ /// correctly returning DoesNotHaveIter.
+ fn next(&self) -> Option<&Self> {
+ Some(self)
+ }
+
+ fn quote_into_iter(&self) -> (&Self, DoesNotHaveIter) {
+ (self, DoesNotHaveIter)
+ }
+ }
+
+ impl<T: ToTokens + ?Sized> RepToTokensExt for T {}
+
+ /// Extension trait providing the `quote_into_iter` method for types that
+ /// can be referenced as an iterator.
+ #[doc(hidden)]
+ pub trait RepAsIteratorExt<'q> {
+ type Iter: Iterator;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter);
+ }
+
+ impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a T {
+ type Iter = T::Iter;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ <T as RepAsIteratorExt>::quote_into_iter(*self)
+ }
+ }
+
+ impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a mut T {
+ type Iter = T::Iter;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ <T as RepAsIteratorExt>::quote_into_iter(*self)
+ }
+ }
+
+ impl<'q, T: 'q> RepAsIteratorExt<'q> for [T] {
+ type Iter = slice::Iter<'q, T>;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ (self.iter(), HasIter)
+ }
+ }
+
+ impl<'q, T: 'q> RepAsIteratorExt<'q> for Vec<T> {
+ type Iter = slice::Iter<'q, T>;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ (self.iter(), HasIter)
+ }
+ }
+
+ impl<'q, T: 'q> RepAsIteratorExt<'q> for BTreeSet<T> {
+ type Iter = btree_set::Iter<'q, T>;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ (self.iter(), HasIter)
+ }
+ }
+
+ impl<'q, T: RepAsIteratorExt<'q>> RepAsIteratorExt<'q> for RepInterp<T> {
+ type Iter = T::Iter;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ self.0.quote_into_iter()
+ }
+ }
+}
+
+// Helper type used within interpolations to allow for repeated binding names.
+// Implements the relevant traits, and exports a dummy `next()` method.
+#[derive(Copy, Clone)]
+#[doc(hidden)]
+pub struct RepInterp<T>(pub T);
+
+impl<T> RepInterp<T> {
+ // This method is intended to look like `Iterator::next`, and is called when
+ // a name is bound multiple times, as the previous binding will shadow the
+ // original `Iterator` object. This allows us to avoid advancing the
+ // iterator multiple times per iteration.
+ pub fn next(self) -> Option<T> {
+ Some(self.0)
+ }
+}
+
+impl<T: Iterator> Iterator for RepInterp<T> {
+ type Item = T::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next()
+ }
+}
+
+impl<T: ToTokens> ToTokens for RepInterp<T> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.0.to_tokens(tokens);
+ }
+}
+
+#[doc(hidden)]
+#[inline]
+pub fn get_span<T>(span: T) -> GetSpan<T> {
+ GetSpan(GetSpanInner(GetSpanBase(span)))
+}
+
+mod get_span {
+ use core::ops::Deref;
+ use proc_macro2::extra::DelimSpan;
+ use proc_macro2::Span;
+
+ pub struct GetSpan<T>(pub(crate) GetSpanInner<T>);
+
+ pub struct GetSpanInner<T>(pub(crate) GetSpanBase<T>);
+
+ pub struct GetSpanBase<T>(pub(crate) T);
+
+ impl GetSpan<Span> {
+ #[inline]
+ pub fn __into_span(self) -> Span {
+ ((self.0).0).0
+ }
+ }
+
+ impl GetSpanInner<DelimSpan> {
+ #[inline]
+ pub fn __into_span(&self) -> Span {
+ (self.0).0.join()
+ }
+ }
+
+ impl<T> GetSpanBase<T> {
+ #[allow(clippy::unused_self)]
+ pub fn __into_span(&self) -> T {
+ unreachable!()
+ }
+ }
+
+ impl<T> Deref for GetSpan<T> {
+ type Target = GetSpanInner<T>;
+
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+ }
+
+ impl<T> Deref for GetSpanInner<T> {
+ type Target = GetSpanBase<T>;
+
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+ }
+}
+
+#[doc(hidden)]
+pub fn push_group(tokens: &mut TokenStream, delimiter: Delimiter, inner: TokenStream) {
+ tokens.append(Group::new(delimiter, inner));
+}
+
+#[doc(hidden)]
+pub fn push_group_spanned(
+ tokens: &mut TokenStream,
+ span: Span,
+ delimiter: Delimiter,
+ inner: TokenStream,
+) {
+ let mut g = Group::new(delimiter, inner);
+ g.set_span(span);
+ tokens.append(g);
+}
+
+#[doc(hidden)]
+pub fn parse(tokens: &mut TokenStream, s: &str) {
+ let s: TokenStream = s.parse().expect("invalid token stream");
+ tokens.extend(iter::once(s));
+}
+
+#[doc(hidden)]
+pub fn parse_spanned(tokens: &mut TokenStream, span: Span, s: &str) {
+ let s: TokenStream = s.parse().expect("invalid token stream");
+ tokens.extend(s.into_iter().map(|t| respan_token_tree(t, span)));
+}
+
+// Token tree with every span replaced by the given one.
+fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree {
+ match &mut token {
+ TokenTree::Group(g) => {
+ let stream = g
+ .stream()
+ .into_iter()
+ .map(|token| respan_token_tree(token, span))
+ .collect();
+ *g = Group::new(g.delimiter(), stream);
+ g.set_span(span);
+ }
+ other => other.set_span(span),
+ }
+ token
+}
+
+#[doc(hidden)]
+pub fn push_ident(tokens: &mut TokenStream, s: &str) {
+ let span = Span::call_site();
+ push_ident_spanned(tokens, span, s);
+}
+
+#[doc(hidden)]
+pub fn push_ident_spanned(tokens: &mut TokenStream, span: Span, s: &str) {
+ tokens.append(ident_maybe_raw(s, span));
+}
+
+#[doc(hidden)]
+pub fn push_lifetime(tokens: &mut TokenStream, lifetime: &str) {
+ struct Lifetime<'a> {
+ name: &'a str,
+ state: u8,
+ }
+
+ impl<'a> Iterator for Lifetime<'a> {
+ type Item = TokenTree;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.state {
+ 0 => {
+ self.state = 1;
+ Some(TokenTree::Punct(Punct::new('\'', Spacing::Joint)))
+ }
+ 1 => {
+ self.state = 2;
+ Some(TokenTree::Ident(Ident::new(self.name, Span::call_site())))
+ }
+ _ => None,
+ }
+ }
+ }
+
+ tokens.extend(Lifetime {
+ name: &lifetime[1..],
+ state: 0,
+ });
+}
+
+#[doc(hidden)]
+pub fn push_lifetime_spanned(tokens: &mut TokenStream, span: Span, lifetime: &str) {
+ struct Lifetime<'a> {
+ name: &'a str,
+ span: Span,
+ state: u8,
+ }
+
+ impl<'a> Iterator for Lifetime<'a> {
+ type Item = TokenTree;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ match self.state {
+ 0 => {
+ self.state = 1;
+ let mut apostrophe = Punct::new('\'', Spacing::Joint);
+ apostrophe.set_span(self.span);
+ Some(TokenTree::Punct(apostrophe))
+ }
+ 1 => {
+ self.state = 2;
+ Some(TokenTree::Ident(Ident::new(self.name, self.span)))
+ }
+ _ => None,
+ }
+ }
+ }
+
+ tokens.extend(Lifetime {
+ name: &lifetime[1..],
+ span,
+ state: 0,
+ });
+}
+
+macro_rules! push_punct {
+ ($name:ident $spanned:ident $char1:tt) => {
+ #[doc(hidden)]
+ pub fn $name(tokens: &mut TokenStream) {
+ tokens.append(Punct::new($char1, Spacing::Alone));
+ }
+ #[doc(hidden)]
+ pub fn $spanned(tokens: &mut TokenStream, span: Span) {
+ let mut punct = Punct::new($char1, Spacing::Alone);
+ punct.set_span(span);
+ tokens.append(punct);
+ }
+ };
+ ($name:ident $spanned:ident $char1:tt $char2:tt) => {
+ #[doc(hidden)]
+ pub fn $name(tokens: &mut TokenStream) {
+ tokens.append(Punct::new($char1, Spacing::Joint));
+ tokens.append(Punct::new($char2, Spacing::Alone));
+ }
+ #[doc(hidden)]
+ pub fn $spanned(tokens: &mut TokenStream, span: Span) {
+ let mut punct = Punct::new($char1, Spacing::Joint);
+ punct.set_span(span);
+ tokens.append(punct);
+ let mut punct = Punct::new($char2, Spacing::Alone);
+ punct.set_span(span);
+ tokens.append(punct);
+ }
+ };
+ ($name:ident $spanned:ident $char1:tt $char2:tt $char3:tt) => {
+ #[doc(hidden)]
+ pub fn $name(tokens: &mut TokenStream) {
+ tokens.append(Punct::new($char1, Spacing::Joint));
+ tokens.append(Punct::new($char2, Spacing::Joint));
+ tokens.append(Punct::new($char3, Spacing::Alone));
+ }
+ #[doc(hidden)]
+ pub fn $spanned(tokens: &mut TokenStream, span: Span) {
+ let mut punct = Punct::new($char1, Spacing::Joint);
+ punct.set_span(span);
+ tokens.append(punct);
+ let mut punct = Punct::new($char2, Spacing::Joint);
+ punct.set_span(span);
+ tokens.append(punct);
+ let mut punct = Punct::new($char3, Spacing::Alone);
+ punct.set_span(span);
+ tokens.append(punct);
+ }
+ };
+}
+
+push_punct!(push_add push_add_spanned '+');
+push_punct!(push_add_eq push_add_eq_spanned '+' '=');
+push_punct!(push_and push_and_spanned '&');
+push_punct!(push_and_and push_and_and_spanned '&' '&');
+push_punct!(push_and_eq push_and_eq_spanned '&' '=');
+push_punct!(push_at push_at_spanned '@');
+push_punct!(push_bang push_bang_spanned '!');
+push_punct!(push_caret push_caret_spanned '^');
+push_punct!(push_caret_eq push_caret_eq_spanned '^' '=');
+push_punct!(push_colon push_colon_spanned ':');
+push_punct!(push_colon2 push_colon2_spanned ':' ':');
+push_punct!(push_comma push_comma_spanned ',');
+push_punct!(push_div push_div_spanned '/');
+push_punct!(push_div_eq push_div_eq_spanned '/' '=');
+push_punct!(push_dot push_dot_spanned '.');
+push_punct!(push_dot2 push_dot2_spanned '.' '.');
+push_punct!(push_dot3 push_dot3_spanned '.' '.' '.');
+push_punct!(push_dot_dot_eq push_dot_dot_eq_spanned '.' '.' '=');
+push_punct!(push_eq push_eq_spanned '=');
+push_punct!(push_eq_eq push_eq_eq_spanned '=' '=');
+push_punct!(push_ge push_ge_spanned '>' '=');
+push_punct!(push_gt push_gt_spanned '>');
+push_punct!(push_le push_le_spanned '<' '=');
+push_punct!(push_lt push_lt_spanned '<');
+push_punct!(push_mul_eq push_mul_eq_spanned '*' '=');
+push_punct!(push_ne push_ne_spanned '!' '=');
+push_punct!(push_or push_or_spanned '|');
+push_punct!(push_or_eq push_or_eq_spanned '|' '=');
+push_punct!(push_or_or push_or_or_spanned '|' '|');
+push_punct!(push_pound push_pound_spanned '#');
+push_punct!(push_question push_question_spanned '?');
+push_punct!(push_rarrow push_rarrow_spanned '-' '>');
+push_punct!(push_larrow push_larrow_spanned '<' '-');
+push_punct!(push_rem push_rem_spanned '%');
+push_punct!(push_rem_eq push_rem_eq_spanned '%' '=');
+push_punct!(push_fat_arrow push_fat_arrow_spanned '=' '>');
+push_punct!(push_semi push_semi_spanned ';');
+push_punct!(push_shl push_shl_spanned '<' '<');
+push_punct!(push_shl_eq push_shl_eq_spanned '<' '<' '=');
+push_punct!(push_shr push_shr_spanned '>' '>');
+push_punct!(push_shr_eq push_shr_eq_spanned '>' '>' '=');
+push_punct!(push_star push_star_spanned '*');
+push_punct!(push_sub push_sub_spanned '-');
+push_punct!(push_sub_eq push_sub_eq_spanned '-' '=');
+
+#[doc(hidden)]
+pub fn push_underscore(tokens: &mut TokenStream) {
+ push_underscore_spanned(tokens, Span::call_site());
+}
+
+#[doc(hidden)]
+pub fn push_underscore_spanned(tokens: &mut TokenStream, span: Span) {
+ tokens.append(Ident::new("_", span));
+}
+
+// Helper method for constructing identifiers from the `format_ident!` macro,
+// handling `r#` prefixes.
+#[doc(hidden)]
+pub fn mk_ident(id: &str, span: Option<Span>) -> Ident {
+ let span = span.unwrap_or_else(Span::call_site);
+ ident_maybe_raw(id, span)
+}
+
+fn ident_maybe_raw(id: &str, span: Span) -> Ident {
+ if let Some(id) = id.strip_prefix("r#") {
+ Ident::new_raw(id, span)
+ } else {
+ Ident::new(id, span)
+ }
+}
+
+// Adapts from `IdentFragment` to `fmt::Display` for use by the `format_ident!`
+// macro, and exposes span information from these fragments.
+//
+// This struct also has forwarding implementations of the formatting traits
+// `Octal`, `LowerHex`, `UpperHex`, and `Binary` to allow for their use within
+// `format_ident!`.
+#[derive(Copy, Clone)]
+#[doc(hidden)]
+pub struct IdentFragmentAdapter<T: IdentFragment>(pub T);
+
+impl<T: IdentFragment> IdentFragmentAdapter<T> {
+ pub fn span(&self) -> Option<Span> {
+ self.0.span()
+ }
+}
+
+impl<T: IdentFragment> fmt::Display for IdentFragmentAdapter<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ IdentFragment::fmt(&self.0, f)
+ }
+}
+
+impl<T: IdentFragment + fmt::Octal> fmt::Octal for IdentFragmentAdapter<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Octal::fmt(&self.0, f)
+ }
+}
+
+impl<T: IdentFragment + fmt::LowerHex> fmt::LowerHex for IdentFragmentAdapter<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::LowerHex::fmt(&self.0, f)
+ }
+}
+
+impl<T: IdentFragment + fmt::UpperHex> fmt::UpperHex for IdentFragmentAdapter<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::UpperHex::fmt(&self.0, f)
+ }
+}
+
+impl<T: IdentFragment + fmt::Binary> fmt::Binary for IdentFragmentAdapter<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Binary::fmt(&self.0, f)
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/quote/src/spanned.rs b/rust/hw/char/pl011/vendor/quote/src/spanned.rs
new file mode 100644
index 0000000000..6eba64445d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/src/spanned.rs
@@ -0,0 +1,50 @@
+use crate::ToTokens;
+use proc_macro2::extra::DelimSpan;
+use proc_macro2::{Span, TokenStream};
+
+// Not public API other than via the syn crate. Use syn::spanned::Spanned.
+pub trait Spanned: private::Sealed {
+ fn __span(&self) -> Span;
+}
+
+impl Spanned for Span {
+ fn __span(&self) -> Span {
+ *self
+ }
+}
+
+impl Spanned for DelimSpan {
+ fn __span(&self) -> Span {
+ self.join()
+ }
+}
+
+impl<T: ?Sized + ToTokens> Spanned for T {
+ fn __span(&self) -> Span {
+ join_spans(self.into_token_stream())
+ }
+}
+
+fn join_spans(tokens: TokenStream) -> Span {
+ let mut iter = tokens.into_iter().map(|tt| tt.span());
+
+ let first = match iter.next() {
+ Some(span) => span,
+ None => return Span::call_site(),
+ };
+
+ iter.fold(None, |_prev, next| Some(next))
+ .and_then(|last| first.join(last))
+ .unwrap_or(first)
+}
+
+mod private {
+ use crate::ToTokens;
+ use proc_macro2::extra::DelimSpan;
+ use proc_macro2::Span;
+
+ pub trait Sealed {}
+ impl Sealed for Span {}
+ impl Sealed for DelimSpan {}
+ impl<T: ?Sized + ToTokens> Sealed for T {}
+}
diff --git a/rust/hw/char/pl011/vendor/quote/src/to_tokens.rs b/rust/hw/char/pl011/vendor/quote/src/to_tokens.rs
new file mode 100644
index 0000000000..23b6ec2c08
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/src/to_tokens.rs
@@ -0,0 +1,209 @@
+use super::TokenStreamExt;
+use alloc::borrow::Cow;
+use alloc::rc::Rc;
+use core::iter;
+use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
+
+/// Types that can be interpolated inside a `quote!` invocation.
+///
+/// [`quote!`]: macro.quote.html
+pub trait ToTokens {
+ /// Write `self` to the given `TokenStream`.
+ ///
+ /// The token append methods provided by the [`TokenStreamExt`] extension
+ /// trait may be useful for implementing `ToTokens`.
+ ///
+ /// [`TokenStreamExt`]: trait.TokenStreamExt.html
+ ///
+ /// # Example
+ ///
+ /// Example implementation for a struct representing Rust paths like
+ /// `std::cmp::PartialEq`:
+ ///
+ /// ```
+ /// use proc_macro2::{TokenTree, Spacing, Span, Punct, TokenStream};
+ /// use quote::{TokenStreamExt, ToTokens};
+ ///
+ /// pub struct Path {
+ /// pub global: bool,
+ /// pub segments: Vec<PathSegment>,
+ /// }
+ ///
+ /// impl ToTokens for Path {
+ /// fn to_tokens(&self, tokens: &mut TokenStream) {
+ /// for (i, segment) in self.segments.iter().enumerate() {
+ /// if i > 0 || self.global {
+ /// // Double colon `::`
+ /// tokens.append(Punct::new(':', Spacing::Joint));
+ /// tokens.append(Punct::new(':', Spacing::Alone));
+ /// }
+ /// segment.to_tokens(tokens);
+ /// }
+ /// }
+ /// }
+ /// #
+ /// # pub struct PathSegment;
+ /// #
+ /// # impl ToTokens for PathSegment {
+ /// # fn to_tokens(&self, tokens: &mut TokenStream) {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// ```
+ fn to_tokens(&self, tokens: &mut TokenStream);
+
+ /// Convert `self` directly into a `TokenStream` object.
+ ///
+ /// This method is implicitly implemented using `to_tokens`, and acts as a
+ /// convenience method for consumers of the `ToTokens` trait.
+ fn to_token_stream(&self) -> TokenStream {
+ let mut tokens = TokenStream::new();
+ self.to_tokens(&mut tokens);
+ tokens
+ }
+
+ /// Convert `self` directly into a `TokenStream` object.
+ ///
+ /// This method is implicitly implemented using `to_tokens`, and acts as a
+ /// convenience method for consumers of the `ToTokens` trait.
+ fn into_token_stream(self) -> TokenStream
+ where
+ Self: Sized,
+ {
+ self.to_token_stream()
+ }
+}
+
+impl<'a, T: ?Sized + ToTokens> ToTokens for &'a T {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens);
+ }
+}
+
+impl<'a, T: ?Sized + ToTokens> ToTokens for &'a mut T {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens);
+ }
+}
+
+impl<'a, T: ?Sized + ToOwned + ToTokens> ToTokens for Cow<'a, T> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens);
+ }
+}
+
+impl<T: ?Sized + ToTokens> ToTokens for Box<T> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens);
+ }
+}
+
+impl<T: ?Sized + ToTokens> ToTokens for Rc<T> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens);
+ }
+}
+
+impl<T: ToTokens> ToTokens for Option<T> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ if let Some(ref t) = *self {
+ t.to_tokens(tokens);
+ }
+ }
+}
+
+impl ToTokens for str {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(Literal::string(self));
+ }
+}
+
+impl ToTokens for String {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.as_str().to_tokens(tokens);
+ }
+}
+
+macro_rules! primitive {
+ ($($t:ident => $name:ident)*) => {
+ $(
+ impl ToTokens for $t {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(Literal::$name(*self));
+ }
+ }
+ )*
+ };
+}
+
+primitive! {
+ i8 => i8_suffixed
+ i16 => i16_suffixed
+ i32 => i32_suffixed
+ i64 => i64_suffixed
+ i128 => i128_suffixed
+ isize => isize_suffixed
+
+ u8 => u8_suffixed
+ u16 => u16_suffixed
+ u32 => u32_suffixed
+ u64 => u64_suffixed
+ u128 => u128_suffixed
+ usize => usize_suffixed
+
+ f32 => f32_suffixed
+ f64 => f64_suffixed
+}
+
+impl ToTokens for char {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(Literal::character(*self));
+ }
+}
+
+impl ToTokens for bool {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let word = if *self { "true" } else { "false" };
+ tokens.append(Ident::new(word, Span::call_site()));
+ }
+}
+
+impl ToTokens for Group {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(self.clone());
+ }
+}
+
+impl ToTokens for Ident {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(self.clone());
+ }
+}
+
+impl ToTokens for Punct {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(self.clone());
+ }
+}
+
+impl ToTokens for Literal {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(self.clone());
+ }
+}
+
+impl ToTokens for TokenTree {
+ fn to_tokens(&self, dst: &mut TokenStream) {
+ dst.append(self.clone());
+ }
+}
+
+impl ToTokens for TokenStream {
+ fn to_tokens(&self, dst: &mut TokenStream) {
+ dst.extend(iter::once(self.clone()));
+ }
+
+ fn into_token_stream(self) -> TokenStream {
+ self
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/quote/tests/compiletest.rs b/rust/hw/char/pl011/vendor/quote/tests/compiletest.rs
new file mode 100644
index 0000000000..7974a6249e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/compiletest.rs
@@ -0,0 +1,7 @@
+#[rustversion::attr(not(nightly), ignore)]
+#[cfg_attr(miri, ignore)]
+#[test]
+fn ui() {
+ let t = trybuild::TestCases::new();
+ t.compile_fail("tests/ui/*.rs");
+}
diff --git a/rust/hw/char/pl011/vendor/quote/tests/test.rs b/rust/hw/char/pl011/vendor/quote/tests/test.rs
new file mode 100644
index 0000000000..eab4f55aa8
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/test.rs
@@ -0,0 +1,549 @@
+#![allow(
+ clippy::disallowed_names,
+ clippy::let_underscore_untyped,
+ clippy::shadow_unrelated,
+ clippy::unseparated_literal_suffix,
+ clippy::used_underscore_binding
+)]
+
+extern crate proc_macro;
+
+use std::borrow::Cow;
+use std::collections::BTreeSet;
+
+use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream};
+use quote::{format_ident, quote, quote_spanned, TokenStreamExt};
+
+struct X;
+
+impl quote::ToTokens for X {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(Ident::new("X", Span::call_site()));
+ }
+}
+
+#[test]
+fn test_quote_impl() {
+ let tokens = quote! {
+ impl<'a, T: ToTokens> ToTokens for &'a T {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens)
+ }
+ }
+ };
+
+ let expected = concat!(
+ "impl < 'a , T : ToTokens > ToTokens for & 'a T { ",
+ "fn to_tokens (& self , tokens : & mut TokenStream) { ",
+ "(* * self) . to_tokens (tokens) ",
+ "} ",
+ "}"
+ );
+
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_quote_spanned_impl() {
+ let span = Span::call_site();
+ let tokens = quote_spanned! {span=>
+ impl<'a, T: ToTokens> ToTokens for &'a T {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens)
+ }
+ }
+ };
+
+ let expected = concat!(
+ "impl < 'a , T : ToTokens > ToTokens for & 'a T { ",
+ "fn to_tokens (& self , tokens : & mut TokenStream) { ",
+ "(* * self) . to_tokens (tokens) ",
+ "} ",
+ "}"
+ );
+
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_substitution() {
+ let x = X;
+ let tokens = quote!(#x <#x> (#x) [#x] {#x});
+
+ let expected = "X < X > (X) [X] { X }";
+
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_iter() {
+ let primes = &[X, X, X, X];
+
+ assert_eq!("X X X X", quote!(#(#primes)*).to_string());
+
+ assert_eq!("X , X , X , X ,", quote!(#(#primes,)*).to_string());
+
+ assert_eq!("X , X , X , X", quote!(#(#primes),*).to_string());
+}
+
+#[test]
+fn test_array() {
+ let array: [u8; 40] = [0; 40];
+ let _ = quote!(#(#array #array)*);
+
+ let ref_array: &[u8; 40] = &[0; 40];
+ let _ = quote!(#(#ref_array #ref_array)*);
+
+ let ref_slice: &[u8] = &[0; 40];
+ let _ = quote!(#(#ref_slice #ref_slice)*);
+
+ let array: [X; 2] = [X, X]; // !Copy
+ let _ = quote!(#(#array #array)*);
+
+ let ref_array: &[X; 2] = &[X, X];
+ let _ = quote!(#(#ref_array #ref_array)*);
+
+ let ref_slice: &[X] = &[X, X];
+ let _ = quote!(#(#ref_slice #ref_slice)*);
+}
+
+#[test]
+fn test_advanced() {
+ let generics = quote!( <'a, T> );
+
+ let where_clause = quote!( where T: Serialize );
+
+ let field_ty = quote!(String);
+
+ let item_ty = quote!(Cow<'a, str>);
+
+ let path = quote!(SomeTrait::serialize_with);
+
+ let value = quote!(self.x);
+
+ let tokens = quote! {
+ struct SerializeWith #generics #where_clause {
+ value: &'a #field_ty,
+ phantom: ::std::marker::PhantomData<#item_ty>,
+ }
+
+ impl #generics ::serde::Serialize for SerializeWith #generics #where_clause {
+ fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
+ where S: ::serde::Serializer
+ {
+ #path(self.value, s)
+ }
+ }
+
+ SerializeWith {
+ value: #value,
+ phantom: ::std::marker::PhantomData::<#item_ty>,
+ }
+ };
+
+ let expected = concat!(
+ "struct SerializeWith < 'a , T > where T : Serialize { ",
+ "value : & 'a String , ",
+ "phantom : :: std :: marker :: PhantomData < Cow < 'a , str > > , ",
+ "} ",
+ "impl < 'a , T > :: serde :: Serialize for SerializeWith < 'a , T > where T : Serialize { ",
+ "fn serialize < S > (& self , s : & mut S) -> Result < () , S :: Error > ",
+ "where S : :: serde :: Serializer ",
+ "{ ",
+ "SomeTrait :: serialize_with (self . value , s) ",
+ "} ",
+ "} ",
+ "SerializeWith { ",
+ "value : self . x , ",
+ "phantom : :: std :: marker :: PhantomData :: < Cow < 'a , str > > , ",
+ "}"
+ );
+
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_integer() {
+ let ii8 = -1i8;
+ let ii16 = -1i16;
+ let ii32 = -1i32;
+ let ii64 = -1i64;
+ let ii128 = -1i128;
+ let iisize = -1isize;
+ let uu8 = 1u8;
+ let uu16 = 1u16;
+ let uu32 = 1u32;
+ let uu64 = 1u64;
+ let uu128 = 1u128;
+ let uusize = 1usize;
+
+ let tokens = quote! {
+ 1 1i32 1u256
+ #ii8 #ii16 #ii32 #ii64 #ii128 #iisize
+ #uu8 #uu16 #uu32 #uu64 #uu128 #uusize
+ };
+ let expected =
+ "1 1i32 1u256 - 1i8 - 1i16 - 1i32 - 1i64 - 1i128 - 1isize 1u8 1u16 1u32 1u64 1u128 1usize";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_floating() {
+ let e32 = 2.345f32;
+
+ let e64 = 2.345f64;
+
+ let tokens = quote! {
+ #e32
+ #e64
+ };
+ let expected = concat!("2.345f32 2.345f64");
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_char() {
+ let zero = '\u{1}';
+ let pound = '#';
+ let quote = '"';
+ let apost = '\'';
+ let newline = '\n';
+ let heart = '\u{2764}';
+
+ let tokens = quote! {
+ #zero #pound #quote #apost #newline #heart
+ };
+ let expected = "'\\u{1}' '#' '\"' '\\'' '\\n' '\u{2764}'";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_str() {
+ let s = "\u{1} a 'b \" c";
+ let tokens = quote!(#s);
+ let expected = "\"\\u{1} a 'b \\\" c\"";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_string() {
+ let s = "\u{1} a 'b \" c".to_string();
+ let tokens = quote!(#s);
+ let expected = "\"\\u{1} a 'b \\\" c\"";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_interpolated_literal() {
+ macro_rules! m {
+ ($literal:literal) => {
+ quote!($literal)
+ };
+ }
+
+ let tokens = m!(1);
+ let expected = "1";
+ assert_eq!(expected, tokens.to_string());
+
+ let tokens = m!(-1);
+ let expected = "- 1";
+ assert_eq!(expected, tokens.to_string());
+
+ let tokens = m!(true);
+ let expected = "true";
+ assert_eq!(expected, tokens.to_string());
+
+ let tokens = m!(-true);
+ let expected = "- true";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_ident() {
+ let foo = Ident::new("Foo", Span::call_site());
+ let bar = Ident::new(&format!("Bar{}", 7), Span::call_site());
+ let tokens = quote!(struct #foo; enum #bar {});
+ let expected = "struct Foo ; enum Bar7 { }";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_underscore() {
+ let tokens = quote!(let _;);
+ let expected = "let _ ;";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_duplicate() {
+ let ch = 'x';
+
+ let tokens = quote!(#ch #ch);
+
+ let expected = "'x' 'x'";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_fancy_repetition() {
+ let foo = vec!["a", "b"];
+ let bar = vec![true, false];
+
+ let tokens = quote! {
+ #(#foo: #bar),*
+ };
+
+ let expected = r#""a" : true , "b" : false"#;
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_nested_fancy_repetition() {
+ let nested = vec![vec!['a', 'b', 'c'], vec!['x', 'y', 'z']];
+
+ let tokens = quote! {
+ #(
+ #(#nested)*
+ ),*
+ };
+
+ let expected = "'a' 'b' 'c' , 'x' 'y' 'z'";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_duplicate_name_repetition() {
+ let foo = &["a", "b"];
+
+ let tokens = quote! {
+ #(#foo: #foo),*
+ #(#foo: #foo),*
+ };
+
+ let expected = r#""a" : "a" , "b" : "b" "a" : "a" , "b" : "b""#;
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_duplicate_name_repetition_no_copy() {
+ let foo = vec!["a".to_owned(), "b".to_owned()];
+
+ let tokens = quote! {
+ #(#foo: #foo),*
+ };
+
+ let expected = r#""a" : "a" , "b" : "b""#;
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_btreeset_repetition() {
+ let mut set = BTreeSet::new();
+ set.insert("a".to_owned());
+ set.insert("b".to_owned());
+
+ let tokens = quote! {
+ #(#set: #set),*
+ };
+
+ let expected = r#""a" : "a" , "b" : "b""#;
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_variable_name_conflict() {
+ // The implementation of `#(...),*` uses the variable `_i` but it should be
+ // fine, if a little confusing when debugging.
+ let _i = vec!['a', 'b'];
+ let tokens = quote! { #(#_i),* };
+ let expected = "'a' , 'b'";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_nonrep_in_repetition() {
+ let rep = vec!["a", "b"];
+ let nonrep = "c";
+
+ let tokens = quote! {
+ #(#rep #rep : #nonrep #nonrep),*
+ };
+
+ let expected = r#""a" "a" : "c" "c" , "b" "b" : "c" "c""#;
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_empty_quote() {
+ let tokens = quote!();
+ assert_eq!("", tokens.to_string());
+}
+
+#[test]
+fn test_box_str() {
+ let b = "str".to_owned().into_boxed_str();
+ let tokens = quote! { #b };
+ assert_eq!("\"str\"", tokens.to_string());
+}
+
+#[test]
+fn test_cow() {
+ let owned: Cow<Ident> = Cow::Owned(Ident::new("owned", Span::call_site()));
+
+ let ident = Ident::new("borrowed", Span::call_site());
+ let borrowed = Cow::Borrowed(&ident);
+
+ let tokens = quote! { #owned #borrowed };
+ assert_eq!("owned borrowed", tokens.to_string());
+}
+
+#[test]
+fn test_closure() {
+ fn field_i(i: usize) -> Ident {
+ format_ident!("__field{}", i)
+ }
+
+ let fields = (0usize..3)
+ .map(field_i as fn(_) -> _)
+ .map(|var| quote! { #var });
+
+ let tokens = quote! { #(#fields)* };
+ assert_eq!("__field0 __field1 __field2", tokens.to_string());
+}
+
+#[test]
+fn test_append_tokens() {
+ let mut a = quote!(a);
+ let b = quote!(b);
+ a.append_all(b);
+ assert_eq!("a b", a.to_string());
+}
+
+#[test]
+fn test_format_ident() {
+ let id0 = format_ident!("Aa");
+ let id1 = format_ident!("Hello{x}", x = id0);
+ let id2 = format_ident!("Hello{x}", x = 5usize);
+ let id3 = format_ident!("Hello{}_{x}", id0, x = 10usize);
+ let id4 = format_ident!("Aa", span = Span::call_site());
+ let id5 = format_ident!("Hello{}", Cow::Borrowed("World"));
+
+ assert_eq!(id0, "Aa");
+ assert_eq!(id1, "HelloAa");
+ assert_eq!(id2, "Hello5");
+ assert_eq!(id3, "HelloAa_10");
+ assert_eq!(id4, "Aa");
+ assert_eq!(id5, "HelloWorld");
+}
+
+#[test]
+fn test_format_ident_strip_raw() {
+ let id = format_ident!("r#struct");
+ let my_id = format_ident!("MyId{}", id);
+ let raw_my_id = format_ident!("r#MyId{}", id);
+
+ assert_eq!(id, "r#struct");
+ assert_eq!(my_id, "MyIdstruct");
+ assert_eq!(raw_my_id, "r#MyIdstruct");
+}
+
+#[test]
+fn test_outer_line_comment() {
+ let tokens = quote! {
+ /// doc
+ };
+ let expected = "# [doc = r\" doc\"]";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_inner_line_comment() {
+ let tokens = quote! {
+ //! doc
+ };
+ let expected = "# ! [doc = r\" doc\"]";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_outer_block_comment() {
+ let tokens = quote! {
+ /** doc */
+ };
+ let expected = "# [doc = r\" doc \"]";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_inner_block_comment() {
+ let tokens = quote! {
+ /*! doc */
+ };
+ let expected = "# ! [doc = r\" doc \"]";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_outer_attr() {
+ let tokens = quote! {
+ #[inline]
+ };
+ let expected = "# [inline]";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_inner_attr() {
+ let tokens = quote! {
+ #![no_std]
+ };
+ let expected = "# ! [no_std]";
+ assert_eq!(expected, tokens.to_string());
+}
+
+// https://github.com/dtolnay/quote/issues/130
+#[test]
+fn test_star_after_repetition() {
+ let c = vec!['0', '1'];
+ let tokens = quote! {
+ #(
+ f(#c);
+ )*
+ *out = None;
+ };
+ let expected = "f ('0') ; f ('1') ; * out = None ;";
+ assert_eq!(expected, tokens.to_string());
+}
+
+#[test]
+fn test_quote_raw_id() {
+ let id = quote!(r#raw_id);
+ assert_eq!(id.to_string(), "r#raw_id");
+}
+
+#[test]
+fn test_type_inference_for_span() {
+ trait CallSite {
+ fn get() -> Self;
+ }
+
+ impl CallSite for Span {
+ fn get() -> Self {
+ Span::call_site()
+ }
+ }
+
+ let span = Span::call_site();
+ let _ = quote_spanned!(span=> ...);
+
+ let delim_span = Group::new(Delimiter::Parenthesis, TokenStream::new()).delim_span();
+ let _ = quote_spanned!(delim_span=> ...);
+
+ let inferred = CallSite::get();
+ let _ = quote_spanned!(inferred=> ...);
+
+ if false {
+ let proc_macro_span = proc_macro::Span::call_site();
+ let _ = quote_spanned!(proc_macro_span.into()=> ...);
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs
new file mode 100644
index 0000000000..0a39f41507
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs
@@ -0,0 +1,9 @@
+use quote::quote;
+
+fn main() {
+ let nonrep = "";
+
+ // Without some protection against repetitions with no iterator somewhere
+ // inside, this would loop infinitely.
+ quote!(#(#nonrep #nonrep)*);
+}
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
new file mode 100644
index 0000000000..99c20a5676
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+ --> tests/ui/does-not-have-iter-interpolated-dup.rs:8:5
+ |
+8 | quote!(#(#nonrep #nonrep)*);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected `HasIterator`, found `ThereIsNoIteratorInRepetition`
+ | expected due to this
+ | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition`
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs
new file mode 100644
index 0000000000..2c740cc083
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs
@@ -0,0 +1,9 @@
+use quote::quote;
+
+fn main() {
+ let nonrep = "";
+
+ // Without some protection against repetitions with no iterator somewhere
+ // inside, this would loop infinitely.
+ quote!(#(#nonrep)*);
+}
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr
new file mode 100644
index 0000000000..ef908131ba
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+ --> tests/ui/does-not-have-iter-interpolated.rs:8:5
+ |
+8 | quote!(#(#nonrep)*);
+ | ^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected `HasIterator`, found `ThereIsNoIteratorInRepetition`
+ | expected due to this
+ | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition`
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.rs b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.rs
new file mode 100644
index 0000000000..c027243dda
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.rs
@@ -0,0 +1,5 @@
+use quote::quote;
+
+fn main() {
+ quote!(#(a b),*);
+}
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.stderr b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.stderr
new file mode 100644
index 0000000000..7c6e30f2b8
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> tests/ui/does-not-have-iter-separated.rs:4:5
+ |
+4 | quote!(#(a b),*);
+ | ^^^^^^^^^^^^^^^^
+ | |
+ | expected `HasIterator`, found `ThereIsNoIteratorInRepetition`
+ | expected due to this
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.rs b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.rs
new file mode 100644
index 0000000000..8908353b57
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.rs
@@ -0,0 +1,5 @@
+use quote::quote;
+
+fn main() {
+ quote!(#(a b)*);
+}
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.stderr b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.stderr
new file mode 100644
index 0000000000..0b13e5cb78
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> tests/ui/does-not-have-iter.rs:4:5
+ |
+4 | quote!(#(a b)*);
+ | ^^^^^^^^^^^^^^^
+ | |
+ | expected `HasIterator`, found `ThereIsNoIteratorInRepetition`
+ | expected due to this
+ |
+ = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.rs b/rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.rs
new file mode 100644
index 0000000000..f991c1883d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.rs
@@ -0,0 +1,7 @@
+use quote::quote;
+use std::net::Ipv4Addr;
+
+fn main() {
+ let ip = Ipv4Addr::LOCALHOST;
+ let _ = quote! { #ip };
+}
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.stderr b/rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.stderr
new file mode 100644
index 0000000000..7bd20707e7
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.stderr
@@ -0,0 +1,20 @@
+error[E0277]: the trait bound `Ipv4Addr: ToTokens` is not satisfied
+ --> tests/ui/not-quotable.rs:6:13
+ |
+6 | let _ = quote! { #ip };
+ | ^^^^^^^^^^^^^^
+ | |
+ | the trait `ToTokens` is not implemented for `Ipv4Addr`
+ | required by a bound introduced by this call
+ |
+ = help: the following other types implement trait `ToTokens`:
+ &'a T
+ &'a mut T
+ Box<T>
+ Cow<'a, T>
+ Option<T>
+ Rc<T>
+ RepInterp<T>
+ String
+ and $N others
+ = note: this error originates in the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.rs b/rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.rs
new file mode 100644
index 0000000000..a8f0fe773c
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.rs
@@ -0,0 +1,8 @@
+use quote::quote;
+
+struct Ipv4Addr;
+
+fn main() {
+ let ip = Ipv4Addr;
+ let _ = quote! { #(#ip)* };
+}
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.stderr b/rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.stderr
new file mode 100644
index 0000000000..26932bbf67
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.stderr
@@ -0,0 +1,34 @@
+error[E0599]: the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied
+ --> tests/ui/not-repeatable.rs:7:13
+ |
+3 | struct Ipv4Addr;
+ | --------------- method `quote_into_iter` not found for this struct because it doesn't satisfy `Ipv4Addr: Iterator`, `Ipv4Addr: ToTokens`, `Ipv4Addr: ext::RepIteratorExt` or `Ipv4Addr: ext::RepToTokensExt`
+...
+7 | let _ = quote! { #(#ip)* };
+ | ^^^^^^^^^^^^^^^^^^ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds
+ |
+ = note: the following trait bounds were not satisfied:
+ `Ipv4Addr: Iterator`
+ which is required by `Ipv4Addr: ext::RepIteratorExt`
+ `&Ipv4Addr: Iterator`
+ which is required by `&Ipv4Addr: ext::RepIteratorExt`
+ `Ipv4Addr: ToTokens`
+ which is required by `Ipv4Addr: ext::RepToTokensExt`
+ `&mut Ipv4Addr: Iterator`
+ which is required by `&mut Ipv4Addr: ext::RepIteratorExt`
+note: the traits `Iterator` and `ToTokens` must be implemented
+ --> src/to_tokens.rs
+ |
+ | pub trait ToTokens {
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ ::: $RUST/core/src/iter/traits/iterator.rs
+ |
+ | pub trait Iterator {
+ | ^^^^^^^^^^^^^^^^^^
+ = help: items from traits can only be used if the trait is implemented and in scope
+ = note: the following traits define an item `quote_into_iter`, perhaps you need to implement one of them:
+ candidate #1: `ext::RepAsIteratorExt`
+ candidate #2: `ext::RepIteratorExt`
+ candidate #3: `ext::RepToTokensExt`
+ = note: this error originates in the macro `$crate::quote_bind_into_iter` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.rs b/rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.rs
new file mode 100644
index 0000000000..d5601c8a06
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.rs
@@ -0,0 +1,7 @@
+use quote::quote_spanned;
+
+fn main() {
+ let span = "";
+ let x = 0i32;
+ quote_spanned!(span=> #x);
+}
diff --git a/rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.stderr b/rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.stderr
new file mode 100644
index 0000000000..12ad307703
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.stderr
@@ -0,0 +1,10 @@
+error[E0308]: mismatched types
+ --> tests/ui/wrong-type-span.rs:6:5
+ |
+6 | quote_spanned!(span=> #x);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | expected `Span`, found `&str`
+ | expected due to this
+ |
+ = note: this error originates in the macro `quote_spanned` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/rust/hw/char/pl011/vendor/syn/.cargo-checksum.json b/rust/hw/char/pl011/vendor/syn/.cargo-checksum.json
new file mode 100644
index 0000000000..abc9f4cabd
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"9ed91391aa48c48ccc7b52a0f196ee2e5d3b4905cc390d682dc3517957d2ff40","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"684c75ce029ed7c4ad57cb12fcecfee86d521699c3332c6c4c57af98f6e3b276","benches/file.rs":"0a0527c78d849148cbb6118b4d36f72da7d4add865ba1a410e0a1be9e8dbfe0e","benches/rust.rs":"77342ecd278686080c6390e84d70ecb4a31cc696d45dc4b8ddcc5ca65a25bcfb","src/attr.rs":"bd959c93f997d5d77ec08a5f580d1d38a391978b916b5bbe82bad4c03e694563","src/bigint.rs":"0299829b2f7a1a798fe2f7bc1680e4a10f9b6f4a852d09af4da2deab466c4242","src/buffer.rs":"8f05a11b2c6fcfca3c52a70695de982b0afba7d41d4c0d4ca4192589179ca626","src/classify.rs":"192835587f4585d84abdcc76ee00892f2dd39da6c16911aca073e24b44bddc35","src/custom_keyword.rs":"322114e36ae43a2f8605506fb4568efdbc2986853e2fee74bd10a4ca0fb60c69","src/custom_punctuation.rs":"2ae2339c29b1aff3ab16157d51a3a07bfca594aa38586981534fe07a62cdd9d1","src/data.rs":"7ad7f3c55d9f0b2ff223f3f30602ffa82013c0e7366006b0a9a01193de753db0","src/derive.rs":"f54f8cf9386a2d45186ff3c86ade5dae59e0e337b0198532449190ae8520cff8","src/discouraged.rs":"c246e96f7b25cc0af11944766e1ce176be8c396447bb696769b73c4d9bb5cfcf","src/drops.rs":"013385f1dd95663f1afab41abc1e2eea04181998644828935ca564c74d6462ae","src/error.rs":"3b03fd75eee8b0bb646eaf20f7e287345bdc7515ad5286024a2dd1e53c1e7bf2","src/export.rs":"b260cc49da1da3489e7755832bc8015cfad79e84f6c74e237f65ae25a2385e56","src/expr.rs":"35cc7d3ba13bad9355756d3903d8156c8fec8e203ff016e5ff0a8acb252b9dd5","src/ext.rs":"ed143b029af286e62ceb4310286a4ce894792dd588465face042b4199b39d329","src/file.rs":"39d4ed9c56a7dc0d83259843732c434cd187248a4cde3dba4a98c3b92df6d08f","src/fixup.rs":"ec3f84bb2e09a00d460399ee009c582ce468d294c7a7c930f7677571b5bc985e","src/gen/clone.rs":"36491f5f9e9cad6c4eb354b3331ec2b672607bb26429eba6379d1e9a4919170f","src/gen/debug.rs":"c9b2547663ed9025ba614fb1a70810df1b25f471ebb57abb01de5ab8e4fa8bf0","src/gen/eq.rs":"b5fffca0c3b6c31b3fcc80a7bd8fec65baed982a4e2fb4c8862db6059ab7dea1","src/gen/fold.rs":"345e6a6d9a7d2d09e09cd5857fc903af4202df42f0759a3da118556e98829fd2","src/gen/hash.rs":"447e840245178d0777b4e143b54c356b88962456e80282dcaad1763093709c13","src/gen/visit.rs":"178a6841d7d1974bff8c8c2f9a18e9b77384956841861a50828252bcaef67c18","src/gen/visit_mut.rs":"2a8f9a1c0259060f3fa1d6cab8a1924c1b07d713561aa9562cde8e79a39e66d5","src/generics.rs":"53ba17d13f89d316387c7debb302f703f99d5038921a7272a6d25e6f8bec42ec","src/group.rs":"911dd046f5a043d1c984b1b0b893addd152a9065457908fa4515722e96663d79","src/ident.rs":"d6061030fadae9c7dc847e1ee46178d9657d782aad108c7197e8cafe765b3eaa","src/item.rs":"81e2f57843cf2f8df82e314da940a6dda9bfa54e0641dbabe3ca2a7a68c9c5a8","src/lib.rs":"3a3e7d3d191d4411c9cf98e31a5efb562bab63facba27d12f54fc333a1ecd158","src/lifetime.rs":"5787d5a5dc7e5332b03283a25ae0a9e826464242ca2d149b1a19e7cae9cee34d","src/lit.rs":"205bb729cdf82ce0ec727304878132da0290b3042d41f4ccf0dbb7250fe91c51","src/lookahead.rs":"289dbd9048a74d75e5c3fa66045e72805ff8a2d3cf7aab685b6d7e136faba248","src/mac.rs":"cd85132ab4d302333f771be7a9b40f9281781ae9bcaee0607e0a25547352baaa","src/macros.rs":"e0587f60d510fd0079c60521f6898b61da5857664bd8b450154f83c85c4403c5","src/meta.rs":"969d8ccbdbc6ea2e4928a21831b791c57447b231e1373149e4c63b46f3951801","src/op.rs":"a61757370f802e44efa3c4a1057ae2cd26e64e273f7d76c06d5ffb49602319e2","src/parse.rs":"2b5d032212425a220e910ca5ebe3eb84ee9e2892e25d4b5a34ae7e9384e5ff2a","src/parse_macro_input.rs":"e4e22b63d0496d06a4ca17742a22467ed93f08a739081324773828bad63175ee","src/parse_quote.rs":"50bfd45f176d10562cb5f4e53af9034b8e1506081bf6cb5f507ce42d24d81d7d","src/pat.rs":"e552911a1712508c672eca35abdf9f81bad3a960f21522eddbc411a6a7070445","src/path.rs":"d77045e5dad382056d67fe31a42bc45b6a02ce044c43287bd38a95e32fd6aead","src/precedence.rs":"abd13523c4e72c555d68e734d11b779ba16e33a214cf00bf9a993d3abff34638","src/print.rs":"22910bf0521ab868ebd7c62601c55912d12cfb400c65723e08e5cfa3a2d111c0","src/punctuated.rs":"19f762231c8ea46b1610fc2a293329c85f0ce82f1819f1607e71634634d43212","src/restriction.rs":"eabb012634ef67aa3c3849c905ab549189461df7fefde2a4b90161c8685f31b2","src/sealed.rs":"6ece3b3dcb30f6bb98b93d83759ca7712ee8592bef9c0511141039c38765db0e","src/span.rs":"0a48e375e5c9768f6f64174a91ba6a255f4b021e2fb3548d8494e617f142601b","src/spanned.rs":"4b9bd65f60ab81922adfd0be8f03b6d50e98da3a5f525f242f9639aec4beac79","src/stmt.rs":"bb4cd196ce23c3fc07fefa47e67a0cd815db4f02ce1192625379d60bd657ffd2","src/thread.rs":"1f1deb1272525ab2af9a36aac4bce8f65b0e315adb1656641fd7075662f49222","src/token.rs":"25df9f6a305c1be58eb4f2454b6ab35c6bef703bf4954fcfed2108b27723cb16","src/tt.rs":"a58303a95d08d6bf3f3e09715b9b70a57b91b54774cfc1f00f2848034d2ff5c7","src/ty.rs":"90af4ce1911c91bdfd9ae431def641640daeb0c788c39a2ef024926485e7b2b2","src/verbatim.rs":"87cbe82a90f48efb57ffd09141042698b3e011a21d0d5412154d80324b0a5ef0","src/whitespace.rs":"9cdcbfe9045b259046329a795bc1105ab5a871471a6d3f7318d275ee53f7a825","tests/common/eq.rs":"1a754d31cd6acd15cd17d7cc8e6afe918f2a11334fe6fc46c92ab887a470d838","tests/common/mod.rs":"64fb893bc0e7148395fd9ce1f67432b3d8406be29cbd664e2b73585da5ee5719","tests/common/parse.rs":"fff650bb98a9382beefbd22d2a89c0c8f90501dd6d58abc4d12b29cb4f647dc7","tests/debug/gen.rs":"3ca161a049fe72ff73ead99fbfe78335fdb2ac7c41085fe8cd0c9a0b29995151","tests/debug/mod.rs":"b56136586267ae1812a937b69215dd053ada2c21717771d89dcd3ce52bcb27f5","tests/macros/mod.rs":"64b0da858096e7cf0f772e66bc1787a867e45897d7677de580c0a1f35c0f6852","tests/regression.rs":"e9565ea0efecb4136f099164ffcfa26e1996b0a27fb9c6659e90ad9bdd42e7b6","tests/regression/issue1108.rs":"f32db35244a674e22ff824ca9e5bbec2184e287b59f022db68c418b5878a2edc","tests/regression/issue1235.rs":"a2266b10c3f7c7af5734817ab0a3e8b309b51e7d177b63f26e67e6b744d280b0","tests/repo/mod.rs":"a463bc4786fa211005ef93bf2257d89c8ccd0be621275d9689396a53cb9bf425","tests/repo/progress.rs":"c08d0314a7f3ecf760d471f27da3cd2a500aeb9f1c8331bffb2aa648f9fabf3f","tests/test_asyncness.rs":"8982f6bc4e36510f924e288247473403e72697389ce9dda4e4b5ab0a8e49259f","tests/test_attribute.rs":"b35550a43bbd187bb330997ba36f90c65d8fc489135b1d32ef4547f145cb7612","tests/test_derive_input.rs":"99c4e6e45e3322ea9e269b309059c8a00fda1dcc03aed41f6e7d8c7e0a72fa2b","tests/test_expr.rs":"59843a1534d5a84fd302a815523eef9d5177f7323b8be48e75f2d9d970950751","tests/test_generics.rs":"2fcc8575d695b568f3724b3b33d853b8fa6d9864eb816b5e3ca82420682e6155","tests/test_grouping.rs":"1bd63c8ca0b90bd493fb3f927079ab9ddf74d2a78da82db2f638e652d22305d5","tests/test_ident.rs":"d5850e817720e774cd397a46dbc5298c57933823c18e20805e84503fc9387e8f","tests/test_item.rs":"1b8412a5581adf93eaa215785a592f139af8511c954dee283d52dff2718a6cc2","tests/test_iterators.rs":"f4dacb5f3a8e0473dfb0d27f05270d41e79eddb4759b1fad3e88e379b4731e17","tests/test_lit.rs":"01b0acfe03cff16e7c1a45ceb7f4b637e5cbc6145840886ba981b7ed8e83691c","tests/test_meta.rs":"4ae570333f849ed8edec5dd957111a2deb721ede360f1e1ffeeab75380578ad4","tests/test_parse_buffer.rs":"0de6af13ba0345986b18d495063f9b75a1018e8569c34b277f9522c63a6c0941","tests/test_parse_quote.rs":"928176da6ebb449ef01a798f3352c9b181d3077c1266eb008df73876f4013c47","tests/test_parse_stream.rs":"b6b533432173123d6d01d8d2cb33714bc50b30b16ffbb6116f93937221ad4594","tests/test_pat.rs":"f6954a50e62a97ac2bc1ba0cb7a5a1fc53b7b01fb55ffe0176bee3fe1955d460","tests/test_path.rs":"d54350aa91508f8d301f5be3e3a34e03b0615b1a04e8fbbab9840da20161838b","tests/test_precedence.rs":"62484c9a04778b506c183b06cae5f0c460a581e3c3b6baf4ff2cff0827698c3f","tests/test_receiver.rs":"af64117acd66fbf42edc476f731ecd20c88009d9cb641dbd7a1d6384ae99ae73","tests/test_round_trip.rs":"c9aae3a76ee801b9fb7ce2f2732aa9e1bf1b8f43f317ec1bfd0f8e5765c4e39c","tests/test_shebang.rs":"98e8a6690c04e0aad2893b747593620b51836fe704f50f5c6fe352609837138a","tests/test_size.rs":"57c83ebf1a4d4fb910b4db16566c611b08428271da30a278fab749b2f2177459","tests/test_stmt.rs":"bbc305ea888254798b6faf285187d8bc7a955e4402d9a497d4b9d361e0436691","tests/test_token_trees.rs":"d012da9c3c861073711b006bf6ffdc073821fb9fb0a08733628cdae57124d1f5","tests/test_ty.rs":"49fbb880891d4c2e21350e35b914d92aa9a056fbaad9c4afa5242802848fe9c4","tests/test_visibility.rs":"7bd239aef6f6d8173462dbd869064f3fdb9ba71644ac1f62c5d2fbb2568fb986","tests/zzz_stable.rs":"2a862e59cb446235ed99aec0e6ada8e16d3ecc30229b29d825b7c0bbc2602989"},"package":"c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/syn/Cargo.toml b/rust/hw/char/pl011/vendor/syn/Cargo.toml
new file mode 100644
index 0000000000..1d42e2745f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/Cargo.toml
@@ -0,0 +1,260 @@
+# 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.60"
+name = "syn"
+version = "2.0.66"
+authors = ["David Tolnay <dtolnay@gmail.com>"]
+build = false
+include = [
+ "/benches/**",
+ "/Cargo.toml",
+ "/LICENSE-APACHE",
+ "/LICENSE-MIT",
+ "/README.md",
+ "/src/**",
+ "/tests/**",
+]
+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
+rustdoc-args = ["--generate-link-to-definition"]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[package.metadata.playground]
+features = [
+ "full",
+ "visit",
+ "visit-mut",
+ "fold",
+ "extra-traits",
+]
+
+[lib]
+name = "syn"
+path = "src/lib.rs"
+doc-scrape-examples = false
+
+[[test]]
+name = "test_meta"
+path = "tests/test_meta.rs"
+
+[[test]]
+name = "test_stmt"
+path = "tests/test_stmt.rs"
+
+[[test]]
+name = "test_receiver"
+path = "tests/test_receiver.rs"
+
+[[test]]
+name = "regression"
+path = "tests/regression.rs"
+
+[[test]]
+name = "test_generics"
+path = "tests/test_generics.rs"
+
+[[test]]
+name = "test_grouping"
+path = "tests/test_grouping.rs"
+
+[[test]]
+name = "test_parse_stream"
+path = "tests/test_parse_stream.rs"
+
+[[test]]
+name = "test_round_trip"
+path = "tests/test_round_trip.rs"
+
+[[test]]
+name = "test_derive_input"
+path = "tests/test_derive_input.rs"
+
+[[test]]
+name = "test_visibility"
+path = "tests/test_visibility.rs"
+
+[[test]]
+name = "test_pat"
+path = "tests/test_pat.rs"
+
+[[test]]
+name = "zzz_stable"
+path = "tests/zzz_stable.rs"
+
+[[test]]
+name = "test_item"
+path = "tests/test_item.rs"
+
+[[test]]
+name = "test_iterators"
+path = "tests/test_iterators.rs"
+
+[[test]]
+name = "test_path"
+path = "tests/test_path.rs"
+
+[[test]]
+name = "test_lit"
+path = "tests/test_lit.rs"
+
+[[test]]
+name = "test_ident"
+path = "tests/test_ident.rs"
+
+[[test]]
+name = "test_parse_quote"
+path = "tests/test_parse_quote.rs"
+
+[[test]]
+name = "test_size"
+path = "tests/test_size.rs"
+
+[[test]]
+name = "test_ty"
+path = "tests/test_ty.rs"
+
+[[test]]
+name = "test_shebang"
+path = "tests/test_shebang.rs"
+
+[[test]]
+name = "test_attribute"
+path = "tests/test_attribute.rs"
+
+[[test]]
+name = "test_asyncness"
+path = "tests/test_asyncness.rs"
+
+[[test]]
+name = "test_expr"
+path = "tests/test_expr.rs"
+
+[[test]]
+name = "test_token_trees"
+path = "tests/test_token_trees.rs"
+
+[[test]]
+name = "test_parse_buffer"
+path = "tests/test_parse_buffer.rs"
+
+[[test]]
+name = "test_precedence"
+path = "tests/test_precedence.rs"
+
+[[bench]]
+name = "rust"
+path = "benches/rust.rs"
+harness = false
+required-features = [
+ "full",
+ "parsing",
+]
+
+[[bench]]
+name = "file"
+path = "benches/file.rs"
+required-features = [
+ "full",
+ "parsing",
+]
+
+[dependencies.proc-macro2]
+version = "1.0.83"
+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.flate2]
+version = "1"
+
+[dev-dependencies.insta]
+version = "1"
+
+[dev-dependencies.rayon]
+version = "1"
+
+[dev-dependencies.ref-cast]
+version = "1"
+
+[dev-dependencies.reqwest]
+version = "0.12"
+features = ["blocking"]
+
+[dev-dependencies.rustversion]
+version = "1"
+
+[dev-dependencies.syn-test-suite]
+version = "0"
+
+[dev-dependencies.tar]
+version = "0.4.16"
+
+[dev-dependencies.termcolor]
+version = "1"
+
+[dev-dependencies.walkdir]
+version = "2.3.2"
+
+[features]
+clone-impls = []
+default = [
+ "derive",
+ "parsing",
+ "printing",
+ "clone-impls",
+ "proc-macro",
+]
+derive = []
+extra-traits = []
+fold = []
+full = []
+parsing = []
+printing = ["dep:quote"]
+proc-macro = [
+ "proc-macro2/proc-macro",
+ "quote?/proc-macro",
+]
+test = ["syn-test-suite/all-features"]
+visit = []
+visit-mut = []
diff --git a/rust/hw/char/pl011/vendor/syn/LICENSE-APACHE b/rust/hw/char/pl011/vendor/syn/LICENSE-APACHE
new file mode 100644
index 0000000000..1b5ec8b78e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/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/rust/hw/char/pl011/vendor/syn/LICENSE-MIT b/rust/hw/char/pl011/vendor/syn/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/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/rust/hw/char/pl011/vendor/syn/README.md b/rust/hw/char/pl011/vendor/syn/README.md
new file mode 100644
index 0000000000..04f9bf6cb1
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/README.md
@@ -0,0 +1,284 @@
+Parser for Rust source code
+===========================
+
+[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/syn-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/syn)
+[<img alt="crates.io" src="https://img.shields.io/crates/v/syn.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/syn)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-syn-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/syn)
+[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/syn/ci.yml?branch=master&style=for-the-badge" height="20">](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 complete syntax tree that can represent
+ any valid Rust source code. 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<T>`. 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/2.0/syn/struct.File.html
+[`syn::Item`]: https://docs.rs/syn/2.0/syn/enum.Item.html
+[`syn::Expr`]: https://docs.rs/syn/2.0/syn/enum.Expr.html
+[`syn::Type`]: https://docs.rs/syn/2.0/syn/enum.Type.html
+[`syn::DeriveInput`]: https://docs.rs/syn/2.0/syn/struct.DeriveInput.html
+[parser functions]: https://docs.rs/syn/2.0/syn/parse/index.html
+
+*Version requirement: Syn supports rustc 1.60 and up.*
+
+[*Release notes*](https://github.com/dtolnay/syn/releases)
+
+<br>
+
+## 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
+
+<br>
+
+## 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
+[dependencies]
+syn = "2.0"
+quote = "1.0"
+
+[lib]
+proc-macro = true
+```
+
+```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<T>,
+ b: u8,
+ c: &'a str,
+ d: String,
+}
+```
+
+<br>
+
+## 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 `std::thread::Thread: HeapSize` is not satisfied
+ --> src/main.rs:7:5
+ |
+7 | bad: std::thread::Thread,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `std::thread::Thread`
+```
+
+<br>
+
+## 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();
+ | ^^^
+```
+
+<br>
+
+## 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
+
+<br>
+
+## Debugging
+
+When developing a procedural macro it can be helpful to look at what the
+generated code looks like. Use `cargo rustc -- -Zunstable-options
+--pretty=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/
+
+<br>
+
+## 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.
+
+<br>
+
+## 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/
+
+<br>
+
+#### License
+
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
+
+<br>
+
+<sub>
+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.
+</sub>
diff --git a/rust/hw/char/pl011/vendor/syn/benches/file.rs b/rust/hw/char/pl011/vendor/syn/benches/file.rs
new file mode 100644
index 0000000000..b424723966
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/benches/file.rs
@@ -0,0 +1,57 @@
+// $ cargo bench --features full,test --bench file
+
+#![feature(rustc_private, test)]
+#![recursion_limit = "1024"]
+#![allow(
+ clippy::items_after_statements,
+ clippy::manual_let_else,
+ clippy::match_like_matches_macro,
+ clippy::missing_panics_doc,
+ clippy::must_use_candidate,
+ 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::<syn::File>(tokens.clone()));
+}
diff --git a/rust/hw/char/pl011/vendor/syn/benches/rust.rs b/rust/hw/char/pl011/vendor/syn/benches/rust.rs
new file mode 100644
index 0000000000..bfa3a17f4a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/benches/rust.rs
@@ -0,0 +1,182 @@
+// $ 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::let_underscore_untyped,
+ clippy::manual_let_else,
+ clippy::match_like_matches_macro,
+ 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::time::{Duration, Instant};
+
+#[cfg(not(syn_only))]
+mod tokenstream_parse {
+ use proc_macro2::TokenStream;
+ use std::str::FromStr;
+
+ pub fn bench(content: &str) -> Result<(), ()> {
+ TokenStream::from_str(content).map(drop).map_err(drop)
+ }
+}
+
+mod syn_parse {
+ pub fn bench(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 rustc_data_structures::sync::Lrc;
+ use rustc_error_messages::FluentBundle;
+ use rustc_errors::{emitter::Emitter, translation::Translate, DiagCtxt, DiagInner};
+ use rustc_session::parse::ParseSess;
+ use rustc_span::source_map::{FilePathMapping, SourceMap};
+ use rustc_span::{edition::Edition, FileName};
+
+ pub fn bench(content: &str) -> Result<(), ()> {
+ struct SilentEmitter;
+
+ impl Emitter for SilentEmitter {
+ fn emit_diagnostic(&mut self, _diag: DiagInner) {}
+ fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+ None
+ }
+ }
+
+ impl Translate for SilentEmitter {
+ fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
+ None
+ }
+ fn fallback_fluent_bundle(&self) -> &FluentBundle {
+ panic!("silent emitter attempted to translate a diagnostic");
+ }
+ }
+
+ rustc_span::create_session_if_not_set_then(Edition::Edition2018, |_| {
+ let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+ let emitter = Box::new(SilentEmitter);
+ let handler = DiagCtxt::new(emitter);
+ let sess = ParseSess::with_dcx(handler, source_map);
+ if let Err(diagnostic) = rustc_parse::parse_crate_from_source_str(
+ FileName::Custom("bench".to_owned()),
+ content.to_owned(),
+ &sess,
+ ) {
+ diagnostic.cancel();
+ return Err(());
+ };
+ Ok(())
+ })
+ }
+}
+
+#[cfg(not(syn_only))]
+mod read_from_disk {
+ pub fn bench(content: &str) -> Result<(), ()> {
+ let _ = content;
+ Ok(())
+ }
+}
+
+fn exec(mut codepath: impl FnMut(&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(&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(&str) -> Result<(), ()>),
+ )*
+ ]
+ };
+ }
+
+ #[cfg(not(syn_only))]
+ {
+ let mut lines = 0;
+ let mut files = 0;
+ exec(|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/rust/hw/char/pl011/vendor/syn/meson.build b/rust/hw/char/pl011/vendor/syn/meson.build
new file mode 100644
index 0000000000..87b9628671
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/meson.build
@@ -0,0 +1,24 @@
+_syn_rs = static_library(
+ 'syn',
+ files('src/lib.rs'),
+ gnu_symbol_visibility: 'hidden',
+ rust_abi: 'rust',
+ rust_args: rust_args + [
+ '--edition', '2021',
+ '--cfg', 'feature="full"',
+ '--cfg', 'feature="derive"',
+ '--cfg', 'feature="parsing"',
+ '--cfg', 'feature="printing"',
+ '--cfg', 'feature="clone-impls"',
+ '--cfg', 'feature="proc-macro"',
+ ],
+ dependencies: [
+ dep_quote,
+ dep_proc_macro2,
+ dep_unicode_ident,
+ ],
+)
+
+dep_syn = declare_dependency(
+ link_with: _syn_rs,
+)
diff --git a/rust/hw/char/pl011/vendor/syn/src/attr.rs b/rust/hw/char/pl011/vendor/syn/src/attr.rs
new file mode 100644
index 0000000000..c19715cb3b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/attr.rs
@@ -0,0 +1,793 @@
+#[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;
+use proc_macro2::TokenStream;
+#[cfg(feature = "printing")]
+use std::iter;
+#[cfg(feature = "printing")]
+use std::slice;
+
+ast_struct! {
+ /// An attribute, like `#[repr(transparent)]`.
+ ///
+ /// <br>
+ ///
+ /// # 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
+ /// ```
+ ///
+ /// <br>
+ ///
+ /// # 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<Attribute>,
+ /// struct_token: Token![struct],
+ /// name: Ident,
+ /// semi_token: Token![;],
+ /// }
+ ///
+ /// impl Parse for UnitStruct {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// Ok(UnitStruct {
+ /// attrs: input.call(Attribute::parse_outer)?,
+ /// struct_token: input.parse()?,
+ /// name: input.parse()?,
+ /// semi_token: input.parse()?,
+ /// })
+ /// }
+ /// }
+ /// ```
+ ///
+ /// <p><br></p>
+ ///
+ /// # 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
+ ///
+ /// <p><br></p>
+ ///
+ /// # 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::<T>(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<T: Parse>(&self) -> Result<T> {
+ 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<F: Parser>(&self, parser: F) -> Result<F::Output> {
+ 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::<usize>;
+ /// let mut repr_packed = None::<usize>;
+ /// 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::<usize>;
+ /// let mut repr_packed = None::<usize>;
+ /// for attr in &input.attrs {
+ /// if attr.path().is_ident("repr") {
+ /// let nested = attr.parse_args_with(Punctuated::<Meta, Token![,]>::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<Vec<Self>> {
+ 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<Vec<Self>> {
+ 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_of_structs! {
+ /// 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<T: Parse>(&self) -> Result<T> {
+ 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<F: Parser>(&self, parser: F) -> Result<F::Output> {
+ 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<Item = &'a Attribute>;
+
+ 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<slice::Iter<'a, Attribute>, 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)
+ }
+}
+
+#[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 std::fmt::{self, Display};
+
+ pub(crate) fn parse_inner(input: ParseStream, attrs: &mut Vec<Attribute>) -> 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<Attribute> {
+ 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<Attribute> {
+ 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<Self> {
+ let path = input.call(Path::parse_mod_style)?;
+ parse_meta_after_path(path, input)
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for MetaList {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let path = input.call(Path::parse_mod_style)?;
+ parse_meta_list_after_path(path, input)
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for MetaNameValue {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let path = input.call(Path::parse_mod_style)?;
+ parse_meta_name_value_after_path(path, input)
+ }
+ }
+
+ pub(crate) fn parse_meta_after_path(path: Path, input: ParseStream) -> Result<Meta> {
+ 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![=]) {
+ 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<MetaList> {
+ let (delimiter, tokens) = mac::parse_delimiter(input)?;
+ Ok(MetaList {
+ path,
+ delimiter,
+ tokens,
+ })
+ }
+
+ fn parse_meta_name_value_after_path(path: Path, input: ParseStream) -> Result<MetaNameValue> {
+ let eq_token: Token![=] = input.parse()?;
+ let ahead = input.fork();
+ let lit: Option<Lit> = 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, MetaList, MetaNameValue};
+ 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 MetaList {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.path.to_tokens(tokens);
+ 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) {
+ self.path.to_tokens(tokens);
+ self.eq_token.to_tokens(tokens);
+ self.value.to_tokens(tokens);
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/bigint.rs b/rust/hw/char/pl011/vendor/syn/src/bigint.rs
new file mode 100644
index 0000000000..66aaa93725
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/bigint.rs
@@ -0,0 +1,66 @@
+use std::ops::{AddAssign, MulAssign};
+
+// For implementing base10_digits() accessor on LitInt.
+pub(crate) struct BigInt {
+ digits: Vec<u8>,
+}
+
+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<u8> 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<u8> 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/rust/hw/char/pl011/vendor/syn/src/buffer.rs b/rust/hw/char/pl011/vendor/syn/src/buffer.rs
new file mode 100644
index 0000000000..1686e28209
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/buffer.rs
@@ -0,0 +1,434 @@
+//! 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::Lifetime;
+use proc_macro2::extra::DelimSpan;
+use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
+use std::cmp::Ordering;
+use std::marker::PhantomData;
+
+/// 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.
+ End(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<Entry>, 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)); // we replace this below
+ Self::recursive_new(entries, group.stream());
+ let group_end_index = entries.len();
+ entries.push(Entry::End(-(group_end_index as isize)));
+ let group_end_offset = group_end_index - group_start_index;
+ entries[group_start_index] = Entry::Group(group, group_end_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)));
+ 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));
+
+ 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 == 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.offset(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.
+ self.ptr == self.scope
+ }
+
+ /// 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
+ }
+
+ pub(crate) 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
+ }
+
+ /// 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,
+ }
+ }
+
+ /// 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,
+ }
+ }
+
+ /// 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,
+ }
+ }
+
+ /// Copies all remaining tokens visible from this cursor into a
+ /// `TokenStream`.
+ pub fn token_stream(self) -> TokenStream {
+ let mut tts = Vec::new();
+ let mut cursor = self;
+ while let Some((tt, rest)) = cursor.token_tree() {
+ tts.push(tt);
+ cursor = rest;
+ }
+ tts.into_iter().collect()
+ }
+
+ /// 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(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(_) => 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.
+ #[cfg(any(feature = "full", feature = "derive"))]
+ pub(crate) fn prev_span(mut self) -> Span {
+ if start_of_buffer(self) < self.ptr {
+ self.ptr = unsafe { self.ptr.offset(-1) };
+ if let Entry::End(_) = self.entry() {
+ // Locate the matching Group begin token.
+ let mut depth = 1;
+ loop {
+ self.ptr = unsafe { self.ptr.offset(-1) };
+ match self.entry() {
+ Entry::Group(group, _) => {
+ depth -= 1;
+ if depth == 0 {
+ return group.span();
+ }
+ }
+ Entry::End(_) => depth += 1,
+ Entry::Literal(_) | Entry::Ident(_) | Entry::Punct(_) => {}
+ }
+ }
+ }
+ }
+ 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<Cursor<'a>> {
+ 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) })
+ }
+}
+
+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 {
+ self.ptr == other.ptr
+ }
+}
+
+impl<'a> PartialOrd for Cursor<'a> {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if same_buffer(*self, *other) {
+ Some(cmp_assuming_same_buffer(*self, *other))
+ } else {
+ None
+ }
+ }
+}
+
+pub(crate) fn same_scope(a: Cursor, b: Cursor) -> bool {
+ a.scope == b.scope
+}
+
+pub(crate) fn same_buffer(a: Cursor, b: Cursor) -> bool {
+ 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(),
+ }
+}
+
+pub(crate) fn close_span_of_group(cursor: Cursor) -> Span {
+ match cursor.entry() {
+ Entry::Group(group, _) => group.span_close(),
+ _ => cursor.span(),
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/classify.rs b/rust/hw/char/pl011/vendor/syn/src/classify.rs
new file mode 100644
index 0000000000..1b0ff30040
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/classify.rs
@@ -0,0 +1,377 @@
+use crate::expr::Expr;
+use crate::generics::TypeParamBound;
+use crate::path::{Path, PathArguments};
+use crate::punctuated::Punctuated;
+use crate::ty::{ReturnType, Type};
+#[cfg(feature = "full")]
+use proc_macro2::{Delimiter, TokenStream, TokenTree};
+use std::ops::ControlFlow;
+
+#[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::Reference(_)
+ | Expr::Repeat(_)
+ | Expr::Return(_)
+ | Expr::Struct(_)
+ | Expr::Try(_)
+ | Expr::Tuple(_)
+ | Expr::Unary(_)
+ | Expr::Yield(_)
+ | Expr::Verbatim(_) => true
+ }
+}
+
+#[cfg(all(feature = "printing", feature = "full"))]
+pub(crate) fn confusable_with_adjacent_block(mut expr: &Expr) -> bool {
+ let mut stack = Vec::new();
+
+ while let Some(next) = match expr {
+ Expr::Assign(e) => {
+ stack.push(&e.right);
+ Some(&e.left)
+ }
+ Expr::Await(e) => Some(&e.base),
+ Expr::Binary(e) => {
+ stack.push(&e.right);
+ Some(&e.left)
+ }
+ Expr::Break(e) => {
+ if let Some(Expr::Block(_)) = e.expr.as_deref() {
+ return true;
+ }
+ stack.pop()
+ }
+ Expr::Call(e) => Some(&e.func),
+ Expr::Cast(e) => Some(&e.expr),
+ Expr::Closure(e) => Some(&e.body),
+ Expr::Field(e) => Some(&e.base),
+ Expr::Index(e) => Some(&e.expr),
+ Expr::MethodCall(e) => Some(&e.receiver),
+ Expr::Range(e) => {
+ if let Some(Expr::Block(_)) = e.end.as_deref() {
+ return true;
+ }
+ match (&e.start, &e.end) {
+ (Some(start), end) => {
+ stack.extend(end);
+ Some(start)
+ }
+ (None, Some(end)) => Some(end),
+ (None, None) => stack.pop(),
+ }
+ }
+ Expr::Reference(e) => Some(&e.expr),
+ Expr::Return(e) => {
+ if e.expr.is_none() && stack.is_empty() {
+ return true;
+ }
+ stack.pop()
+ }
+ Expr::Struct(_) => return true,
+ Expr::Try(e) => Some(&e.expr),
+ Expr::Unary(e) => Some(&e.expr),
+ Expr::Yield(e) => {
+ if e.expr.is_none() && stack.is_empty() {
+ return true;
+ }
+ stack.pop()
+ }
+
+ Expr::Array(_)
+ | Expr::Async(_)
+ | Expr::Block(_)
+ | Expr::Const(_)
+ | Expr::Continue(_)
+ | Expr::ForLoop(_)
+ | Expr::Group(_)
+ | Expr::If(_)
+ | Expr::Infer(_)
+ | Expr::Let(_)
+ | Expr::Lit(_)
+ | Expr::Loop(_)
+ | Expr::Macro(_)
+ | Expr::Match(_)
+ | Expr::Paren(_)
+ | Expr::Path(_)
+ | Expr::Repeat(_)
+ | Expr::TryBlock(_)
+ | Expr::Tuple(_)
+ | Expr::Unsafe(_)
+ | Expr::Verbatim(_)
+ | Expr::While(_) => stack.pop(),
+ } {
+ expr = next;
+ }
+
+ false
+}
+
+#[cfg(feature = "printing")]
+pub(crate) fn confusable_with_adjacent_lt(mut expr: &Expr) -> bool {
+ loop {
+ match expr {
+ Expr::Binary(e) => expr = &e.right,
+ Expr::Cast(e) => return trailing_unparameterized_path(&e.ty),
+ Expr::Reference(e) => expr = &e.expr,
+ Expr::Unary(e) => expr = &e.expr,
+
+ Expr::Array(_)
+ | Expr::Assign(_)
+ | Expr::Async(_)
+ | Expr::Await(_)
+ | Expr::Block(_)
+ | Expr::Break(_)
+ | Expr::Call(_)
+ | Expr::Closure(_)
+ | Expr::Const(_)
+ | Expr::Continue(_)
+ | Expr::Field(_)
+ | Expr::ForLoop(_)
+ | Expr::Group(_)
+ | Expr::If(_)
+ | Expr::Index(_)
+ | Expr::Infer(_)
+ | Expr::Let(_)
+ | Expr::Lit(_)
+ | Expr::Loop(_)
+ | Expr::Macro(_)
+ | Expr::Match(_)
+ | Expr::MethodCall(_)
+ | Expr::Paren(_)
+ | Expr::Path(_)
+ | Expr::Range(_)
+ | Expr::Repeat(_)
+ | Expr::Return(_)
+ | Expr::Struct(_)
+ | Expr::Try(_)
+ | Expr::TryBlock(_)
+ | Expr::Tuple(_)
+ | Expr::Unsafe(_)
+ | Expr::Verbatim(_)
+ | Expr::While(_)
+ | Expr::Yield(_) => return false,
+ }
+ }
+
+ fn trailing_unparameterized_path(mut ty: &Type) -> bool {
+ loop {
+ match ty {
+ Type::BareFn(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<bool, &Type> {
+ 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<TypeParamBound, Token![+]>,
+ ) -> ControlFlow<bool, &Type> {
+ match bounds.last().unwrap() {
+ TypeParamBound::Trait(t) => last_type_in_path(&t.path),
+ TypeParamBound::Lifetime(_) | TypeParamBound::Verbatim(_) => ControlFlow::Break(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::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::BareFn(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<TypeParamBound, Token![+]>,
+ ) -> ControlFlow<bool, &Type> {
+ 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(_) => 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/rust/hw/char/pl011/vendor/syn/src/custom_keyword.rs b/rust/hw/char/pl011/vendor/syn/src/custom_keyword.rs
new file mode 100644
index 0000000000..cc4f632c98
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/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::<kw::whatever>()?`
+///
+/// - [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<Self> {
+/// let lookahead = input.lookahead1();
+/// if lookahead.peek(kw::bool) {
+/// Ok(Argument::Bool {
+/// bool_token: input.parse::<kw::bool>()?,
+/// eq_token: input.parse()?,
+/// value: input.parse()?,
+/// })
+/// } else if lookahead.peek(kw::str) {
+/// Ok(Argument::Str {
+/// str_token: input.parse::<kw::str>()?,
+/// 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/rust/hw/char/pl011/vendor/syn/src/custom_punctuation.rs b/rust/hw/char/pl011/vendor/syn/src/custom_punctuation.rs
new file mode 100644
index 0000000000..eef5f54584
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/custom_punctuation.rs
@@ -0,0 +1,304 @@
+/// 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::<LeftRightArrow>()?`
+///
+/// - [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 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<Expr, PathSeparator>,
+/// }
+///
+/// impl Parse for PathSegments {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// 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<E: Peek>(input: ParseStream, end: E) -> Result<TokenStream> {
+/// let mut tokens = TokenStream::new();
+/// while !input.is_empty() && !input.peek(end) {
+/// let next: TokenTree = input.parse()?;
+/// tokens.extend(Some(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/rust/hw/char/pl011/vendor/syn/src/data.rs b/rust/hw/char/pl011/vendor/syn/src/data.rs
new file mode 100644
index 0000000000..a44cdf341d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/data.rs
@@ -0,0 +1,423 @@
+use crate::attr::Attribute;
+use crate::expr::Expr;
+use crate::ident::Ident;
+use crate::punctuated::{self, Punctuated};
+use crate::restriction::{FieldMutability, Visibility};
+use crate::token;
+use crate::ty::Type;
+
+ast_struct! {
+ /// An enum variant.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct Variant {
+ pub attrs: Vec<Attribute>,
+
+ /// 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<Field, Token![,]>,
+ }
+}
+
+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<Field, Token![,]>,
+ }
+}
+
+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<Field> {
+ 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<Field> {
+ 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(),
+ }
+ }
+}
+
+impl IntoIterator for Fields {
+ type Item = Field;
+ type IntoIter = punctuated::IntoIter<Field>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ match self {
+ Fields::Unit => Punctuated::<Field, ()>::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<Attribute>,
+
+ pub vis: Visibility,
+
+ pub mutability: FieldMutability,
+
+ /// Name of the field, if any.
+ ///
+ /// Fields of tuple structs have no names.
+ pub ident: Option<Ident>,
+
+ pub colon_token: Option<Token![:]>,
+
+ pub ty: Type,
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::attr::Attribute;
+ use crate::data::{Field, Fields, FieldsNamed, FieldsUnnamed, Variant};
+ use crate::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::{FieldMutability, Visibility};
+ 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<Self> {
+ 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.fork();
+ let ahead = input.fork();
+ let mut discriminant: Result<Expr> = ahead.parse();
+ if discriminant.is_ok() {
+ input.advance_to(&ahead);
+ } else if scan_lenient_discriminant(input).is_ok() {
+ discriminant = Ok(Expr::Verbatim(verbatim::between(&begin, input)));
+ }
+ discriminant?
+ };
+ Some((eq_token, discriminant))
+ } else {
+ None
+ };
+ Ok(Variant {
+ attrs,
+ ident,
+ fields,
+ discriminant,
+ })
+ }
+ }
+
+ #[cfg(not(feature = "full"))]
+ pub(crate) fn scan_lenient_discriminant(input: ParseStream) -> Result<()> {
+ use crate::expr::Member;
+ use crate::lifetime::Lifetime;
+ use crate::lit::Lit;
+ use crate::lit::LitFloat;
+ use crate::op::{BinOp, UnOp};
+ use crate::path::{self, AngleBracketedGenericArguments};
+ use proc_macro2::Delimiter::{self, Brace, Bracket, Parenthesis};
+
+ let consume = |delimiter: Delimiter| {
+ Result::unwrap(input.step(|cursor| match cursor.group(delimiter) {
+ Some((_inside, _span, rest)) => Ok((true, rest)),
+ None => Ok((false, *cursor)),
+ }))
+ };
+
+ macro_rules! consume {
+ [$token:tt] => {
+ input.parse::<Option<Token![$token]>>().unwrap().is_some()
+ };
+ }
+
+ let mut initial = true;
+ let mut depth = 0usize;
+ loop {
+ if initial {
+ if consume![&] {
+ input.parse::<Option<Token![mut]>>()?;
+ } else if consume![if] || consume![match] || consume![while] {
+ depth += 1;
+ } else if input.parse::<Option<Lit>>()?.is_some()
+ || (consume(Brace) || consume(Bracket) || consume(Parenthesis))
+ || (consume![async] || consume![const] || consume![loop] || consume![unsafe])
+ && (consume(Brace) || break)
+ {
+ initial = false;
+ } else if consume![let] {
+ while !consume![=] {
+ if !((consume![|] || consume![ref] || consume![mut] || consume![@])
+ || (consume![!] || input.parse::<Option<Lit>>()?.is_some())
+ || (consume![..=] || consume![..] || consume![&] || consume![_])
+ || (consume(Brace) || consume(Bracket) || consume(Parenthesis)))
+ {
+ path::parsing::qpath(input, true)?;
+ }
+ }
+ } else if input.parse::<Option<Lifetime>>()?.is_some() && !consume![:] {
+ break;
+ } else if input.parse::<UnOp>().is_err() {
+ path::parsing::qpath(input, true)?;
+ initial = consume![!] || depth == 0 && input.peek(token::Brace);
+ }
+ } else if input.is_empty() || input.peek(Token![,]) {
+ return Ok(());
+ } else if depth > 0 && consume(Brace) {
+ if consume![else] && !consume(Brace) {
+ initial = consume![if] || break;
+ } else {
+ depth -= 1;
+ }
+ } else if input.parse::<BinOp>().is_ok() || (consume![..] | consume![=]) {
+ initial = true;
+ } else if consume![.] {
+ if input.parse::<Option<LitFloat>>()?.is_none()
+ && (input.parse::<Member>()?.is_named() && consume![::])
+ {
+ AngleBracketedGenericArguments::do_parse(None, input)?;
+ }
+ } else if consume![as] {
+ input.parse::<Type>()?;
+ } else if !(consume(Brace) || consume(Bracket) || consume(Parenthesis)) {
+ break;
+ }
+ }
+
+ Err(input.error("unsupported expression"))
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for FieldsNamed {
+ fn parse(input: ParseStream) -> Result<Self> {
+ 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<Self> {
+ 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<Self> {
+ 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.fork();
+ input.call(Ident::parse_any)?;
+ input.parse::<FieldsNamed>()?;
+ Type::Verbatim(verbatim::between(&begin, input))
+ } else {
+ input.parse()?
+ };
+
+ Ok(Field {
+ attrs,
+ vis,
+ mutability: FieldMutability::None,
+ ident: Some(ident),
+ colon_token: Some(colon_token),
+ ty,
+ })
+ }
+
+ /// Parses an unnamed (tuple struct) field.
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn parse_unnamed(input: ParseStream) -> Result<Self> {
+ Ok(Field {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ mutability: FieldMutability::None,
+ ident: None,
+ colon_token: None,
+ ty: input.parse()?,
+ })
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use crate::data::{Field, FieldsNamed, FieldsUnnamed, Variant};
+ use crate::print::TokensOrDefault;
+ use proc_macro2::TokenStream;
+ use quote::{ToTokens, TokenStreamExt};
+
+ #[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);
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/derive.rs b/rust/hw/char/pl011/vendor/syn/src/derive.rs
new file mode 100644
index 0000000000..3443ecfc05
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/derive.rs
@@ -0,0 +1,259 @@
+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;
+
+ast_struct! {
+ /// Data structure sent to a `proc_macro_derive` macro.
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ pub struct DeriveInput {
+ pub attrs: Vec<Attribute>,
+ 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<Token![;]>,
+ }
+}
+
+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<Variant, Token![,]>,
+ }
+}
+
+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<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis = input.parse::<Visibility>()?;
+
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Token![struct]) {
+ let struct_token = input.parse::<Token![struct]>()?;
+ let ident = input.parse::<Ident>()?;
+ let generics = input.parse::<Generics>()?;
+ 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::<Token![enum]>()?;
+ let ident = input.parse::<Ident>()?;
+ let generics = input.parse::<Generics>()?;
+ 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::<Token![union]>()?;
+ let ident = input.parse::<Ident>()?;
+ let generics = input.parse::<Generics>()?;
+ 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<WhereClause>, Fields, Option<Token![;]>)> {
+ 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<WhereClause>,
+ token::Brace,
+ Punctuated<Variant, Token![,]>,
+ )> {
+ 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<WhereClause>, 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/rust/hw/char/pl011/vendor/syn/src/discouraged.rs b/rust/hw/char/pl011/vendor/syn/src/discouraged.rs
new file mode 100644
index 0000000000..4109c670e7
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/discouraged.rs
@@ -0,0 +1,225 @@
+//! Extensions to the parsing API with niche applicability.
+
+use crate::buffer::Cursor;
+use crate::error::Result;
+use crate::parse::{inner_unexpected, ParseBuffer, Unexpected};
+use proc_macro2::extra::DelimSpan;
+use proc_macro2::Delimiter;
+use std::cell::Cell;
+use std::mem;
+use std::rc::Rc;
+
+/// Extensions to the `ParseStream` API to support speculative parsing.
+pub trait Speculative {
+ /// 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::<T>` no longer required by accepting
+ /// `path::to<T>` 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<T> From<T> for PathSegment
+ /// # where
+ /// # T: Into<Ident>,
+ /// # {
+ /// # fn from(ident: T) -> Self {
+ /// # PathSegment {
+ /// # ident: ident.into(),
+ /// # arguments: PathArguments::None,
+ /// # }
+ /// # }
+ /// # }
+ ///
+ /// impl Parse for PathSegment {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// 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::<PathSegment>("a<b,c>").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), None) => {
+ self_unexp.set(Unexpected::Some(span));
+ }
+ // 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
+ // bubble up the chain by replacing the root `unexpected`
+ // pointer, only 'unexpected' tokens from existing group
+ // parsers should bubble.
+ 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::<Cursor, Cursor<'static>>(fork.cursor()) });
+ }
+}
+
+/// Extensions to the `ParseStream` API to support manipulating invisible
+/// delimiters the same as if they were visible.
+pub trait AnyDelimiter {
+ /// 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 = crate::buffer::close_span_of_group(*cursor);
+ 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"))
+ }
+ })
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/drops.rs b/rust/hw/char/pl011/vendor/syn/src/drops.rs
new file mode 100644
index 0000000000..89b42d82ef
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/drops.rs
@@ -0,0 +1,58 @@
+use std::iter;
+use std::mem::ManuallyDrop;
+use std::ops::{Deref, DerefMut};
+use std::option;
+use std::slice;
+
+#[repr(transparent)]
+pub(crate) struct NoDrop<T: ?Sized>(ManuallyDrop<T>);
+
+impl<T> NoDrop<T> {
+ pub(crate) fn new(value: T) -> Self
+ where
+ T: TrivialDrop,
+ {
+ NoDrop(ManuallyDrop::new(value))
+ }
+}
+
+impl<T: ?Sized> Deref for NoDrop<T> {
+ type Target = T;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+impl<T: ?Sized> DerefMut for NoDrop<T> {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.0
+ }
+}
+
+pub(crate) trait TrivialDrop {}
+
+impl<T> TrivialDrop for iter::Empty<T> {}
+impl<'a, T> TrivialDrop for slice::Iter<'a, T> {}
+impl<'a, T> TrivialDrop for slice::IterMut<'a, T> {}
+impl<'a, T> TrivialDrop for option::IntoIter<&'a T> {}
+impl<'a, T> TrivialDrop for option::IntoIter<&'a mut T> {}
+
+#[test]
+fn test_needs_drop() {
+ use std::mem::needs_drop;
+
+ struct NeedsDrop;
+
+ impl Drop for NeedsDrop {
+ fn drop(&mut self) {}
+ }
+
+ assert!(needs_drop::<NeedsDrop>());
+
+ // Test each of the types with a handwritten TrivialDrop impl above.
+ assert!(!needs_drop::<iter::Empty<NeedsDrop>>());
+ assert!(!needs_drop::<slice::Iter<NeedsDrop>>());
+ assert!(!needs_drop::<slice::IterMut<NeedsDrop>>());
+ assert!(!needs_drop::<option::IntoIter<&NeedsDrop>>());
+ assert!(!needs_drop::<option::IntoIter<&mut NeedsDrop>>());
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/error.rs b/rust/hw/char/pl011/vendor/syn/src/error.rs
new file mode 100644
index 0000000000..63310543a3
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/error.rs
@@ -0,0 +1,467 @@
+#[cfg(feature = "parsing")]
+use crate::buffer::Cursor;
+use crate::thread::ThreadBound;
+use proc_macro2::{
+ Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree,
+};
+#[cfg(feature = "printing")]
+use quote::ToTokens;
+use std::fmt::{self, Debug, Display};
+use std::slice;
+use std::vec;
+
+/// The result of a Syn parser.
+pub type Result<T> = std::result::Result<T, Error>;
+
+/// 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!`]: std::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<Self> {
+/// # 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<proc_macro2::TokenStream>
+/// 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<TokenStream> {
+/// # unimplemented!()
+/// # }
+/// # }
+/// ```
+pub struct Error {
+ messages: Vec<ErrorMessage>,
+}
+
+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<SpanRange>,
+ message: String,
+}
+
+// Cannot use std::ops::Range<Span> because that does not implement Copy,
+// whereas ThreadBound<T> 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<LitStr> {
+ /// 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::<Token![=]>()?;
+ /// let s: LitStr = input.parse()?;
+ /// Ok(s)
+ /// }
+ /// ```
+ pub fn new<T: Display>(span: Span, message: T) -> 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<T: ToTokens, U: Display>(tokens: T, message: U) -> 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,
+ }],
+ }
+ }
+ }
+
+ /// 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!`]: std::compile_error!
+ /// [`parse_macro_input!`]: crate::parse_macro_input!
+ pub fn to_compile_error(&self) -> TokenStream {
+ self.messages
+ .iter()
+ .map(ErrorMessage::to_compile_error)
+ .collect()
+ }
+
+ /// Render the error as an invocation of [`compile_error!`].
+ ///
+ /// [`compile_error!`]: std::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<TokenStream> {
+ /// /* ... */
+ /// # 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) -> 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)
+ TokenStream::from_iter([
+ TokenTree::Punct({
+ let mut punct = Punct::new(':', Spacing::Joint);
+ punct.set_span(start);
+ punct
+ }),
+ TokenTree::Punct({
+ let mut punct = Punct::new(':', Spacing::Alone);
+ punct.set_span(start);
+ punct
+ }),
+ TokenTree::Ident(Ident::new("core", start)),
+ TokenTree::Punct({
+ let mut punct = Punct::new(':', Spacing::Joint);
+ punct.set_span(start);
+ punct
+ }),
+ TokenTree::Punct({
+ let mut punct = Punct::new(':', Spacing::Alone);
+ punct.set_span(start);
+ punct
+ }),
+ TokenTree::Ident(Ident::new("compile_error", start)),
+ TokenTree::Punct({
+ let mut punct = Punct::new('!', Spacing::Alone);
+ punct.set_span(start);
+ punct
+ }),
+ TokenTree::Group({
+ let mut group = Group::new(Delimiter::Brace, {
+ TokenStream::from_iter([TokenTree::Literal({
+ let mut string = Literal::string(&self.message);
+ string.set_span(end);
+ string
+ })])
+ });
+ group.set_span(end);
+ group
+ }),
+ ])
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) fn new_at<T: Display>(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<T: Display>(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 {}
+
+impl std::error::Error for Error {}
+
+impl From<LexError> 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<ErrorMessage>,
+}
+
+impl Iterator for IntoIter {
+ type Item = Error;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ 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<Self::Item> {
+ Some(Error {
+ messages: vec![self.messages.next()?.clone()],
+ })
+ }
+}
+
+impl Extend<Error> for Error {
+ fn extend<T: IntoIterator<Item = Error>>(&mut self, iter: T) {
+ for err in iter {
+ self.combine(err);
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/export.rs b/rust/hw/char/pl011/vendor/syn/src/export.rs
new file mode 100644
index 0000000000..b9ea5c747b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/export.rs
@@ -0,0 +1,73 @@
+#[doc(hidden)]
+pub use std::clone::Clone;
+#[doc(hidden)]
+pub use std::cmp::{Eq, PartialEq};
+#[doc(hidden)]
+pub use std::concat;
+#[doc(hidden)]
+pub use std::default::Default;
+#[doc(hidden)]
+pub use std::fmt::Debug;
+#[doc(hidden)]
+pub use std::hash::{Hash, Hasher};
+#[doc(hidden)]
+pub use std::marker::Copy;
+#[doc(hidden)]
+pub use std::option::Option::{None, Some};
+#[doc(hidden)]
+pub use std::result::Result::{Err, Ok};
+#[doc(hidden)]
+pub use std::stringify;
+
+#[doc(hidden)]
+pub type Formatter<'a> = std::fmt::Formatter<'a>;
+#[doc(hidden)]
+pub type FmtResult = std::fmt::Result;
+
+#[doc(hidden)]
+pub type bool = std::primitive::bool;
+#[doc(hidden)]
+pub type str = std::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/rust/hw/char/pl011/vendor/syn/src/expr.rs b/rust/hw/char/pl011/vendor/syn/src/expr.rs
new file mode 100644
index 0000000000..c60bcf4771
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/expr.rs
@@ -0,0 +1,3960 @@
+use crate::attr::Attribute;
+#[cfg(all(feature = "parsing", feature = "full"))]
+use crate::error::Result;
+#[cfg(feature = "full")]
+use crate::generics::BoundLifetimes;
+use crate::ident::Ident;
+#[cfg(feature = "full")]
+use crate::lifetime::Lifetime;
+use crate::lit::Lit;
+use crate::mac::Macro;
+use crate::op::{BinOp, UnOp};
+#[cfg(all(feature = "parsing", feature = "full"))]
+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;
+#[cfg(feature = "full")]
+use crate::ty::ReturnType;
+use crate::ty::Type;
+use proc_macro2::{Span, TokenStream};
+#[cfg(feature = "printing")]
+use quote::IdentFragment;
+#[cfg(feature = "printing")]
+use std::fmt::{self, Display};
+use std::hash::{Hash, Hasher};
+#[cfg(all(feature = "parsing", feature = "full"))]
+use std::mem;
+
+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`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ #[non_exhaustive]
+ pub enum Expr {
+ /// A slice literal expression: `[a, b, c, d]`.
+ Array(ExprArray),
+
+ /// An assignment expression: `a = compute()`.
+ Assign(ExprAssign),
+
+ /// An async block: `async { ... }`.
+ Async(ExprAsync),
+
+ /// An await expression: `fut.await`.
+ Await(ExprAwait),
+
+ /// A binary operation: `a + b`, `a += b`.
+ Binary(ExprBinary),
+
+ /// A blocked scope: `{ ... }`.
+ Block(ExprBlock),
+
+ /// A `break`, with an optional label to break and an optional
+ /// expression.
+ 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`.
+ Closure(ExprClosure),
+
+ /// A const block: `const { ... }`.
+ Const(ExprConst),
+
+ /// A `continue`, with an optional label.
+ 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 { ... }`.
+ 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.
+ If(ExprIf),
+
+ /// A square bracketed indexing expression: `vector[2]`.
+ Index(ExprIndex),
+
+ /// The inferred value of a const generic argument, denoted `_`.
+ Infer(ExprInfer),
+
+ /// A `let` guard: `let Some(x) = opt`.
+ Let(ExprLet),
+
+ /// A literal in place of an expression: `1`, `"foo"`.
+ Lit(ExprLit),
+
+ /// Conditionless loop: `loop { ... }`.
+ Loop(ExprLoop),
+
+ /// A macro invocation expression: `format!("{}", q)`.
+ Macro(ExprMacro),
+
+ /// A `match` expression: `match n { Some(n) => {}, None => {} }`.
+ Match(ExprMatch),
+
+ /// A method call expression: `x.foo::<T>(a, b)`.
+ MethodCall(ExprMethodCall),
+
+ /// A parenthesized expression: `(a + b)`.
+ Paren(ExprParen),
+
+ /// A path like `std::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`.
+ Range(ExprRange),
+
+ /// A referencing operation: `&a` or `&mut a`.
+ Reference(ExprReference),
+
+ /// An array literal constructed from one repeated element: `[0u8; N]`.
+ Repeat(ExprRepeat),
+
+ /// A `return`, with an optional value to be returned.
+ 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?`.
+ Try(ExprTry),
+
+ /// A try block: `try { ... }`.
+ TryBlock(ExprTryBlock),
+
+ /// A tuple expression: `(a, b, c, d)`.
+ Tuple(ExprTuple),
+
+ /// A unary operation: `!x`, `*x`.
+ Unary(ExprUnary),
+
+ /// An unsafe block: `unsafe { ... }`.
+ Unsafe(ExprUnsafe),
+
+ /// Tokens in expression position not interpreted by Syn.
+ Verbatim(TokenStream),
+
+ /// A while loop: `while expr { ... }`.
+ While(ExprWhile),
+
+ /// A yield expression: `yield expr`.
+ Yield(ExprYield),
+
+ // For testing exhaustiveness in downstream code, use the following idiom:
+ //
+ // match expr {
+ // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
+ //
+ // Expr::Array(expr) => {...}
+ // Expr::Assign(expr) => {...}
+ // ...
+ // 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.
+ }
+}
+
+ast_struct! {
+ /// A slice literal expression: `[a, b, c, d]`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprArray #full {
+ pub attrs: Vec<Attribute>,
+ pub bracket_token: token::Bracket,
+ pub elems: Punctuated<Expr, Token![,]>,
+ }
+}
+
+ast_struct! {
+ /// An assignment expression: `a = compute()`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprAssign #full {
+ pub attrs: Vec<Attribute>,
+ pub left: Box<Expr>,
+ pub eq_token: Token![=],
+ pub right: Box<Expr>,
+ }
+}
+
+ast_struct! {
+ /// An async block: `async { ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprAsync #full {
+ pub attrs: Vec<Attribute>,
+ pub async_token: Token![async],
+ pub capture: Option<Token![move]>,
+ pub block: Block,
+ }
+}
+
+ast_struct! {
+ /// An await expression: `fut.await`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprAwait #full {
+ pub attrs: Vec<Attribute>,
+ pub base: Box<Expr>,
+ 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<Attribute>,
+ pub left: Box<Expr>,
+ pub op: BinOp,
+ pub right: Box<Expr>,
+ }
+}
+
+ast_struct! {
+ /// A blocked scope: `{ ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprBlock #full {
+ pub attrs: Vec<Attribute>,
+ pub label: Option<Label>,
+ pub block: Block,
+ }
+}
+
+ast_struct! {
+ /// A `break`, with an optional label to break and an optional
+ /// expression.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprBreak #full {
+ pub attrs: Vec<Attribute>,
+ pub break_token: Token![break],
+ pub label: Option<Lifetime>,
+ pub expr: Option<Box<Expr>>,
+ }
+}
+
+ast_struct! {
+ /// A function call expression: `invoke(a, b)`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ExprCall {
+ pub attrs: Vec<Attribute>,
+ pub func: Box<Expr>,
+ pub paren_token: token::Paren,
+ pub args: Punctuated<Expr, Token![,]>,
+ }
+}
+
+ast_struct! {
+ /// A cast expression: `foo as f64`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ExprCast {
+ pub attrs: Vec<Attribute>,
+ pub expr: Box<Expr>,
+ pub as_token: Token![as],
+ pub ty: Box<Type>,
+ }
+}
+
+ast_struct! {
+ /// A closure expression: `|a, b| a + b`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprClosure #full {
+ pub attrs: Vec<Attribute>,
+ pub lifetimes: Option<BoundLifetimes>,
+ pub constness: Option<Token![const]>,
+ pub movability: Option<Token![static]>,
+ pub asyncness: Option<Token![async]>,
+ pub capture: Option<Token![move]>,
+ pub or1_token: Token![|],
+ pub inputs: Punctuated<Pat, Token![,]>,
+ pub or2_token: Token![|],
+ pub output: ReturnType,
+ pub body: Box<Expr>,
+ }
+}
+
+ast_struct! {
+ /// A const block: `const { ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprConst #full {
+ pub attrs: Vec<Attribute>,
+ pub const_token: Token![const],
+ pub block: Block,
+ }
+}
+
+ast_struct! {
+ /// A `continue`, with an optional label.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprContinue #full {
+ pub attrs: Vec<Attribute>,
+ pub continue_token: Token![continue],
+ pub label: Option<Lifetime>,
+ }
+}
+
+ast_struct! {
+ /// Access of a named struct field (`obj.k`) or unnamed tuple struct
+ /// field (`obj.0`).
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ExprField {
+ pub attrs: Vec<Attribute>,
+ pub base: Box<Expr>,
+ pub dot_token: Token![.],
+ pub member: Member,
+ }
+}
+
+ast_struct! {
+ /// A for loop: `for pat in expr { ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprForLoop #full {
+ pub attrs: Vec<Attribute>,
+ pub label: Option<Label>,
+ pub for_token: Token![for],
+ pub pat: Box<Pat>,
+ pub in_token: Token![in],
+ pub expr: Box<Expr>,
+ pub body: Block,
+ }
+}
+
+ast_struct! {
+ /// 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`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprGroup {
+ pub attrs: Vec<Attribute>,
+ pub group_token: token::Group,
+ pub expr: Box<Expr>,
+ }
+}
+
+ast_struct! {
+ /// 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")))]
+ pub struct ExprIf #full {
+ pub attrs: Vec<Attribute>,
+ pub if_token: Token![if],
+ pub cond: Box<Expr>,
+ pub then_branch: Block,
+ pub else_branch: Option<(Token![else], Box<Expr>)>,
+ }
+}
+
+ast_struct! {
+ /// A square bracketed indexing expression: `vector[2]`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ExprIndex {
+ pub attrs: Vec<Attribute>,
+ pub expr: Box<Expr>,
+ pub bracket_token: token::Bracket,
+ pub index: Box<Expr>,
+ }
+}
+
+ast_struct! {
+ /// The inferred value of a const generic argument, denoted `_`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprInfer #full {
+ pub attrs: Vec<Attribute>,
+ pub underscore_token: Token![_],
+ }
+}
+
+ast_struct! {
+ /// A `let` guard: `let Some(x) = opt`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprLet #full {
+ pub attrs: Vec<Attribute>,
+ pub let_token: Token![let],
+ pub pat: Box<Pat>,
+ pub eq_token: Token![=],
+ pub expr: Box<Expr>,
+ }
+}
+
+ast_struct! {
+ /// A literal in place of an expression: `1`, `"foo"`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ExprLit {
+ pub attrs: Vec<Attribute>,
+ pub lit: Lit,
+ }
+}
+
+ast_struct! {
+ /// Conditionless loop: `loop { ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprLoop #full {
+ pub attrs: Vec<Attribute>,
+ pub label: Option<Label>,
+ pub loop_token: Token![loop],
+ pub body: Block,
+ }
+}
+
+ast_struct! {
+ /// A macro invocation expression: `format!("{}", q)`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ExprMacro {
+ pub attrs: Vec<Attribute>,
+ pub mac: Macro,
+ }
+}
+
+ast_struct! {
+ /// A `match` expression: `match n { Some(n) => {}, None => {} }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprMatch #full {
+ pub attrs: Vec<Attribute>,
+ pub match_token: Token![match],
+ pub expr: Box<Expr>,
+ pub brace_token: token::Brace,
+ pub arms: Vec<Arm>,
+ }
+}
+
+ast_struct! {
+ /// A method call expression: `x.foo::<T>(a, b)`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ExprMethodCall {
+ pub attrs: Vec<Attribute>,
+ pub receiver: Box<Expr>,
+ pub dot_token: Token![.],
+ pub method: Ident,
+ pub turbofish: Option<AngleBracketedGenericArguments>,
+ pub paren_token: token::Paren,
+ pub args: Punctuated<Expr, Token![,]>,
+ }
+}
+
+ast_struct! {
+ /// A parenthesized expression: `(a + b)`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ExprParen {
+ pub attrs: Vec<Attribute>,
+ pub paren_token: token::Paren,
+ pub expr: Box<Expr>,
+ }
+}
+
+ast_struct! {
+ /// A path like `std::mem::replace` possibly containing generic
+ /// parameters and a qualified self-type.
+ ///
+ /// A plain identifier like `x` is a path of length 1.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ExprPath {
+ pub attrs: Vec<Attribute>,
+ pub qself: Option<QSelf>,
+ pub path: Path,
+ }
+}
+
+ast_struct! {
+ /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprRange #full {
+ pub attrs: Vec<Attribute>,
+ pub start: Option<Box<Expr>>,
+ pub limits: RangeLimits,
+ pub end: Option<Box<Expr>>,
+ }
+}
+
+ast_struct! {
+ /// A referencing operation: `&a` or `&mut a`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ExprReference {
+ pub attrs: Vec<Attribute>,
+ pub and_token: Token![&],
+ pub mutability: Option<Token![mut]>,
+ pub expr: Box<Expr>,
+ }
+}
+
+ast_struct! {
+ /// An array literal constructed from one repeated element: `[0u8; N]`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprRepeat #full {
+ pub attrs: Vec<Attribute>,
+ pub bracket_token: token::Bracket,
+ pub expr: Box<Expr>,
+ pub semi_token: Token![;],
+ pub len: Box<Expr>,
+ }
+}
+
+ast_struct! {
+ /// A `return`, with an optional value to be returned.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprReturn #full {
+ pub attrs: Vec<Attribute>,
+ pub return_token: Token![return],
+ pub expr: Option<Box<Expr>>,
+ }
+}
+
+ast_struct! {
+ /// 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 }`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ExprStruct {
+ pub attrs: Vec<Attribute>,
+ pub qself: Option<QSelf>,
+ pub path: Path,
+ pub brace_token: token::Brace,
+ pub fields: Punctuated<FieldValue, Token![,]>,
+ pub dot2_token: Option<Token![..]>,
+ pub rest: Option<Box<Expr>>,
+ }
+}
+
+ast_struct! {
+ /// A try-expression: `expr?`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprTry #full {
+ pub attrs: Vec<Attribute>,
+ pub expr: Box<Expr>,
+ pub question_token: Token![?],
+ }
+}
+
+ast_struct! {
+ /// A try block: `try { ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprTryBlock #full {
+ pub attrs: Vec<Attribute>,
+ pub try_token: Token![try],
+ pub block: Block,
+ }
+}
+
+ast_struct! {
+ /// A tuple expression: `(a, b, c, d)`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprTuple #full {
+ pub attrs: Vec<Attribute>,
+ pub paren_token: token::Paren,
+ pub elems: Punctuated<Expr, Token![,]>,
+ }
+}
+
+ast_struct! {
+ /// A unary operation: `!x`, `*x`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ExprUnary {
+ pub attrs: Vec<Attribute>,
+ pub op: UnOp,
+ pub expr: Box<Expr>,
+ }
+}
+
+ast_struct! {
+ /// An unsafe block: `unsafe { ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprUnsafe #full {
+ pub attrs: Vec<Attribute>,
+ pub unsafe_token: Token![unsafe],
+ pub block: Block,
+ }
+}
+
+ast_struct! {
+ /// A while loop: `while expr { ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprWhile #full {
+ pub attrs: Vec<Attribute>,
+ pub label: Option<Label>,
+ pub while_token: Token![while],
+ pub cond: Box<Expr>,
+ pub body: Block,
+ }
+}
+
+ast_struct! {
+ /// A yield expression: `yield expr`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ExprYield #full {
+ pub attrs: Vec<Attribute>,
+ pub yield_token: Token![yield],
+ pub expr: Option<Box<Expr>>,
+ }
+}
+
+impl Expr {
+ /// An unspecified invalid expression.
+ ///
+ /// ```
+ /// use quote::ToTokens;
+ /// use std::mem;
+ /// use syn::{parse_quote, Expr};
+ ///
+ /// fn unparenthesize(e: &mut Expr) {
+ /// while let Expr::Paren(paren) = e {
+ /// *e = mem::replace(&mut *paren.expr, Expr::PLACEHOLDER);
+ /// }
+ /// }
+ ///
+ /// fn main() {
+ /// let mut e: Expr = parse_quote! { ((1 + 1)) };
+ /// unparenthesize(&mut e);
+ /// assert_eq!("1 + 1", e.to_token_stream().to_string());
+ /// }
+ /// ```
+ pub const PLACEHOLDER: Self = Expr::Path(ExprPath {
+ attrs: Vec::new(),
+ qself: None,
+ path: Path {
+ leading_colon: None,
+ segments: Punctuated::new(),
+ },
+ });
+
+ /// An alternative to the primary `Expr::parse` parser (from the [`Parse`]
+ /// trait) for ambiguous syntactic positions in which a trailing brace
+ /// should not be taken as part of the expression.
+ ///
+ /// [`Parse`]: crate::parse::Parse
+ ///
+ /// Rust grammar has an ambiguity where braces sometimes turn a path
+ /// expression into a struct initialization and sometimes do not. In the
+ /// following code, the expression `S {}` is one expression. Presumably
+ /// there is an empty struct `struct S {}` defined somewhere which it is
+ /// instantiating.
+ ///
+ /// ```
+ /// # struct S;
+ /// # impl std::ops::Deref for S {
+ /// # type Target = bool;
+ /// # fn deref(&self) -> &Self::Target {
+ /// # &true
+ /// # }
+ /// # }
+ /// let _ = *S {};
+ ///
+ /// // parsed by rustc as: `*(S {})`
+ /// ```
+ ///
+ /// We would want to parse the above using `Expr::parse` after the `=`
+ /// token.
+ ///
+ /// But in the following, `S {}` is *not* a struct init expression.
+ ///
+ /// ```
+ /// # const S: &bool = &true;
+ /// if *S {} {}
+ ///
+ /// // parsed by rustc as:
+ /// //
+ /// // if (*S) {
+ /// // /* empty block */
+ /// // }
+ /// // {
+ /// // /* another empty block */
+ /// // }
+ /// ```
+ ///
+ /// For that reason we would want to parse if-conditions using
+ /// `Expr::parse_without_eager_brace` after the `if` token. Same for similar
+ /// syntactic positions such as the condition expr after a `while` token or
+ /// the expr at the top of a `match`.
+ ///
+ /// The Rust grammar's choices around which way this ambiguity is resolved
+ /// at various syntactic positions is fairly arbitrary. Really either parse
+ /// behavior could work in most positions, and language designers just
+ /// decide each case based on which is more likely to be what the programmer
+ /// had in mind most of the time.
+ ///
+ /// ```
+ /// # struct S;
+ /// # fn doc() -> S {
+ /// if return S {} {}
+ /// # unreachable!()
+ /// # }
+ ///
+ /// // parsed by rustc as:
+ /// //
+ /// // if (return (S {})) {
+ /// // }
+ /// //
+ /// // but could equally well have been this other arbitrary choice:
+ /// //
+ /// // if (return S) {
+ /// // }
+ /// // {}
+ /// ```
+ ///
+ /// Note the grammar ambiguity on trailing braces is distinct from
+ /// precedence and is not captured by assigning a precedence level to the
+ /// braced struct init expr in relation to other operators. This can be
+ /// illustrated by `return 0..S {}` vs `match 0..S {}`. The former parses as
+ /// `return (0..(S {}))` implying tighter precedence for struct init than
+ /// `..`, while the latter parses as `match (0..S) {}` implying tighter
+ /// precedence for `..` than struct init, a contradiction.
+ #[cfg(all(feature = "full", feature = "parsing"))]
+ #[cfg_attr(docsrs, doc(cfg(all(feature = "full", feature = "parsing"))))]
+ pub fn parse_without_eager_brace(input: ParseStream) -> Result<Expr> {
+ parsing::ambiguous_expr(input, parsing::AllowStruct(false))
+ }
+
+ /// An alternative to the primary `Expr::parse` parser (from the [`Parse`]
+ /// trait) for syntactic positions in which expression boundaries are placed
+ /// more eagerly than done by the typical expression grammar. This includes
+ /// expressions at the head of a statement or in the right-hand side of a
+ /// `match` arm.
+ ///
+ /// [`Parse`]: crate::parse::Parse
+ ///
+ /// Compare the following cases:
+ ///
+ /// 1.
+ /// ```
+ /// # let result = ();
+ /// # let guard = false;
+ /// # let cond = true;
+ /// # let f = true;
+ /// # let g = f;
+ /// #
+ /// let _ = match result {
+ /// () if guard => if cond { f } else { g }
+ /// () => false,
+ /// };
+ /// ```
+ ///
+ /// 2.
+ /// ```
+ /// # let cond = true;
+ /// # let f = ();
+ /// # let g = f;
+ /// #
+ /// let _ = || {
+ /// if cond { f } else { g }
+ /// ()
+ /// };
+ /// ```
+ ///
+ /// 3.
+ /// ```
+ /// # let cond = true;
+ /// # let f = || ();
+ /// # let g = f;
+ /// #
+ /// let _ = [if cond { f } else { g } ()];
+ /// ```
+ ///
+ /// The same sequence of tokens `if cond { f } else { g } ()` appears in
+ /// expression position 3 times. The first two syntactic positions use eager
+ /// placement of expression boundaries, and parse as `Expr::If`, with the
+ /// adjacent `()` becoming `Pat::Tuple` or `Expr::Tuple`. In contrast, the
+ /// third case uses standard expression boundaries and parses as
+ /// `Expr::Call`.
+ ///
+ /// As with [`parse_without_eager_brace`], this ambiguity in the Rust
+ /// grammar is independent of precedence.
+ ///
+ /// [`parse_without_eager_brace`]: Self::parse_without_eager_brace
+ #[cfg(all(feature = "full", feature = "parsing"))]
+ #[cfg_attr(docsrs, doc(cfg(all(feature = "full", feature = "parsing"))))]
+ pub fn parse_with_earlier_boundary_rule(input: ParseStream) -> Result<Expr> {
+ parsing::parse_with_earlier_boundary_rule(input)
+ }
+
+ #[cfg(all(feature = "parsing", feature = "full"))]
+ pub(crate) fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
+ match self {
+ Expr::Array(ExprArray { attrs, .. })
+ | Expr::Assign(ExprAssign { attrs, .. })
+ | Expr::Async(ExprAsync { attrs, .. })
+ | Expr::Await(ExprAwait { attrs, .. })
+ | Expr::Binary(ExprBinary { attrs, .. })
+ | Expr::Block(ExprBlock { attrs, .. })
+ | Expr::Break(ExprBreak { attrs, .. })
+ | Expr::Call(ExprCall { attrs, .. })
+ | Expr::Cast(ExprCast { attrs, .. })
+ | Expr::Closure(ExprClosure { attrs, .. })
+ | Expr::Const(ExprConst { attrs, .. })
+ | Expr::Continue(ExprContinue { attrs, .. })
+ | Expr::Field(ExprField { attrs, .. })
+ | Expr::ForLoop(ExprForLoop { attrs, .. })
+ | Expr::Group(ExprGroup { attrs, .. })
+ | Expr::If(ExprIf { attrs, .. })
+ | Expr::Index(ExprIndex { attrs, .. })
+ | Expr::Infer(ExprInfer { attrs, .. })
+ | Expr::Let(ExprLet { 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::Range(ExprRange { attrs, .. })
+ | Expr::Reference(ExprReference { attrs, .. })
+ | Expr::Repeat(ExprRepeat { attrs, .. })
+ | Expr::Return(ExprReturn { attrs, .. })
+ | Expr::Struct(ExprStruct { attrs, .. })
+ | Expr::Try(ExprTry { attrs, .. })
+ | Expr::TryBlock(ExprTryBlock { attrs, .. })
+ | Expr::Tuple(ExprTuple { attrs, .. })
+ | Expr::Unary(ExprUnary { attrs, .. })
+ | Expr::Unsafe(ExprUnsafe { attrs, .. })
+ | Expr::While(ExprWhile { attrs, .. })
+ | Expr::Yield(ExprYield { attrs, .. }) => mem::replace(attrs, new),
+ Expr::Verbatim(_) => Vec::new(),
+ }
+ }
+}
+
+ast_enum! {
+ /// A struct or tuple struct field accessed in a struct literal or field
+ /// expression.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub enum Member {
+ /// A named field like `self.x`.
+ Named(Ident),
+ /// An unnamed field like `self.0`.
+ Unnamed(Index),
+ }
+}
+
+impl From<Ident> for Member {
+ fn from(ident: Ident) -> Member {
+ Member::Named(ident)
+ }
+}
+
+impl From<Index> for Member {
+ fn from(index: Index) -> Member {
+ Member::Unnamed(index)
+ }
+}
+
+impl From<usize> for Member {
+ fn from(index: usize) -> Member {
+ Member::Unnamed(Index::from(index))
+ }
+}
+
+impl Eq for Member {}
+
+impl PartialEq for Member {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (Member::Named(this), Member::Named(other)) => this == other,
+ (Member::Unnamed(this), Member::Unnamed(other)) => this == other,
+ _ => false,
+ }
+ }
+}
+
+impl Hash for Member {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ match self {
+ Member::Named(m) => m.hash(state),
+ Member::Unnamed(m) => m.hash(state),
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+impl IdentFragment for Member {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Member::Named(m) => Display::fmt(m, formatter),
+ Member::Unnamed(m) => Display::fmt(&m.index, formatter),
+ }
+ }
+
+ fn span(&self) -> Option<Span> {
+ match self {
+ Member::Named(m) => Some(m.span()),
+ Member::Unnamed(m) => Some(m.span),
+ }
+ }
+}
+
+ast_struct! {
+ /// The index of an unnamed tuple struct field.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct Index {
+ pub index: u32,
+ pub span: Span,
+ }
+}
+
+impl From<usize> for Index {
+ fn from(index: usize) -> Index {
+ assert!(index < u32::MAX as usize);
+ Index {
+ index: index as u32,
+ span: Span::call_site(),
+ }
+ }
+}
+
+impl Eq for Index {}
+
+impl PartialEq for Index {
+ fn eq(&self, other: &Self) -> bool {
+ self.index == other.index
+ }
+}
+
+impl Hash for Index {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.index.hash(state);
+ }
+}
+
+#[cfg(feature = "printing")]
+impl IdentFragment for Index {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.index, formatter)
+ }
+
+ fn span(&self) -> Option<Span> {
+ Some(self.span)
+ }
+}
+
+ast_struct! {
+ /// A field-value pair in a struct literal.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct FieldValue {
+ pub attrs: Vec<Attribute>,
+ pub member: Member,
+
+ /// The colon in `Struct { x: x }`. If written in shorthand like
+ /// `Struct { x }`, there is no colon.
+ pub colon_token: Option<Token![:]>,
+
+ pub expr: Expr,
+ }
+}
+
+#[cfg(feature = "full")]
+ast_struct! {
+ /// A lifetime labeling a `for`, `while`, or `loop`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct Label {
+ pub name: Lifetime,
+ pub colon_token: Token![:],
+ }
+}
+
+#[cfg(feature = "full")]
+ast_struct! {
+ /// One arm of a `match` expression: `0..=10 => { return true; }`.
+ ///
+ /// As in:
+ ///
+ /// ```
+ /// # fn f() -> bool {
+ /// # let n = 0;
+ /// match n {
+ /// 0..=10 => {
+ /// return true;
+ /// }
+ /// // ...
+ /// # _ => {}
+ /// }
+ /// # false
+ /// # }
+ /// ```
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct Arm {
+ pub attrs: Vec<Attribute>,
+ pub pat: Pat,
+ pub guard: Option<(Token![if], Box<Expr>)>,
+ pub fat_arrow_token: Token![=>],
+ pub body: Box<Expr>,
+ pub comma: Option<Token![,]>,
+ }
+}
+
+#[cfg(feature = "full")]
+ast_enum! {
+ /// Limit types of a range, inclusive or exclusive.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub enum RangeLimits {
+ /// Inclusive at the beginning, exclusive at the end.
+ HalfOpen(Token![..]),
+ /// Inclusive at the beginning and end.
+ Closed(Token![..=]),
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ #[cfg(feature = "full")]
+ use crate::attr;
+ use crate::attr::Attribute;
+ #[cfg(feature = "full")]
+ use crate::classify;
+ use crate::error::{Error, Result};
+ #[cfg(feature = "full")]
+ use crate::expr::{
+ Arm, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure,
+ ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch,
+ ExprRange, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprTuple, ExprUnsafe, ExprWhile,
+ ExprYield, Label, RangeLimits,
+ };
+ use crate::expr::{
+ Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprGroup, ExprIndex, ExprLit, ExprMacro,
+ ExprMethodCall, ExprParen, ExprPath, ExprReference, ExprStruct, ExprUnary, FieldValue,
+ Index, Member,
+ };
+ #[cfg(feature = "full")]
+ use crate::ext::IdentExt as _;
+ #[cfg(feature = "full")]
+ use crate::generics::BoundLifetimes;
+ use crate::ident::Ident;
+ #[cfg(feature = "full")]
+ use crate::lifetime::Lifetime;
+ use crate::lit::{Lit, LitFloat, LitInt};
+ use crate::mac::{self, Macro};
+ use crate::op::BinOp;
+ use crate::parse::discouraged::Speculative as _;
+ #[cfg(feature = "full")]
+ use crate::parse::ParseBuffer;
+ use crate::parse::{Parse, ParseStream};
+ #[cfg(feature = "full")]
+ use crate::pat::{Pat, PatType};
+ use crate::path::{self, AngleBracketedGenericArguments, Path, QSelf};
+ use crate::precedence::Precedence;
+ use crate::punctuated::Punctuated;
+ #[cfg(feature = "full")]
+ use crate::stmt::Block;
+ use crate::token;
+ use crate::ty;
+ #[cfg(feature = "full")]
+ use crate::ty::{ReturnType, Type};
+ use crate::verbatim;
+ #[cfg(feature = "full")]
+ use proc_macro2::TokenStream;
+ use std::mem;
+
+ mod kw {
+ crate::custom_keyword!(builtin);
+ crate::custom_keyword!(raw);
+ }
+
+ // When we're parsing expressions which occur before blocks, like in an if
+ // statement's condition, we cannot parse a struct literal.
+ //
+ // Struct literals are ambiguous in certain positions
+ // https://github.com/rust-lang/rfcs/pull/92
+ #[cfg(feature = "full")]
+ pub(super) struct AllowStruct(pub bool);
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Expr {
+ fn parse(input: ParseStream) -> Result<Self> {
+ ambiguous_expr(
+ input,
+ #[cfg(feature = "full")]
+ AllowStruct(true),
+ )
+ }
+ }
+
+ #[cfg(feature = "full")]
+ pub(super) fn parse_with_earlier_boundary_rule(input: ParseStream) -> Result<Expr> {
+ let mut attrs = input.call(expr_attrs)?;
+ let mut expr = if input.peek(token::Group) {
+ let allow_struct = AllowStruct(true);
+ let atom = expr_group(input, allow_struct)?;
+ if continue_parsing_early(&atom) {
+ trailer_helper(input, atom)?
+ } else {
+ atom
+ }
+ } else if input.peek(Token![if]) {
+ Expr::If(input.parse()?)
+ } else if input.peek(Token![while]) {
+ Expr::While(input.parse()?)
+ } else if input.peek(Token![for])
+ && !(input.peek2(Token![<]) && (input.peek3(Lifetime) || input.peek3(Token![>])))
+ {
+ Expr::ForLoop(input.parse()?)
+ } else if input.peek(Token![loop]) {
+ Expr::Loop(input.parse()?)
+ } else if input.peek(Token![match]) {
+ Expr::Match(input.parse()?)
+ } else if input.peek(Token![try]) && input.peek2(token::Brace) {
+ Expr::TryBlock(input.parse()?)
+ } else if input.peek(Token![unsafe]) {
+ Expr::Unsafe(input.parse()?)
+ } else if input.peek(Token![const]) && input.peek2(token::Brace) {
+ Expr::Const(input.parse()?)
+ } else if input.peek(token::Brace) {
+ Expr::Block(input.parse()?)
+ } else if input.peek(Lifetime) {
+ atom_labeled(input)?
+ } else {
+ let allow_struct = AllowStruct(true);
+ unary_expr(input, allow_struct)?
+ };
+
+ if continue_parsing_early(&expr) {
+ attrs.extend(expr.replace_attrs(Vec::new()));
+ expr.replace_attrs(attrs);
+
+ let allow_struct = AllowStruct(true);
+ return parse_expr(input, expr, allow_struct, Precedence::Any);
+ }
+
+ if input.peek(Token![.]) && !input.peek(Token![..]) || input.peek(Token![?]) {
+ expr = trailer_helper(input, expr)?;
+
+ attrs.extend(expr.replace_attrs(Vec::new()));
+ expr.replace_attrs(attrs);
+
+ let allow_struct = AllowStruct(true);
+ return parse_expr(input, expr, allow_struct, Precedence::Any);
+ }
+
+ attrs.extend(expr.replace_attrs(Vec::new()));
+ expr.replace_attrs(attrs);
+ Ok(expr)
+ }
+
+ #[cfg(feature = "full")]
+ impl Copy for AllowStruct {}
+
+ #[cfg(feature = "full")]
+ impl Clone for AllowStruct {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn can_begin_expr(input: ParseStream) -> bool {
+ input.peek(Ident::peek_any) // value name or keyword
+ || input.peek(token::Paren) // tuple
+ || input.peek(token::Bracket) // array
+ || input.peek(token::Brace) // block
+ || input.peek(Lit) // literal
+ || input.peek(Token![!]) && !input.peek(Token![!=]) // operator not
+ || input.peek(Token![-]) && !input.peek(Token![-=]) && !input.peek(Token![->]) // unary minus
+ || input.peek(Token![*]) && !input.peek(Token![*=]) // dereference
+ || input.peek(Token![|]) && !input.peek(Token![|=]) // closure
+ || input.peek(Token![&]) && !input.peek(Token![&=]) // reference
+ || input.peek(Token![..]) // range notation
+ || input.peek(Token![<]) && !input.peek(Token![<=]) && !input.peek(Token![<<=]) // associated path
+ || input.peek(Token![::]) // global path
+ || input.peek(Lifetime) // labeled loop
+ || input.peek(Token![#]) // expression attributes
+ }
+
+ #[cfg(feature = "full")]
+ fn parse_expr(
+ input: ParseStream,
+ mut lhs: Expr,
+ allow_struct: AllowStruct,
+ base: Precedence,
+ ) -> Result<Expr> {
+ loop {
+ let ahead = input.fork();
+ if let Expr::Range(ExprRange { end: Some(_), .. }) = lhs {
+ // A range with an upper bound cannot be the left-hand side of
+ // another binary operator.
+ break;
+ } else if let Ok(op) = ahead.parse::<BinOp>() {
+ let precedence = Precedence::of_binop(&op);
+ if precedence < base {
+ break;
+ }
+ if precedence == Precedence::Compare {
+ if let Expr::Binary(lhs) = &lhs {
+ if Precedence::of_binop(&lhs.op) == Precedence::Compare {
+ break;
+ }
+ }
+ }
+ input.advance_to(&ahead);
+ let right = parse_binop_rhs(input, allow_struct, precedence)?;
+ lhs = Expr::Binary(ExprBinary {
+ attrs: Vec::new(),
+ left: Box::new(lhs),
+ op,
+ right,
+ });
+ } else if Precedence::Assign >= base && input.peek(Token![=]) && !input.peek(Token![=>])
+ {
+ let eq_token: Token![=] = input.parse()?;
+ let right = parse_binop_rhs(input, allow_struct, Precedence::Assign)?;
+ lhs = Expr::Assign(ExprAssign {
+ attrs: Vec::new(),
+ left: Box::new(lhs),
+ eq_token,
+ right,
+ });
+ } else if Precedence::Range >= base && input.peek(Token![..]) {
+ let limits: RangeLimits = input.parse()?;
+ let end = parse_range_end(input, &limits, allow_struct)?;
+ lhs = Expr::Range(ExprRange {
+ attrs: Vec::new(),
+ start: Some(Box::new(lhs)),
+ limits,
+ end,
+ });
+ } else if Precedence::Cast >= base && input.peek(Token![as]) {
+ let as_token: Token![as] = input.parse()?;
+ let allow_plus = false;
+ let allow_group_generic = false;
+ let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?;
+ check_cast(input)?;
+ lhs = Expr::Cast(ExprCast {
+ attrs: Vec::new(),
+ expr: Box::new(lhs),
+ as_token,
+ ty: Box::new(ty),
+ });
+ } else {
+ break;
+ }
+ }
+ Ok(lhs)
+ }
+
+ #[cfg(not(feature = "full"))]
+ fn parse_expr(input: ParseStream, mut lhs: Expr, base: Precedence) -> Result<Expr> {
+ loop {
+ let ahead = input.fork();
+ if let Ok(op) = ahead.parse::<BinOp>() {
+ let precedence = Precedence::of_binop(&op);
+ if precedence < base {
+ break;
+ }
+ if precedence == Precedence::Compare {
+ if let Expr::Binary(lhs) = &lhs {
+ if Precedence::of_binop(&lhs.op) == Precedence::Compare {
+ break;
+ }
+ }
+ }
+ input.advance_to(&ahead);
+ let right = parse_binop_rhs(input, precedence)?;
+ lhs = Expr::Binary(ExprBinary {
+ attrs: Vec::new(),
+ left: Box::new(lhs),
+ op,
+ right,
+ });
+ } else if Precedence::Cast >= base && input.peek(Token![as]) {
+ let as_token: Token![as] = input.parse()?;
+ let allow_plus = false;
+ let allow_group_generic = false;
+ let ty = ty::parsing::ambig_ty(input, allow_plus, allow_group_generic)?;
+ check_cast(input)?;
+ lhs = Expr::Cast(ExprCast {
+ attrs: Vec::new(),
+ expr: Box::new(lhs),
+ as_token,
+ ty: Box::new(ty),
+ });
+ } else {
+ break;
+ }
+ }
+ Ok(lhs)
+ }
+
+ fn parse_binop_rhs(
+ input: ParseStream,
+ #[cfg(feature = "full")] allow_struct: AllowStruct,
+ precedence: Precedence,
+ ) -> Result<Box<Expr>> {
+ let mut rhs = unary_expr(
+ input,
+ #[cfg(feature = "full")]
+ allow_struct,
+ )?;
+ loop {
+ let next = peek_precedence(input);
+ if next > precedence || next == precedence && precedence == Precedence::Assign {
+ rhs = parse_expr(
+ input,
+ rhs,
+ #[cfg(feature = "full")]
+ allow_struct,
+ next,
+ )?;
+ } else {
+ return Ok(Box::new(rhs));
+ }
+ }
+ }
+
+ fn peek_precedence(input: ParseStream) -> Precedence {
+ if let Ok(op) = input.fork().parse() {
+ Precedence::of_binop(&op)
+ } else if input.peek(Token![=]) && !input.peek(Token![=>]) {
+ Precedence::Assign
+ } else if input.peek(Token![..]) {
+ Precedence::Range
+ } else if input.peek(Token![as]) {
+ Precedence::Cast
+ } else {
+ Precedence::Any
+ }
+ }
+
+ // Parse an arbitrary expression.
+ pub(super) fn ambiguous_expr(
+ input: ParseStream,
+ #[cfg(feature = "full")] allow_struct: AllowStruct,
+ ) -> Result<Expr> {
+ let lhs = unary_expr(
+ input,
+ #[cfg(feature = "full")]
+ allow_struct,
+ )?;
+ parse_expr(
+ input,
+ lhs,
+ #[cfg(feature = "full")]
+ allow_struct,
+ Precedence::Any,
+ )
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_attrs(input: ParseStream) -> Result<Vec<Attribute>> {
+ let mut attrs = Vec::new();
+ while !input.peek(token::Group) && input.peek(Token![#]) {
+ attrs.push(input.call(attr::parsing::single_parse_outer)?);
+ }
+ Ok(attrs)
+ }
+
+ // <UnOp> <trailer>
+ // & <trailer>
+ // &mut <trailer>
+ // box <trailer>
+ #[cfg(feature = "full")]
+ fn unary_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
+ let begin = input.fork();
+ let attrs = input.call(expr_attrs)?;
+ if input.peek(token::Group) {
+ return trailer_expr(begin, attrs, input, allow_struct);
+ }
+
+ if input.peek(Token![&]) {
+ let and_token: Token![&] = input.parse()?;
+ let raw: Option<kw::raw> = if input.peek(kw::raw)
+ && (input.peek2(Token![mut]) || input.peek2(Token![const]))
+ {
+ Some(input.parse()?)
+ } else {
+ None
+ };
+ let mutability: Option<Token![mut]> = input.parse()?;
+ if raw.is_some() && mutability.is_none() {
+ input.parse::<Token![const]>()?;
+ }
+ let expr = Box::new(unary_expr(input, allow_struct)?);
+ if raw.is_some() {
+ Ok(Expr::Verbatim(verbatim::between(&begin, input)))
+ } else {
+ Ok(Expr::Reference(ExprReference {
+ attrs,
+ and_token,
+ mutability,
+ expr,
+ }))
+ }
+ } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
+ expr_unary(input, attrs, allow_struct).map(Expr::Unary)
+ } else {
+ trailer_expr(begin, attrs, input, allow_struct)
+ }
+ }
+
+ #[cfg(not(feature = "full"))]
+ fn unary_expr(input: ParseStream) -> Result<Expr> {
+ if input.peek(Token![&]) {
+ Ok(Expr::Reference(ExprReference {
+ attrs: Vec::new(),
+ and_token: input.parse()?,
+ mutability: input.parse()?,
+ expr: Box::new(unary_expr(input)?),
+ }))
+ } else if input.peek(Token![*]) || input.peek(Token![!]) || input.peek(Token![-]) {
+ Ok(Expr::Unary(ExprUnary {
+ attrs: Vec::new(),
+ op: input.parse()?,
+ expr: Box::new(unary_expr(input)?),
+ }))
+ } else {
+ trailer_expr(input)
+ }
+ }
+
+ // <atom> (..<args>) ...
+ // <atom> . <ident> (..<args>) ...
+ // <atom> . <ident> ...
+ // <atom> . <lit> ...
+ // <atom> [ <expr> ] ...
+ // <atom> ? ...
+ #[cfg(feature = "full")]
+ fn trailer_expr(
+ begin: ParseBuffer,
+ mut attrs: Vec<Attribute>,
+ input: ParseStream,
+ allow_struct: AllowStruct,
+ ) -> Result<Expr> {
+ let atom = atom_expr(input, allow_struct)?;
+ let mut e = trailer_helper(input, atom)?;
+
+ if let Expr::Verbatim(tokens) = &mut e {
+ *tokens = verbatim::between(&begin, input);
+ } else {
+ let inner_attrs = e.replace_attrs(Vec::new());
+ attrs.extend(inner_attrs);
+ e.replace_attrs(attrs);
+ }
+
+ Ok(e)
+ }
+
+ #[cfg(feature = "full")]
+ fn trailer_helper(input: ParseStream, mut e: Expr) -> Result<Expr> {
+ loop {
+ if input.peek(token::Paren) {
+ let content;
+ e = Expr::Call(ExprCall {
+ attrs: Vec::new(),
+ func: Box::new(e),
+ paren_token: parenthesized!(content in input),
+ args: content.parse_terminated(Expr::parse, Token![,])?,
+ });
+ } else if input.peek(Token![.])
+ && !input.peek(Token![..])
+ && match e {
+ Expr::Range(_) => false,
+ _ => true,
+ }
+ {
+ let mut dot_token: Token![.] = input.parse()?;
+
+ let float_token: Option<LitFloat> = input.parse()?;
+ if let Some(float_token) = float_token {
+ if multi_index(&mut e, &mut dot_token, float_token)? {
+ continue;
+ }
+ }
+
+ let await_token: Option<Token![await]> = input.parse()?;
+ if let Some(await_token) = await_token {
+ e = Expr::Await(ExprAwait {
+ attrs: Vec::new(),
+ base: Box::new(e),
+ dot_token,
+ await_token,
+ });
+ continue;
+ }
+
+ let member: Member = input.parse()?;
+ let turbofish = if member.is_named() && input.peek(Token![::]) {
+ Some(AngleBracketedGenericArguments::parse_turbofish(input)?)
+ } else {
+ None
+ };
+
+ if turbofish.is_some() || input.peek(token::Paren) {
+ if let Member::Named(method) = member {
+ let content;
+ e = Expr::MethodCall(ExprMethodCall {
+ attrs: Vec::new(),
+ receiver: Box::new(e),
+ dot_token,
+ method,
+ turbofish,
+ paren_token: parenthesized!(content in input),
+ args: content.parse_terminated(Expr::parse, Token![,])?,
+ });
+ continue;
+ }
+ }
+
+ e = Expr::Field(ExprField {
+ attrs: Vec::new(),
+ base: Box::new(e),
+ dot_token,
+ member,
+ });
+ } else if input.peek(token::Bracket) {
+ let content;
+ e = Expr::Index(ExprIndex {
+ attrs: Vec::new(),
+ expr: Box::new(e),
+ bracket_token: bracketed!(content in input),
+ index: content.parse()?,
+ });
+ } else if input.peek(Token![?]) {
+ e = Expr::Try(ExprTry {
+ attrs: Vec::new(),
+ expr: Box::new(e),
+ question_token: input.parse()?,
+ });
+ } else {
+ break;
+ }
+ }
+ Ok(e)
+ }
+
+ #[cfg(not(feature = "full"))]
+ fn trailer_expr(input: ParseStream) -> Result<Expr> {
+ let mut e = atom_expr(input)?;
+
+ loop {
+ if input.peek(token::Paren) {
+ let content;
+ e = Expr::Call(ExprCall {
+ attrs: Vec::new(),
+ func: Box::new(e),
+ paren_token: parenthesized!(content in input),
+ args: content.parse_terminated(Expr::parse, Token![,])?,
+ });
+ } else if input.peek(Token![.])
+ && !input.peek(Token![..])
+ && !input.peek2(Token![await])
+ {
+ let mut dot_token: Token![.] = input.parse()?;
+
+ let float_token: Option<LitFloat> = input.parse()?;
+ if let Some(float_token) = float_token {
+ if multi_index(&mut e, &mut dot_token, float_token)? {
+ continue;
+ }
+ }
+
+ let member: Member = input.parse()?;
+ let turbofish = if member.is_named() && input.peek(Token![::]) {
+ let colon2_token: Token![::] = input.parse()?;
+ let turbofish =
+ AngleBracketedGenericArguments::do_parse(Some(colon2_token), input)?;
+ Some(turbofish)
+ } else {
+ None
+ };
+
+ if turbofish.is_some() || input.peek(token::Paren) {
+ if let Member::Named(method) = member {
+ let content;
+ e = Expr::MethodCall(ExprMethodCall {
+ attrs: Vec::new(),
+ receiver: Box::new(e),
+ dot_token,
+ method,
+ turbofish,
+ paren_token: parenthesized!(content in input),
+ args: content.parse_terminated(Expr::parse, Token![,])?,
+ });
+ continue;
+ }
+ }
+
+ e = Expr::Field(ExprField {
+ attrs: Vec::new(),
+ base: Box::new(e),
+ dot_token,
+ member,
+ });
+ } else if input.peek(token::Bracket) {
+ let content;
+ e = Expr::Index(ExprIndex {
+ attrs: Vec::new(),
+ expr: Box::new(e),
+ bracket_token: bracketed!(content in input),
+ index: content.parse()?,
+ });
+ } else {
+ break;
+ }
+ }
+
+ Ok(e)
+ }
+
+ // Parse all atomic expressions which don't have to worry about precedence
+ // interactions, as they are fully contained.
+ #[cfg(feature = "full")]
+ fn atom_expr(input: ParseStream, allow_struct: AllowStruct) -> Result<Expr> {
+ if input.peek(token::Group) {
+ expr_group(input, allow_struct)
+ } else if input.peek(Lit) {
+ input.parse().map(Expr::Lit)
+ } else if input.peek(Token![async])
+ && (input.peek2(token::Brace) || input.peek2(Token![move]) && input.peek3(token::Brace))
+ {
+ input.parse().map(Expr::Async)
+ } else if input.peek(Token![try]) && input.peek2(token::Brace) {
+ input.parse().map(Expr::TryBlock)
+ } else if input.peek(Token![|])
+ || input.peek(Token![move])
+ || input.peek(Token![for])
+ && input.peek2(Token![<])
+ && (input.peek3(Lifetime) || input.peek3(Token![>]))
+ || input.peek(Token![const]) && !input.peek2(token::Brace)
+ || input.peek(Token![static])
+ || input.peek(Token![async]) && (input.peek2(Token![|]) || input.peek2(Token![move]))
+ {
+ expr_closure(input, allow_struct).map(Expr::Closure)
+ } else if input.peek(kw::builtin) && input.peek2(Token![#]) {
+ expr_builtin(input)
+ } else if input.peek(Ident)
+ || input.peek(Token![::])
+ || input.peek(Token![<])
+ || input.peek(Token![self])
+ || input.peek(Token![Self])
+ || input.peek(Token![super])
+ || input.peek(Token![crate])
+ || input.peek(Token![try]) && (input.peek2(Token![!]) || input.peek2(Token![::]))
+ {
+ path_or_macro_or_struct(input, allow_struct)
+ } else if input.peek(token::Paren) {
+ paren_or_tuple(input)
+ } else if input.peek(Token![break]) {
+ expr_break(input, allow_struct).map(Expr::Break)
+ } else if input.peek(Token![continue]) {
+ input.parse().map(Expr::Continue)
+ } else if input.peek(Token![return]) {
+ input.parse().map(Expr::Return)
+ } else if input.peek(token::Bracket) {
+ array_or_repeat(input)
+ } else if input.peek(Token![let]) {
+ expr_let(input, allow_struct).map(Expr::Let)
+ } else if input.peek(Token![if]) {
+ input.parse().map(Expr::If)
+ } else if input.peek(Token![while]) {
+ input.parse().map(Expr::While)
+ } else if input.peek(Token![for]) {
+ input.parse().map(Expr::ForLoop)
+ } else if input.peek(Token![loop]) {
+ input.parse().map(Expr::Loop)
+ } else if input.peek(Token![match]) {
+ input.parse().map(Expr::Match)
+ } else if input.peek(Token![yield]) {
+ input.parse().map(Expr::Yield)
+ } else if input.peek(Token![unsafe]) {
+ input.parse().map(Expr::Unsafe)
+ } else if input.peek(Token![const]) {
+ input.parse().map(Expr::Const)
+ } else if input.peek(token::Brace) {
+ input.parse().map(Expr::Block)
+ } else if input.peek(Token![..]) {
+ expr_range(input, allow_struct).map(Expr::Range)
+ } else if input.peek(Token![_]) {
+ input.parse().map(Expr::Infer)
+ } else if input.peek(Lifetime) {
+ atom_labeled(input)
+ } else {
+ Err(input.error("expected an expression"))
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn atom_labeled(input: ParseStream) -> Result<Expr> {
+ let the_label: Label = input.parse()?;
+ let mut expr = if input.peek(Token![while]) {
+ Expr::While(input.parse()?)
+ } else if input.peek(Token![for]) {
+ Expr::ForLoop(input.parse()?)
+ } else if input.peek(Token![loop]) {
+ Expr::Loop(input.parse()?)
+ } else if input.peek(token::Brace) {
+ Expr::Block(input.parse()?)
+ } else {
+ return Err(input.error("expected loop or block expression"));
+ };
+ match &mut expr {
+ Expr::While(ExprWhile { label, .. })
+ | Expr::ForLoop(ExprForLoop { label, .. })
+ | Expr::Loop(ExprLoop { label, .. })
+ | Expr::Block(ExprBlock { label, .. }) => *label = Some(the_label),
+ _ => unreachable!(),
+ }
+ Ok(expr)
+ }
+
+ #[cfg(not(feature = "full"))]
+ fn atom_expr(input: ParseStream) -> Result<Expr> {
+ if input.peek(token::Group) {
+ expr_group(input)
+ } else if input.peek(Lit) {
+ input.parse().map(Expr::Lit)
+ } else if input.peek(token::Paren) {
+ input.call(expr_paren).map(Expr::Paren)
+ } else if input.peek(Ident)
+ || input.peek(Token![::])
+ || input.peek(Token![<])
+ || input.peek(Token![self])
+ || input.peek(Token![Self])
+ || input.peek(Token![super])
+ || input.peek(Token![crate])
+ {
+ path_or_macro_or_struct(input)
+ } else if input.is_empty() {
+ Err(input.error("expected an expression"))
+ } else {
+ if input.peek(token::Brace) {
+ let scan = input.fork();
+ let content;
+ braced!(content in scan);
+ if content.parse::<Expr>().is_ok() && content.is_empty() {
+ let expr_block = verbatim::between(input, &scan);
+ input.advance_to(&scan);
+ return Ok(Expr::Verbatim(expr_block));
+ }
+ }
+ Err(input.error("unsupported expression; enable syn's features=[\"full\"]"))
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_builtin(input: ParseStream) -> Result<Expr> {
+ let begin = input.fork();
+
+ input.parse::<kw::builtin>()?;
+ input.parse::<Token![#]>()?;
+ input.parse::<Ident>()?;
+
+ let args;
+ parenthesized!(args in input);
+ args.parse::<TokenStream>()?;
+
+ Ok(Expr::Verbatim(verbatim::between(&begin, input)))
+ }
+
+ fn path_or_macro_or_struct(
+ input: ParseStream,
+ #[cfg(feature = "full")] allow_struct: AllowStruct,
+ ) -> Result<Expr> {
+ let (qself, path) = path::parsing::qpath(input, true)?;
+ rest_of_path_or_macro_or_struct(
+ qself,
+ path,
+ input,
+ #[cfg(feature = "full")]
+ allow_struct,
+ )
+ }
+
+ fn rest_of_path_or_macro_or_struct(
+ qself: Option<QSelf>,
+ path: Path,
+ input: ParseStream,
+ #[cfg(feature = "full")] allow_struct: AllowStruct,
+ ) -> Result<Expr> {
+ if qself.is_none()
+ && input.peek(Token![!])
+ && !input.peek(Token![!=])
+ && path.is_mod_style()
+ {
+ let bang_token: Token![!] = input.parse()?;
+ let (delimiter, tokens) = mac::parse_delimiter(input)?;
+ return Ok(Expr::Macro(ExprMacro {
+ attrs: Vec::new(),
+ mac: Macro {
+ path,
+ bang_token,
+ delimiter,
+ tokens,
+ },
+ }));
+ }
+
+ #[cfg(not(feature = "full"))]
+ let allow_struct = (true,);
+ if allow_struct.0 && input.peek(token::Brace) {
+ return expr_struct_helper(input, qself, path).map(Expr::Struct);
+ }
+
+ Ok(Expr::Path(ExprPath {
+ attrs: Vec::new(),
+ qself,
+ path,
+ }))
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprMacro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprMacro {
+ attrs: Vec::new(),
+ mac: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn paren_or_tuple(input: ParseStream) -> Result<Expr> {
+ let content;
+ let paren_token = parenthesized!(content in input);
+ if content.is_empty() {
+ return Ok(Expr::Tuple(ExprTuple {
+ attrs: Vec::new(),
+ paren_token,
+ elems: Punctuated::new(),
+ }));
+ }
+
+ let first: Expr = content.parse()?;
+ if content.is_empty() {
+ return Ok(Expr::Paren(ExprParen {
+ attrs: Vec::new(),
+ paren_token,
+ expr: Box::new(first),
+ }));
+ }
+
+ let mut elems = Punctuated::new();
+ elems.push_value(first);
+ while !content.is_empty() {
+ let punct = content.parse()?;
+ elems.push_punct(punct);
+ if content.is_empty() {
+ break;
+ }
+ let value = content.parse()?;
+ elems.push_value(value);
+ }
+ Ok(Expr::Tuple(ExprTuple {
+ attrs: Vec::new(),
+ paren_token,
+ elems,
+ }))
+ }
+
+ #[cfg(feature = "full")]
+ fn array_or_repeat(input: ParseStream) -> Result<Expr> {
+ let content;
+ let bracket_token = bracketed!(content in input);
+ if content.is_empty() {
+ return Ok(Expr::Array(ExprArray {
+ attrs: Vec::new(),
+ bracket_token,
+ elems: Punctuated::new(),
+ }));
+ }
+
+ let first: Expr = content.parse()?;
+ if content.is_empty() || content.peek(Token![,]) {
+ let mut elems = Punctuated::new();
+ elems.push_value(first);
+ while !content.is_empty() {
+ let punct = content.parse()?;
+ elems.push_punct(punct);
+ if content.is_empty() {
+ break;
+ }
+ let value = content.parse()?;
+ elems.push_value(value);
+ }
+ Ok(Expr::Array(ExprArray {
+ attrs: Vec::new(),
+ bracket_token,
+ elems,
+ }))
+ } else if content.peek(Token![;]) {
+ let semi_token: Token![;] = content.parse()?;
+ let len: Expr = content.parse()?;
+ Ok(Expr::Repeat(ExprRepeat {
+ attrs: Vec::new(),
+ bracket_token,
+ expr: Box::new(first),
+ semi_token,
+ len: Box::new(len),
+ }))
+ } else {
+ Err(content.error("expected `,` or `;`"))
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprArray {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ let bracket_token = bracketed!(content in input);
+ let mut elems = Punctuated::new();
+
+ while !content.is_empty() {
+ let first: Expr = content.parse()?;
+ elems.push_value(first);
+ if content.is_empty() {
+ break;
+ }
+ let punct = content.parse()?;
+ elems.push_punct(punct);
+ }
+
+ Ok(ExprArray {
+ attrs: Vec::new(),
+ bracket_token,
+ elems,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprRepeat {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(ExprRepeat {
+ bracket_token: bracketed!(content in input),
+ attrs: Vec::new(),
+ expr: content.parse()?,
+ semi_token: content.parse()?,
+ len: content.parse()?,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn continue_parsing_early(mut expr: &Expr) -> bool {
+ while let Expr::Group(group) = expr {
+ expr = &group.expr;
+ }
+ match expr {
+ Expr::If(_)
+ | Expr::While(_)
+ | Expr::ForLoop(_)
+ | Expr::Loop(_)
+ | Expr::Match(_)
+ | Expr::TryBlock(_)
+ | Expr::Unsafe(_)
+ | Expr::Const(_)
+ | Expr::Block(_) => false,
+ _ => true,
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprLit {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprLit {
+ attrs: Vec::new(),
+ lit: input.parse()?,
+ })
+ }
+ }
+
+ fn expr_group(
+ input: ParseStream,
+ #[cfg(feature = "full")] allow_struct: AllowStruct,
+ ) -> Result<Expr> {
+ let group = crate::group::parse_group(input)?;
+ let mut inner: Expr = group.content.parse()?;
+
+ match inner {
+ Expr::Path(mut expr) if expr.attrs.is_empty() => {
+ let grouped_len = expr.path.segments.len();
+ Path::parse_rest(input, &mut expr.path, true)?;
+ match rest_of_path_or_macro_or_struct(
+ expr.qself,
+ expr.path,
+ input,
+ #[cfg(feature = "full")]
+ allow_struct,
+ )? {
+ Expr::Path(expr) if expr.path.segments.len() == grouped_len => {
+ inner = Expr::Path(expr);
+ }
+ extended => return Ok(extended),
+ }
+ }
+ _ => {}
+ }
+
+ Ok(Expr::Group(ExprGroup {
+ attrs: Vec::new(),
+ group_token: group.token,
+ expr: Box::new(inner),
+ }))
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprParen {
+ fn parse(input: ParseStream) -> Result<Self> {
+ expr_paren(input)
+ }
+ }
+
+ fn expr_paren(input: ParseStream) -> Result<ExprParen> {
+ let content;
+ Ok(ExprParen {
+ attrs: Vec::new(),
+ paren_token: parenthesized!(content in input),
+ expr: content.parse()?,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprLet {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_struct = AllowStruct(true);
+ expr_let(input, allow_struct)
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_let(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprLet> {
+ Ok(ExprLet {
+ attrs: Vec::new(),
+ let_token: input.parse()?,
+ pat: Box::new(Pat::parse_multi_with_leading_vert(input)?),
+ eq_token: input.parse()?,
+ expr: Box::new({
+ let lhs = unary_expr(input, allow_struct)?;
+ parse_expr(input, lhs, allow_struct, Precedence::Compare)?
+ }),
+ })
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprIf {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+
+ let mut clauses = Vec::new();
+ let mut expr;
+ loop {
+ let if_token: Token![if] = input.parse()?;
+ let cond = input.call(Expr::parse_without_eager_brace)?;
+ let then_branch: Block = input.parse()?;
+
+ expr = ExprIf {
+ attrs: Vec::new(),
+ if_token,
+ cond: Box::new(cond),
+ then_branch,
+ else_branch: None,
+ };
+
+ if !input.peek(Token![else]) {
+ break;
+ }
+
+ let else_token: Token![else] = input.parse()?;
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Token![if]) {
+ expr.else_branch = Some((else_token, Box::new(Expr::PLACEHOLDER)));
+ clauses.push(expr);
+ continue;
+ } else if lookahead.peek(token::Brace) {
+ expr.else_branch = Some((
+ else_token,
+ Box::new(Expr::Block(ExprBlock {
+ attrs: Vec::new(),
+ label: None,
+ block: input.parse()?,
+ })),
+ ));
+ break;
+ } else {
+ return Err(lookahead.error());
+ }
+ }
+
+ while let Some(mut prev) = clauses.pop() {
+ *prev.else_branch.as_mut().unwrap().1 = Expr::If(expr);
+ expr = prev;
+ }
+ expr.attrs = attrs;
+ Ok(expr)
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprInfer {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprInfer {
+ attrs: input.call(Attribute::parse_outer)?,
+ underscore_token: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprForLoop {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let label: Option<Label> = input.parse()?;
+ let for_token: Token![for] = input.parse()?;
+
+ let pat = Pat::parse_multi_with_leading_vert(input)?;
+
+ let in_token: Token![in] = input.parse()?;
+ let expr: Expr = input.call(Expr::parse_without_eager_brace)?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ attr::parsing::parse_inner(&content, &mut attrs)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ExprForLoop {
+ attrs,
+ label,
+ for_token,
+ pat: Box::new(pat),
+ in_token,
+ expr: Box::new(expr),
+ body: Block { brace_token, stmts },
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprLoop {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let label: Option<Label> = input.parse()?;
+ let loop_token: Token![loop] = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ attr::parsing::parse_inner(&content, &mut attrs)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ExprLoop {
+ attrs,
+ label,
+ loop_token,
+ body: Block { brace_token, stmts },
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprMatch {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let match_token: Token![match] = input.parse()?;
+ let expr = Expr::parse_without_eager_brace(input)?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ attr::parsing::parse_inner(&content, &mut attrs)?;
+
+ let mut arms = Vec::new();
+ while !content.is_empty() {
+ arms.push(content.call(Arm::parse)?);
+ }
+
+ Ok(ExprMatch {
+ attrs,
+ match_token,
+ expr: Box::new(expr),
+ brace_token,
+ arms,
+ })
+ }
+ }
+
+ macro_rules! impl_by_parsing_expr {
+ (
+ $(
+ $expr_type:ty, $variant:ident, $msg:expr,
+ )*
+ ) => {
+ $(
+ #[cfg(all(feature = "full", feature = "printing"))]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for $expr_type {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut expr: Expr = input.parse()?;
+ loop {
+ match expr {
+ Expr::$variant(inner) => return Ok(inner),
+ Expr::Group(next) => expr = *next.expr,
+ _ => return Err(Error::new_spanned(expr, $msg)),
+ }
+ }
+ }
+ }
+ )*
+ };
+ }
+
+ impl_by_parsing_expr! {
+ ExprAssign, Assign, "expected assignment expression",
+ ExprAwait, Await, "expected await expression",
+ ExprBinary, Binary, "expected binary operation",
+ ExprCall, Call, "expected function call expression",
+ ExprCast, Cast, "expected cast expression",
+ ExprField, Field, "expected struct field access",
+ ExprIndex, Index, "expected indexing expression",
+ ExprMethodCall, MethodCall, "expected method call expression",
+ ExprRange, Range, "expected range expression",
+ ExprTry, Try, "expected try expression",
+ ExprTuple, Tuple, "expected tuple expression",
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprUnary {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = Vec::new();
+ let allow_struct = AllowStruct(true);
+ expr_unary(input, attrs, allow_struct)
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_unary(
+ input: ParseStream,
+ attrs: Vec<Attribute>,
+ allow_struct: AllowStruct,
+ ) -> Result<ExprUnary> {
+ Ok(ExprUnary {
+ attrs,
+ op: input.parse()?,
+ expr: Box::new(unary_expr(input, allow_struct)?),
+ })
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprClosure {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_struct = AllowStruct(true);
+ expr_closure(input, allow_struct)
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprReference {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_struct = AllowStruct(true);
+ Ok(ExprReference {
+ attrs: Vec::new(),
+ and_token: input.parse()?,
+ mutability: input.parse()?,
+ expr: Box::new(unary_expr(input, allow_struct)?),
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprBreak {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_struct = AllowStruct(true);
+ expr_break(input, allow_struct)
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprReturn {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprReturn {
+ attrs: Vec::new(),
+ return_token: input.parse()?,
+ expr: {
+ if can_begin_expr(input) {
+ Some(input.parse()?)
+ } else {
+ None
+ }
+ },
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprTryBlock {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprTryBlock {
+ attrs: Vec::new(),
+ try_token: input.parse()?,
+ block: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprYield {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprYield {
+ attrs: Vec::new(),
+ yield_token: input.parse()?,
+ expr: {
+ if can_begin_expr(input) {
+ Some(input.parse()?)
+ } else {
+ None
+ }
+ },
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_closure(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprClosure> {
+ let lifetimes: Option<BoundLifetimes> = input.parse()?;
+ let constness: Option<Token![const]> = input.parse()?;
+ let movability: Option<Token![static]> = input.parse()?;
+ let asyncness: Option<Token![async]> = input.parse()?;
+ let capture: Option<Token![move]> = input.parse()?;
+ let or1_token: Token![|] = input.parse()?;
+
+ let mut inputs = Punctuated::new();
+ loop {
+ if input.peek(Token![|]) {
+ break;
+ }
+ let value = closure_arg(input)?;
+ inputs.push_value(value);
+ if input.peek(Token![|]) {
+ break;
+ }
+ let punct: Token![,] = input.parse()?;
+ inputs.push_punct(punct);
+ }
+
+ let or2_token: Token![|] = input.parse()?;
+
+ let (output, body) = if input.peek(Token![->]) {
+ let arrow_token: Token![->] = input.parse()?;
+ let ty: Type = input.parse()?;
+ let body: Block = input.parse()?;
+ let output = ReturnType::Type(arrow_token, Box::new(ty));
+ let block = Expr::Block(ExprBlock {
+ attrs: Vec::new(),
+ label: None,
+ block: body,
+ });
+ (output, block)
+ } else {
+ let body = ambiguous_expr(input, allow_struct)?;
+ (ReturnType::Default, body)
+ };
+
+ Ok(ExprClosure {
+ attrs: Vec::new(),
+ lifetimes,
+ constness,
+ movability,
+ asyncness,
+ capture,
+ or1_token,
+ inputs,
+ or2_token,
+ output,
+ body: Box::new(body),
+ })
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprAsync {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprAsync {
+ attrs: Vec::new(),
+ async_token: input.parse()?,
+ capture: input.parse()?,
+ block: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn closure_arg(input: ParseStream) -> Result<Pat> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let mut pat = Pat::parse_single(input)?;
+
+ if input.peek(Token![:]) {
+ Ok(Pat::Type(PatType {
+ attrs,
+ pat: Box::new(pat),
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ }))
+ } else {
+ match &mut pat {
+ Pat::Const(pat) => pat.attrs = attrs,
+ Pat::Ident(pat) => pat.attrs = attrs,
+ Pat::Lit(pat) => pat.attrs = attrs,
+ Pat::Macro(pat) => pat.attrs = attrs,
+ Pat::Or(pat) => pat.attrs = attrs,
+ Pat::Paren(pat) => pat.attrs = attrs,
+ Pat::Path(pat) => pat.attrs = attrs,
+ Pat::Range(pat) => pat.attrs = attrs,
+ Pat::Reference(pat) => pat.attrs = attrs,
+ Pat::Rest(pat) => pat.attrs = attrs,
+ Pat::Slice(pat) => pat.attrs = attrs,
+ Pat::Struct(pat) => pat.attrs = attrs,
+ Pat::Tuple(pat) => pat.attrs = attrs,
+ Pat::TupleStruct(pat) => pat.attrs = attrs,
+ Pat::Type(_) => unreachable!(),
+ Pat::Verbatim(_) => {}
+ Pat::Wild(pat) => pat.attrs = attrs,
+ }
+ Ok(pat)
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprWhile {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let label: Option<Label> = input.parse()?;
+ let while_token: Token![while] = input.parse()?;
+ let cond = Expr::parse_without_eager_brace(input)?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ attr::parsing::parse_inner(&content, &mut attrs)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ExprWhile {
+ attrs,
+ label,
+ while_token,
+ cond: Box::new(cond),
+ body: Block { brace_token, stmts },
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprConst {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let const_token: Token![const] = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ExprConst {
+ attrs: inner_attrs,
+ const_token,
+ block: Block { brace_token, stmts },
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Label {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(Label {
+ name: input.parse()?,
+ colon_token: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Option<Label> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Lifetime) {
+ input.parse().map(Some)
+ } else {
+ Ok(None)
+ }
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprContinue {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ExprContinue {
+ attrs: Vec::new(),
+ continue_token: input.parse()?,
+ label: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_break(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprBreak> {
+ let break_token: Token![break] = input.parse()?;
+
+ let ahead = input.fork();
+ let label: Option<Lifetime> = ahead.parse()?;
+ if label.is_some() && ahead.peek(Token![:]) {
+ // Not allowed: `break 'label: loop {...}`
+ // Parentheses are required. `break ('label: loop {...})`
+ let _: Expr = input.parse()?;
+ let start_span = label.unwrap().apostrophe;
+ let end_span = input.cursor().prev_span();
+ return Err(crate::error::new2(
+ start_span,
+ end_span,
+ "parentheses required",
+ ));
+ }
+
+ input.advance_to(&ahead);
+ let expr = if can_begin_expr(input) && (allow_struct.0 || !input.peek(token::Brace)) {
+ Some(input.parse()?)
+ } else {
+ None
+ };
+
+ Ok(ExprBreak {
+ attrs: Vec::new(),
+ break_token,
+ label,
+ expr,
+ })
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for FieldValue {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let member: Member = input.parse()?;
+ let (colon_token, value) = if input.peek(Token![:]) || !member.is_named() {
+ let colon_token: Token![:] = input.parse()?;
+ let value: Expr = input.parse()?;
+ (Some(colon_token), value)
+ } else if let Member::Named(ident) = &member {
+ let value = Expr::Path(ExprPath {
+ attrs: Vec::new(),
+ qself: None,
+ path: Path::from(ident.clone()),
+ });
+ (None, value)
+ } else {
+ unreachable!()
+ };
+
+ Ok(FieldValue {
+ attrs,
+ member,
+ colon_token,
+ expr: value,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprStruct {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let (qself, path) = path::parsing::qpath(input, true)?;
+ expr_struct_helper(input, qself, path)
+ }
+ }
+
+ fn expr_struct_helper(
+ input: ParseStream,
+ qself: Option<QSelf>,
+ path: Path,
+ ) -> Result<ExprStruct> {
+ let content;
+ let brace_token = braced!(content in input);
+
+ let mut fields = Punctuated::new();
+ while !content.is_empty() {
+ if content.peek(Token![..]) {
+ return Ok(ExprStruct {
+ attrs: Vec::new(),
+ qself,
+ path,
+ brace_token,
+ fields,
+ dot2_token: Some(content.parse()?),
+ rest: if content.is_empty() {
+ None
+ } else {
+ Some(Box::new(content.parse()?))
+ },
+ });
+ }
+
+ fields.push(content.parse()?);
+ if content.is_empty() {
+ break;
+ }
+ let punct: Token![,] = content.parse()?;
+ fields.push_punct(punct);
+ }
+
+ Ok(ExprStruct {
+ attrs: Vec::new(),
+ qself,
+ path,
+ brace_token,
+ fields,
+ dot2_token: None,
+ rest: None,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprUnsafe {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let unsafe_token: Token![unsafe] = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ let inner_attrs = content.call(Attribute::parse_inner)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ExprUnsafe {
+ attrs: inner_attrs,
+ unsafe_token,
+ block: Block { brace_token, stmts },
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprBlock {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let label: Option<Label> = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ attr::parsing::parse_inner(&content, &mut attrs)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ExprBlock {
+ attrs,
+ label,
+ block: Block { brace_token, stmts },
+ })
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn expr_range(input: ParseStream, allow_struct: AllowStruct) -> Result<ExprRange> {
+ let limits: RangeLimits = input.parse()?;
+ let end = parse_range_end(input, &limits, allow_struct)?;
+ Ok(ExprRange {
+ attrs: Vec::new(),
+ start: None,
+ limits,
+ end,
+ })
+ }
+
+ #[cfg(feature = "full")]
+ fn parse_range_end(
+ input: ParseStream,
+ limits: &RangeLimits,
+ allow_struct: AllowStruct,
+ ) -> Result<Option<Box<Expr>>> {
+ if matches!(limits, RangeLimits::HalfOpen(_))
+ && (input.is_empty()
+ || input.peek(Token![,])
+ || input.peek(Token![;])
+ || input.peek(Token![.]) && !input.peek(Token![..])
+ || !allow_struct.0 && input.peek(token::Brace))
+ {
+ Ok(None)
+ } else {
+ let end = parse_binop_rhs(input, allow_struct, Precedence::Range)?;
+ Ok(Some(end))
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for RangeLimits {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let lookahead = input.lookahead1();
+ let dot_dot = lookahead.peek(Token![..]);
+ let dot_dot_eq = dot_dot && lookahead.peek(Token![..=]);
+ let dot_dot_dot = dot_dot && input.peek(Token![...]);
+ if dot_dot_eq {
+ input.parse().map(RangeLimits::Closed)
+ } else if dot_dot && !dot_dot_dot {
+ input.parse().map(RangeLimits::HalfOpen)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
+
+ #[cfg(feature = "full")]
+ impl RangeLimits {
+ pub(crate) fn parse_obsolete(input: ParseStream) -> Result<Self> {
+ let lookahead = input.lookahead1();
+ let dot_dot = lookahead.peek(Token![..]);
+ let dot_dot_eq = dot_dot && lookahead.peek(Token![..=]);
+ let dot_dot_dot = dot_dot && input.peek(Token![...]);
+ if dot_dot_eq {
+ input.parse().map(RangeLimits::Closed)
+ } else if dot_dot_dot {
+ let dot3: Token![...] = input.parse()?;
+ Ok(RangeLimits::Closed(Token))
+ } else if dot_dot {
+ input.parse().map(RangeLimits::HalfOpen)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ExprPath {
+ fn parse(input: ParseStream) -> Result<Self> {
+ #[cfg(not(feature = "full"))]
+ let attrs = Vec::new();
+ #[cfg(feature = "full")]
+ let attrs = input.call(Attribute::parse_outer)?;
+
+ let (qself, path) = path::parsing::qpath(input, true)?;
+
+ Ok(ExprPath { attrs, qself, path })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Member {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Ident) {
+ input.parse().map(Member::Named)
+ } else if input.peek(LitInt) {
+ input.parse().map(Member::Unnamed)
+ } else {
+ Err(input.error("expected identifier or integer"))
+ }
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Arm {
+ fn parse(input: ParseStream) -> Result<Arm> {
+ let requires_comma;
+ Ok(Arm {
+ attrs: input.call(Attribute::parse_outer)?,
+ pat: Pat::parse_multi_with_leading_vert(input)?,
+ guard: {
+ if input.peek(Token![if]) {
+ let if_token: Token![if] = input.parse()?;
+ let guard: Expr = input.parse()?;
+ Some((if_token, Box::new(guard)))
+ } else {
+ None
+ }
+ },
+ fat_arrow_token: input.parse()?,
+ body: {
+ let body = Expr::parse_with_earlier_boundary_rule(input)?;
+ requires_comma = classify::requires_comma_to_be_match_arm(&body);
+ Box::new(body)
+ },
+ comma: {
+ if requires_comma && !input.is_empty() {
+ Some(input.parse()?)
+ } else {
+ input.parse()?
+ }
+ },
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Index {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let lit: LitInt = input.parse()?;
+ if lit.suffix().is_empty() {
+ Ok(Index {
+ index: lit
+ .base10_digits()
+ .parse()
+ .map_err(|err| Error::new(lit.span(), err))?,
+ span: lit.span(),
+ })
+ } else {
+ Err(Error::new(lit.span(), "expected unsuffixed integer"))
+ }
+ }
+ }
+
+ fn multi_index(e: &mut Expr, dot_token: &mut Token![.], float: LitFloat) -> Result<bool> {
+ let float_token = float.token();
+ let float_span = float_token.span();
+ let mut float_repr = float_token.to_string();
+ let trailing_dot = float_repr.ends_with('.');
+ if trailing_dot {
+ float_repr.truncate(float_repr.len() - 1);
+ }
+
+ let mut offset = 0;
+ for part in float_repr.split('.') {
+ let mut index: Index =
+ crate::parse_str(part).map_err(|err| Error::new(float_span, err))?;
+ let part_end = offset + part.len();
+ index.span = float_token.subspan(offset..part_end).unwrap_or(float_span);
+
+ let base = mem::replace(e, Expr::PLACEHOLDER);
+ *e = Expr::Field(ExprField {
+ attrs: Vec::new(),
+ base: Box::new(base),
+ dot_token: Token,
+ member: Member::Unnamed(index),
+ });
+
+ let dot_span = float_token
+ .subspan(part_end..part_end + 1)
+ .unwrap_or(float_span);
+ *dot_token = Token;
+ offset = part_end + 1;
+ }
+
+ Ok(!trailing_dot)
+ }
+
+ impl Member {
+ pub(crate) fn is_named(&self) -> bool {
+ match self {
+ Member::Named(_) => true,
+ Member::Unnamed(_) => false,
+ }
+ }
+ }
+
+ fn check_cast(input: ParseStream) -> Result<()> {
+ let kind = if input.peek(Token![.]) && !input.peek(Token![..]) {
+ if input.peek2(Token![await]) {
+ "`.await`"
+ } else if input.peek2(Ident) && (input.peek3(token::Paren) || input.peek3(Token![::])) {
+ "a method call"
+ } else {
+ "a field access"
+ }
+ } else if input.peek(Token![?]) {
+ "`?`"
+ } else if input.peek(token::Bracket) {
+ "indexing"
+ } else if input.peek(token::Paren) {
+ "a function call"
+ } else {
+ return Ok(());
+ };
+ let msg = format!("casts cannot be followed by {}", kind);
+ Err(input.error(msg))
+ }
+}
+
+#[cfg(feature = "printing")]
+pub(crate) mod printing {
+ use crate::attr::Attribute;
+ #[cfg(feature = "full")]
+ use crate::attr::FilterAttrs;
+ use crate::classify;
+ #[cfg(feature = "full")]
+ use crate::expr::{
+ Arm, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure,
+ ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch,
+ ExprRange, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprTuple, ExprUnsafe, ExprWhile,
+ ExprYield, Label, RangeLimits,
+ };
+ use crate::expr::{
+ Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprGroup, ExprIndex, ExprLit, ExprMacro,
+ ExprMethodCall, ExprParen, ExprPath, ExprReference, ExprStruct, ExprUnary, FieldValue,
+ Index, Member,
+ };
+ #[cfg(feature = "full")]
+ use crate::fixup::FixupContext;
+ use crate::op::BinOp;
+ use crate::path;
+ use crate::precedence::Precedence;
+ use crate::token;
+ #[cfg(feature = "full")]
+ use crate::ty::ReturnType;
+ use proc_macro2::{Literal, Span, TokenStream};
+ use quote::{ToTokens, TokenStreamExt};
+
+ #[cfg(feature = "full")]
+ pub(crate) fn outer_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
+ tokens.append_all(attrs.outer());
+ }
+
+ #[cfg(feature = "full")]
+ fn inner_attrs_to_tokens(attrs: &[Attribute], tokens: &mut TokenStream) {
+ tokens.append_all(attrs.inner());
+ }
+
+ #[cfg(not(feature = "full"))]
+ pub(crate) fn outer_attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut TokenStream) {}
+
+ #[cfg(feature = "full")]
+ fn print_condition(expr: &Expr, tokens: &mut TokenStream) {
+ print_subexpression(
+ expr,
+ classify::confusable_with_adjacent_block(expr),
+ tokens,
+ FixupContext::new_condition(),
+ );
+ }
+
+ fn print_subexpression(
+ expr: &Expr,
+ needs_group: bool,
+ tokens: &mut TokenStream,
+ #[cfg(feature = "full")] mut fixup: FixupContext,
+ ) {
+ #[cfg(not(feature = "full"))]
+ let do_print_expr = |tokens: &mut TokenStream| expr.to_tokens(tokens);
+
+ #[cfg(feature = "full")]
+ let do_print_expr = {
+ // If we are surrounding the whole cond in parentheses, such as:
+ //
+ // if (return Struct {}) {}
+ //
+ // then there is no need for parenthesizing the individual struct
+ // expressions within. On the other hand if the whole cond is not
+ // parenthesized, then print_expr must parenthesize exterior struct
+ // literals.
+ //
+ // if x == (Struct {}) {}
+ //
+ if needs_group {
+ fixup = FixupContext::NONE;
+ }
+ |tokens: &mut TokenStream| print_expr(expr, tokens, fixup)
+ };
+
+ if needs_group {
+ token::Paren::default().surround(tokens, do_print_expr);
+ } else {
+ do_print_expr(tokens);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ pub(crate) fn print_expr(expr: &Expr, tokens: &mut TokenStream, mut fixup: FixupContext) {
+ let needs_group = fixup.would_cause_statement_boundary(expr);
+ if needs_group {
+ fixup = FixupContext::NONE;
+ }
+
+ let do_print_expr = |tokens: &mut TokenStream| match expr {
+ Expr::Array(e) => e.to_tokens(tokens),
+ Expr::Assign(e) => print_expr_assign(e, tokens, fixup),
+ Expr::Async(e) => e.to_tokens(tokens),
+ Expr::Await(e) => print_expr_await(e, tokens, fixup),
+ Expr::Binary(e) => print_expr_binary(e, tokens, fixup),
+ Expr::Block(e) => e.to_tokens(tokens),
+ Expr::Break(e) => print_expr_break(e, tokens, fixup),
+ Expr::Call(e) => print_expr_call(e, tokens, fixup),
+ Expr::Cast(e) => print_expr_cast(e, tokens, fixup),
+ Expr::Closure(e) => e.to_tokens(tokens),
+ Expr::Const(e) => e.to_tokens(tokens),
+ Expr::Continue(e) => e.to_tokens(tokens),
+ Expr::Field(e) => print_expr_field(e, tokens, fixup),
+ Expr::ForLoop(e) => e.to_tokens(tokens),
+ Expr::Group(e) => e.to_tokens(tokens),
+ Expr::If(e) => e.to_tokens(tokens),
+ Expr::Index(e) => print_expr_index(e, tokens, fixup),
+ Expr::Infer(e) => e.to_tokens(tokens),
+ Expr::Let(e) => print_expr_let(e, tokens, fixup),
+ Expr::Lit(e) => e.to_tokens(tokens),
+ Expr::Loop(e) => e.to_tokens(tokens),
+ Expr::Macro(e) => e.to_tokens(tokens),
+ Expr::Match(e) => e.to_tokens(tokens),
+ Expr::MethodCall(e) => print_expr_method_call(e, tokens, fixup),
+ Expr::Paren(e) => e.to_tokens(tokens),
+ Expr::Path(e) => e.to_tokens(tokens),
+ Expr::Range(e) => print_expr_range(e, tokens, fixup),
+ Expr::Reference(e) => print_expr_reference(e, tokens, fixup),
+ Expr::Repeat(e) => e.to_tokens(tokens),
+ Expr::Return(e) => print_expr_return(e, tokens, fixup),
+ Expr::Struct(e) => e.to_tokens(tokens),
+ Expr::Try(e) => print_expr_try(e, tokens, fixup),
+ Expr::TryBlock(e) => e.to_tokens(tokens),
+ Expr::Tuple(e) => e.to_tokens(tokens),
+ Expr::Unary(e) => print_expr_unary(e, tokens, fixup),
+ Expr::Unsafe(e) => e.to_tokens(tokens),
+ Expr::Verbatim(e) => e.to_tokens(tokens),
+ Expr::While(e) => e.to_tokens(tokens),
+ Expr::Yield(e) => print_expr_yield(e, tokens, fixup),
+ };
+
+ if needs_group {
+ token::Paren::default().surround(tokens, do_print_expr);
+ } else {
+ do_print_expr(tokens);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprArray {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.bracket_token.surround(tokens, |tokens| {
+ self.elems.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprAssign {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_assign(self, tokens, FixupContext::NONE);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn print_expr_assign(e: &ExprAssign, tokens: &mut TokenStream, fixup: FixupContext) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ print_subexpression(
+ &e.left,
+ Precedence::of(&e.left) <= Precedence::Assign,
+ tokens,
+ fixup.leftmost_subexpression(),
+ );
+ e.eq_token.to_tokens(tokens);
+ print_subexpression(
+ &e.right,
+ Precedence::of_rhs(&e.right) < Precedence::Assign,
+ tokens,
+ fixup.subsequent_subexpression(),
+ );
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprAsync {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.async_token.to_tokens(tokens);
+ self.capture.to_tokens(tokens);
+ self.block.to_tokens(tokens);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprAwait {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_await(self, tokens, FixupContext::NONE);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn print_expr_await(e: &ExprAwait, tokens: &mut TokenStream, fixup: FixupContext) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ print_subexpression(
+ &e.base,
+ Precedence::of(&e.base) < Precedence::Postfix,
+ tokens,
+ fixup.leftmost_subexpression_with_dot(),
+ );
+ e.dot_token.to_tokens(tokens);
+ e.await_token.to_tokens(tokens);
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprBinary {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_binary(
+ self,
+ tokens,
+ #[cfg(feature = "full")]
+ FixupContext::NONE,
+ );
+ }
+ }
+
+ fn print_expr_binary(
+ e: &ExprBinary,
+ tokens: &mut TokenStream,
+ #[cfg(feature = "full")] fixup: FixupContext,
+ ) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+
+ let binop_prec = Precedence::of_binop(&e.op);
+ let left_prec = Precedence::of(&e.left);
+ let right_prec = Precedence::of_rhs(&e.right);
+ let (mut left_needs_group, right_needs_group) = if let Precedence::Assign = binop_prec {
+ (left_prec <= binop_prec, right_prec < binop_prec)
+ } else {
+ (left_prec < binop_prec, right_prec <= binop_prec)
+ };
+
+ // These cases require parenthesization independently of precedence.
+ match (&*e.left, &e.op) {
+ // `x as i32 < y` has the parser thinking that `i32 < y` is the
+ // beginning of a path type. It starts trying to parse `x as (i32 <
+ // y ...` instead of `(x as i32) < ...`. We need to convince it
+ // _not_ to do that.
+ (_, BinOp::Lt(_) | BinOp::Shl(_)) if classify::confusable_with_adjacent_lt(&e.left) => {
+ left_needs_group = true;
+ }
+
+ // We are given `(let _ = a) OP b`.
+ //
+ // - When `OP <= LAnd` we should print `let _ = a OP b` to avoid
+ // redundant parens as the parser will interpret this as `(let _ =
+ // a) OP b`.
+ //
+ // - Otherwise, e.g. when we have `(let a = b) < c` in AST, parens
+ // are required since the parser would interpret `let a = b < c`
+ // as `let a = (b < c)`. To achieve this, we force parens.
+ #[cfg(feature = "full")]
+ (Expr::Let(_), _) if binop_prec > Precedence::And => {
+ left_needs_group = true;
+ }
+
+ _ => {}
+ }
+
+ print_subexpression(
+ &e.left,
+ left_needs_group,
+ tokens,
+ #[cfg(feature = "full")]
+ fixup.leftmost_subexpression(),
+ );
+ e.op.to_tokens(tokens);
+ print_subexpression(
+ &e.right,
+ right_needs_group,
+ tokens,
+ #[cfg(feature = "full")]
+ fixup.subsequent_subexpression(),
+ );
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprBlock {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.label.to_tokens(tokens);
+ self.block.brace_token.surround(tokens, |tokens| {
+ inner_attrs_to_tokens(&self.attrs, tokens);
+ tokens.append_all(&self.block.stmts);
+ });
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprBreak {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_break(self, tokens, FixupContext::NONE);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn print_expr_break(e: &ExprBreak, tokens: &mut TokenStream, fixup: FixupContext) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ e.break_token.to_tokens(tokens);
+ e.label.to_tokens(tokens);
+ if let Some(expr) = &e.expr {
+ print_expr(expr, tokens, fixup.subsequent_subexpression());
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprCall {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_call(
+ self,
+ tokens,
+ #[cfg(feature = "full")]
+ FixupContext::NONE,
+ );
+ }
+ }
+
+ fn print_expr_call(
+ e: &ExprCall,
+ tokens: &mut TokenStream,
+ #[cfg(feature = "full")] fixup: FixupContext,
+ ) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+
+ let precedence = if let Expr::Field(_) = &*e.func {
+ Precedence::Any
+ } else {
+ Precedence::Postfix
+ };
+ print_subexpression(
+ &e.func,
+ Precedence::of(&e.func) < precedence,
+ tokens,
+ #[cfg(feature = "full")]
+ fixup.leftmost_subexpression(),
+ );
+
+ e.paren_token.surround(tokens, |tokens| {
+ e.args.to_tokens(tokens);
+ });
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprCast {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_cast(
+ self,
+ tokens,
+ #[cfg(feature = "full")]
+ FixupContext::NONE,
+ );
+ }
+ }
+
+ fn print_expr_cast(
+ e: &ExprCast,
+ tokens: &mut TokenStream,
+ #[cfg(feature = "full")] fixup: FixupContext,
+ ) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ print_subexpression(
+ &e.expr,
+ Precedence::of(&e.expr) < Precedence::Cast,
+ tokens,
+ #[cfg(feature = "full")]
+ fixup.leftmost_subexpression(),
+ );
+ e.as_token.to_tokens(tokens);
+ e.ty.to_tokens(tokens);
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprClosure {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.lifetimes.to_tokens(tokens);
+ self.constness.to_tokens(tokens);
+ self.movability.to_tokens(tokens);
+ self.asyncness.to_tokens(tokens);
+ self.capture.to_tokens(tokens);
+ self.or1_token.to_tokens(tokens);
+ self.inputs.to_tokens(tokens);
+ self.or2_token.to_tokens(tokens);
+ self.output.to_tokens(tokens);
+ if matches!(self.output, ReturnType::Default) || matches!(*self.body, Expr::Block(_)) {
+ self.body.to_tokens(tokens);
+ } else {
+ token::Brace::default().surround(tokens, |tokens| {
+ print_expr(&self.body, tokens, FixupContext::new_stmt());
+ });
+ }
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprConst {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.const_token.to_tokens(tokens);
+ self.block.brace_token.surround(tokens, |tokens| {
+ inner_attrs_to_tokens(&self.attrs, tokens);
+ tokens.append_all(&self.block.stmts);
+ });
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprContinue {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.continue_token.to_tokens(tokens);
+ self.label.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprField {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_field(
+ self,
+ tokens,
+ #[cfg(feature = "full")]
+ FixupContext::NONE,
+ );
+ }
+ }
+
+ fn print_expr_field(
+ e: &ExprField,
+ tokens: &mut TokenStream,
+ #[cfg(feature = "full")] fixup: FixupContext,
+ ) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ print_subexpression(
+ &e.base,
+ Precedence::of(&e.base) < Precedence::Postfix,
+ tokens,
+ #[cfg(feature = "full")]
+ fixup.leftmost_subexpression_with_dot(),
+ );
+ e.dot_token.to_tokens(tokens);
+ e.member.to_tokens(tokens);
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprForLoop {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.label.to_tokens(tokens);
+ self.for_token.to_tokens(tokens);
+ self.pat.to_tokens(tokens);
+ self.in_token.to_tokens(tokens);
+ print_condition(&self.expr, tokens);
+ self.body.brace_token.surround(tokens, |tokens| {
+ inner_attrs_to_tokens(&self.attrs, tokens);
+ tokens.append_all(&self.body.stmts);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprGroup {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.group_token.surround(tokens, |tokens| {
+ self.expr.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprIf {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+
+ let mut expr = self;
+ loop {
+ expr.if_token.to_tokens(tokens);
+ print_condition(&expr.cond, tokens);
+ expr.then_branch.to_tokens(tokens);
+
+ let (else_token, else_) = match &expr.else_branch {
+ Some(else_branch) => else_branch,
+ None => break,
+ };
+
+ else_token.to_tokens(tokens);
+ match &**else_ {
+ Expr::If(next) => {
+ expr = next;
+ }
+ Expr::Block(last) => {
+ last.to_tokens(tokens);
+ break;
+ }
+ // If this is not one of the valid expressions to exist in
+ // an else clause, wrap it in a block.
+ other => {
+ token::Brace::default().surround(tokens, |tokens| {
+ print_expr(other, tokens, FixupContext::new_stmt());
+ });
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprIndex {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_index(
+ self,
+ tokens,
+ #[cfg(feature = "full")]
+ FixupContext::NONE,
+ );
+ }
+ }
+
+ fn print_expr_index(
+ e: &ExprIndex,
+ tokens: &mut TokenStream,
+ #[cfg(feature = "full")] fixup: FixupContext,
+ ) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ print_subexpression(
+ &e.expr,
+ Precedence::of(&e.expr) < Precedence::Postfix,
+ tokens,
+ #[cfg(feature = "full")]
+ fixup.leftmost_subexpression(),
+ );
+ e.bracket_token.surround(tokens, |tokens| {
+ e.index.to_tokens(tokens);
+ });
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprInfer {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.underscore_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprLet {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_let(self, tokens, FixupContext::NONE);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn print_expr_let(e: &ExprLet, tokens: &mut TokenStream, fixup: FixupContext) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ e.let_token.to_tokens(tokens);
+ e.pat.to_tokens(tokens);
+ e.eq_token.to_tokens(tokens);
+ print_subexpression(
+ &e.expr,
+ fixup.needs_group_as_let_scrutinee(&e.expr),
+ tokens,
+ FixupContext::NONE,
+ );
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprLit {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.lit.to_tokens(tokens);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprLoop {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.label.to_tokens(tokens);
+ self.loop_token.to_tokens(tokens);
+ self.body.brace_token.surround(tokens, |tokens| {
+ inner_attrs_to_tokens(&self.attrs, tokens);
+ tokens.append_all(&self.body.stmts);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprMacro {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.mac.to_tokens(tokens);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprMatch {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.match_token.to_tokens(tokens);
+ print_condition(&self.expr, tokens);
+ self.brace_token.surround(tokens, |tokens| {
+ inner_attrs_to_tokens(&self.attrs, tokens);
+ for (i, arm) in self.arms.iter().enumerate() {
+ arm.to_tokens(tokens);
+ // Ensure that we have a comma after a non-block arm, except
+ // for the last one.
+ let is_last = i == self.arms.len() - 1;
+ if !is_last
+ && classify::requires_comma_to_be_match_arm(&arm.body)
+ && arm.comma.is_none()
+ {
+ <Token![,]>::default().to_tokens(tokens);
+ }
+ }
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprMethodCall {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_method_call(
+ self,
+ tokens,
+ #[cfg(feature = "full")]
+ FixupContext::NONE,
+ );
+ }
+ }
+
+ fn print_expr_method_call(
+ e: &ExprMethodCall,
+ tokens: &mut TokenStream,
+ #[cfg(feature = "full")] fixup: FixupContext,
+ ) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ print_subexpression(
+ &e.receiver,
+ Precedence::of(&e.receiver) < Precedence::Postfix,
+ tokens,
+ #[cfg(feature = "full")]
+ fixup.leftmost_subexpression_with_dot(),
+ );
+ e.dot_token.to_tokens(tokens);
+ e.method.to_tokens(tokens);
+ e.turbofish.to_tokens(tokens);
+ e.paren_token.surround(tokens, |tokens| {
+ e.args.to_tokens(tokens);
+ });
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprParen {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.paren_token.surround(tokens, |tokens| {
+ self.expr.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprPath {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ path::printing::print_path(tokens, &self.qself, &self.path);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprRange {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_range(self, tokens, FixupContext::NONE);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn print_expr_range(e: &ExprRange, tokens: &mut TokenStream, fixup: FixupContext) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ if let Some(start) = &e.start {
+ print_subexpression(
+ start,
+ Precedence::of(start) <= Precedence::Range,
+ tokens,
+ fixup.leftmost_subexpression(),
+ );
+ }
+ e.limits.to_tokens(tokens);
+ if let Some(end) = &e.end {
+ print_subexpression(
+ end,
+ Precedence::of_rhs(end) <= Precedence::Range,
+ tokens,
+ fixup.subsequent_subexpression(),
+ );
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprReference {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_reference(
+ self,
+ tokens,
+ #[cfg(feature = "full")]
+ FixupContext::NONE,
+ );
+ }
+ }
+
+ fn print_expr_reference(
+ e: &ExprReference,
+ tokens: &mut TokenStream,
+ #[cfg(feature = "full")] fixup: FixupContext,
+ ) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ e.and_token.to_tokens(tokens);
+ e.mutability.to_tokens(tokens);
+ print_subexpression(
+ &e.expr,
+ Precedence::of_rhs(&e.expr) < Precedence::Prefix,
+ tokens,
+ #[cfg(feature = "full")]
+ fixup.subsequent_subexpression(),
+ );
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprRepeat {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.bracket_token.surround(tokens, |tokens| {
+ self.expr.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ self.len.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprReturn {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_return(self, tokens, FixupContext::NONE);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn print_expr_return(e: &ExprReturn, tokens: &mut TokenStream, fixup: FixupContext) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ e.return_token.to_tokens(tokens);
+ if let Some(expr) = &e.expr {
+ print_expr(expr, tokens, fixup.subsequent_subexpression());
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprStruct {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ path::printing::print_path(tokens, &self.qself, &self.path);
+ self.brace_token.surround(tokens, |tokens| {
+ self.fields.to_tokens(tokens);
+ if let Some(dot2_token) = &self.dot2_token {
+ dot2_token.to_tokens(tokens);
+ } else if self.rest.is_some() {
+ Token).to_tokens(tokens);
+ }
+ self.rest.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprTry {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_try(self, tokens, FixupContext::NONE);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn print_expr_try(e: &ExprTry, tokens: &mut TokenStream, fixup: FixupContext) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ print_subexpression(
+ &e.expr,
+ Precedence::of(&e.expr) < Precedence::Postfix,
+ tokens,
+ fixup.leftmost_subexpression_with_dot(),
+ );
+ e.question_token.to_tokens(tokens);
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprTryBlock {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.try_token.to_tokens(tokens);
+ self.block.to_tokens(tokens);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprTuple {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.paren_token.surround(tokens, |tokens| {
+ self.elems.to_tokens(tokens);
+ // If we only have one argument, we need a trailing comma to
+ // distinguish ExprTuple from ExprParen.
+ if self.elems.len() == 1 && !self.elems.trailing_punct() {
+ <Token![,]>::default().to_tokens(tokens);
+ }
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprUnary {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_unary(
+ self,
+ tokens,
+ #[cfg(feature = "full")]
+ FixupContext::NONE,
+ );
+ }
+ }
+
+ fn print_expr_unary(
+ e: &ExprUnary,
+ tokens: &mut TokenStream,
+ #[cfg(feature = "full")] fixup: FixupContext,
+ ) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ e.op.to_tokens(tokens);
+ print_subexpression(
+ &e.expr,
+ Precedence::of_rhs(&e.expr) < Precedence::Prefix,
+ tokens,
+ #[cfg(feature = "full")]
+ fixup.subsequent_subexpression(),
+ );
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprUnsafe {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.unsafe_token.to_tokens(tokens);
+ self.block.brace_token.surround(tokens, |tokens| {
+ inner_attrs_to_tokens(&self.attrs, tokens);
+ tokens.append_all(&self.block.stmts);
+ });
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprWhile {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.label.to_tokens(tokens);
+ self.while_token.to_tokens(tokens);
+ print_condition(&self.cond, tokens);
+ self.body.brace_token.surround(tokens, |tokens| {
+ inner_attrs_to_tokens(&self.attrs, tokens);
+ tokens.append_all(&self.body.stmts);
+ });
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ExprYield {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ print_expr_yield(self, tokens, FixupContext::NONE);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ fn print_expr_yield(e: &ExprYield, tokens: &mut TokenStream, fixup: FixupContext) {
+ outer_attrs_to_tokens(&e.attrs, tokens);
+ e.yield_token.to_tokens(tokens);
+ if let Some(expr) = &e.expr {
+ print_expr(expr, tokens, fixup.subsequent_subexpression());
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Arm {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(&self.attrs);
+ self.pat.to_tokens(tokens);
+ if let Some((if_token, guard)) = &self.guard {
+ if_token.to_tokens(tokens);
+ guard.to_tokens(tokens);
+ }
+ self.fat_arrow_token.to_tokens(tokens);
+ print_expr(&self.body, tokens, FixupContext::new_match_arm());
+ self.comma.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for FieldValue {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ outer_attrs_to_tokens(&self.attrs, tokens);
+ self.member.to_tokens(tokens);
+ if let Some(colon_token) = &self.colon_token {
+ colon_token.to_tokens(tokens);
+ self.expr.to_tokens(tokens);
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Index {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let mut lit = Literal::i64_unsuffixed(i64::from(self.index));
+ lit.set_span(self.span);
+ tokens.append(lit);
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Label {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.name.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Member {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ Member::Named(ident) => ident.to_tokens(tokens),
+ Member::Unnamed(index) => index.to_tokens(tokens),
+ }
+ }
+ }
+
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for RangeLimits {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ RangeLimits::HalfOpen(t) => t.to_tokens(tokens),
+ RangeLimits::Closed(t) => t.to_tokens(tokens),
+ }
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/ext.rs b/rust/hw/char/pl011/vendor/syn/src/ext.rs
new file mode 100644
index 0000000000..5cd79e863a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/ext.rs
@@ -0,0 +1,136 @@
+//! Extension traits to provide parsing methods on foreign types.
+
+use crate::buffer::Cursor;
+use crate::error::Result;
+use crate::parse::ParseStream;
+use crate::parse::Peek;
+use crate::sealed::lookahead;
+use crate::token::CustomToken;
+use proc_macro2::Ident;
+
+/// Additional methods for `Ident` not provided by proc-macro2 or libproc_macro.
+///
+/// This trait is sealed and cannot be implemented for types outside of Syn. It
+/// is implemented only for `proc_macro2::Ident`.
+pub trait IdentExt: Sized + private::Sealed {
+ /// Parses any identifier including keywords.
+ ///
+ /// This is useful when parsing macro input which allows Rust keywords as
+ /// identifiers.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use syn::{Error, Ident, Result, Token};
+ /// use syn::ext::IdentExt;
+ /// use syn::parse::ParseStream;
+ ///
+ /// mod kw {
+ /// syn::custom_keyword!(name);
+ /// }
+ ///
+ /// // Parses input that looks like `name = NAME` where `NAME` can be
+ /// // any identifier.
+ /// //
+ /// // Examples:
+ /// //
+ /// // name = anything
+ /// // name = impl
+ /// fn parse_dsl(input: ParseStream) -> Result<Ident> {
+ /// input.parse::<kw::name>()?;
+ /// input.parse::<Token![=]>()?;
+ /// let name = input.call(Ident::parse_any)?;
+ /// Ok(name)
+ /// }
+ /// ```
+ fn parse_any(input: ParseStream) -> Result<Self>;
+
+ /// Peeks any identifier including keywords. Usage:
+ /// `input.peek(Ident::peek_any)`
+ ///
+ /// This is different from `input.peek(Ident)` which only returns true in
+ /// the case of an ident which is not a Rust keyword.
+ #[allow(non_upper_case_globals)]
+ const peek_any: private::PeekFn = private::PeekFn;
+
+ /// Strips the raw marker `r#`, if any, from the beginning of an ident.
+ ///
+ /// - unraw(`x`) = `x`
+ /// - unraw(`move`) = `move`
+ /// - unraw(`r#move`) = `move`
+ ///
+ /// # Example
+ ///
+ /// In the case of interop with other languages like Python that have a
+ /// different set of keywords than Rust, we might come across macro input
+ /// that involves raw identifiers to refer to ordinary variables in the
+ /// other language with a name that happens to be a Rust keyword.
+ ///
+ /// The function below appends an identifier from the caller's input onto a
+ /// fixed prefix. Without using `unraw()`, this would tend to produce
+ /// invalid identifiers like `__pyo3_get_r#move`.
+ ///
+ /// ```
+ /// use proc_macro2::Span;
+ /// use syn::Ident;
+ /// use syn::ext::IdentExt;
+ ///
+ /// fn ident_for_getter(variable: &Ident) -> Ident {
+ /// let getter = format!("__pyo3_get_{}", variable.unraw());
+ /// Ident::new(&getter, Span::call_site())
+ /// }
+ /// ```
+ fn unraw(&self) -> Ident;
+}
+
+impl IdentExt for Ident {
+ fn parse_any(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| match cursor.ident() {
+ Some((ident, rest)) => Ok((ident, rest)),
+ None => Err(cursor.error("expected ident")),
+ })
+ }
+
+ fn unraw(&self) -> Ident {
+ let string = self.to_string();
+ if let Some(string) = string.strip_prefix("r#") {
+ Ident::new(string, self.span())
+ } else {
+ self.clone()
+ }
+ }
+}
+
+impl Peek for private::PeekFn {
+ type Token = private::IdentAny;
+}
+
+impl CustomToken for private::IdentAny {
+ fn peek(cursor: Cursor) -> bool {
+ cursor.ident().is_some()
+ }
+
+ fn display() -> &'static str {
+ "identifier"
+ }
+}
+
+impl lookahead::Sealed for private::PeekFn {}
+
+mod private {
+ use proc_macro2::Ident;
+
+ pub trait Sealed {}
+
+ impl Sealed for Ident {}
+
+ pub struct PeekFn;
+ pub struct IdentAny;
+
+ impl Copy for PeekFn {}
+ impl Clone for PeekFn {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/file.rs b/rust/hw/char/pl011/vendor/syn/src/file.rs
new file mode 100644
index 0000000000..681125e137
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/file.rs
@@ -0,0 +1,130 @@
+use crate::attr::Attribute;
+use crate::item::Item;
+
+ast_struct! {
+ /// A complete file of Rust source code.
+ ///
+ /// Typically `File` objects are created with [`parse_file`].
+ ///
+ /// [`parse_file`]: crate::parse_file
+ ///
+ /// # Example
+ ///
+ /// Parse a Rust source file into a `syn::File` and print out a debug
+ /// representation of the syntax tree.
+ ///
+ /// ```
+ /// use std::env;
+ /// use std::fs::File;
+ /// use std::io::Read;
+ /// use std::process;
+ ///
+ /// fn main() {
+ /// # }
+ /// #
+ /// # fn fake_main() {
+ /// let mut args = env::args();
+ /// let _ = args.next(); // executable name
+ ///
+ /// let filename = match (args.next(), args.next()) {
+ /// (Some(filename), None) => filename,
+ /// _ => {
+ /// eprintln!("Usage: dump-syntax path/to/filename.rs");
+ /// process::exit(1);
+ /// }
+ /// };
+ ///
+ /// let mut file = File::open(&filename).expect("unable to open file");
+ ///
+ /// let mut src = String::new();
+ /// file.read_to_string(&mut src).expect("unable to read file");
+ ///
+ /// let syntax = syn::parse_file(&src).expect("unable to parse file");
+ ///
+ /// // Debug impl is available if Syn is built with "extra-traits" feature.
+ /// println!("{:#?}", syntax);
+ /// }
+ /// ```
+ ///
+ /// Running with its own source code as input, this program prints output
+ /// that begins with:
+ ///
+ /// ```text
+ /// File {
+ /// shebang: None,
+ /// attrs: [],
+ /// items: [
+ /// Use(
+ /// ItemUse {
+ /// attrs: [],
+ /// vis: Inherited,
+ /// use_token: Use,
+ /// leading_colon: None,
+ /// tree: Path(
+ /// UsePath {
+ /// ident: Ident(
+ /// std,
+ /// ),
+ /// colon2_token: Colon2,
+ /// tree: Name(
+ /// UseName {
+ /// ident: Ident(
+ /// env,
+ /// ),
+ /// },
+ /// ),
+ /// },
+ /// ),
+ /// semi_token: Semi,
+ /// },
+ /// ),
+ /// ...
+ /// ```
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct File {
+ pub shebang: Option<String>,
+ pub attrs: Vec<Attribute>,
+ pub items: Vec<Item>,
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::attr::Attribute;
+ use crate::error::Result;
+ use crate::file::File;
+ use crate::parse::{Parse, ParseStream};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for File {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(File {
+ shebang: None,
+ attrs: input.call(Attribute::parse_inner)?,
+ items: {
+ let mut items = Vec::new();
+ while !input.is_empty() {
+ items.push(input.parse()?);
+ }
+ items
+ },
+ })
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use crate::attr::FilterAttrs;
+ use crate::file::File;
+ use proc_macro2::TokenStream;
+ use quote::{ToTokens, TokenStreamExt};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for File {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.inner());
+ tokens.append_all(&self.items);
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/fixup.rs b/rust/hw/char/pl011/vendor/syn/src/fixup.rs
new file mode 100644
index 0000000000..5407c9fdf3
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/fixup.rs
@@ -0,0 +1,218 @@
+use crate::classify;
+use crate::expr::Expr;
+use crate::precedence::Precedence;
+
+pub(crate) struct FixupContext {
+ // 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
+ // }
+ //
+ parenthesize_exterior_struct_lit: bool,
+}
+
+impl FixupContext {
+ /// The default amount of fixing is minimal fixing. Fixups should be turned
+ /// on in a targeted fashion where needed.
+ pub const NONE: Self = FixupContext {
+ stmt: false,
+ leftmost_subexpression_in_stmt: false,
+ match_arm: false,
+ leftmost_subexpression_in_match_arm: false,
+ parenthesize_exterior_struct_lit: false,
+ };
+
+ /// Create the initial fixup for printing an expression in statement
+ /// position.
+ pub fn new_stmt() -> 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 {
+ parenthesize_exterior_struct_lit: 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(self) -> Self {
+ FixupContext {
+ 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,
+ ..self
+ }
+ }
+
+ /// 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) -> Self {
+ FixupContext {
+ 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,
+ ..self
+ }
+ }
+
+ /// Transform this fixup into the one that should apply when printing any
+ /// subexpression that is neither a leftmost subexpression nor surrounded in
+ /// delimiters.
+ ///
+ /// This is for any subexpression that has a different first token than the
+ /// current expression, and is not surrounded by a paren/bracket/brace. For
+ /// example the `$b` in `$a + $b` and `-$b`, but not the one in `[$b]` or
+ /// `$a.f($b)`.
+ pub fn subsequent_subexpression(self) -> Self {
+ FixupContext {
+ stmt: false,
+ leftmost_subexpression_in_stmt: false,
+ match_arm: false,
+ leftmost_subexpression_in_match_arm: false,
+ ..self
+ }
+ }
+
+ /// Determine whether parentheses are needed around the given expression to
+ /// head off an unintended statement boundary.
+ ///
+ /// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has
+ /// examples.
+ pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool {
+ (self.leftmost_subexpression_in_stmt && !classify::requires_semi_to_be_stmt(expr))
+ || (self.leftmost_subexpression_in_match_arm
+ && !classify::requires_comma_to_be_match_arm(expr))
+ }
+
+ /// Determine whether parentheses are needed around the given `let`
+ /// scrutinee.
+ ///
+ /// In `if let _ = $e {}`, some examples of `$e` that would need parentheses
+ /// are:
+ ///
+ /// - `Struct {}.f()`, because otherwise the `{` would be misinterpreted
+ /// as the opening of the if's then-block.
+ ///
+ /// - `true && false`, because otherwise this would be misinterpreted as a
+ /// "let chain".
+ pub fn needs_group_as_let_scrutinee(self, expr: &Expr) -> bool {
+ self.parenthesize_exterior_struct_lit && classify::confusable_with_adjacent_block(expr)
+ || Precedence::of_rhs(expr) <= Precedence::And
+ }
+}
+
+impl Copy for FixupContext {}
+
+impl Clone for FixupContext {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/gen/clone.rs b/rust/hw/char/pl011/vendor/syn/src/gen/clone.rs
new file mode 100644
index 0000000000..de8d574516
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/gen/clone.rs
@@ -0,0 +1,2209 @@
+// This file is @generated by syn-internal-codegen.
+// It is not intended for manual editing.
+
+#![allow(clippy::clone_on_copy, clippy::expl_impl_clone_on_copy)]
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Abi {
+ fn clone(&self) -> Self {
+ crate::Abi {
+ extern_token: self.extern_token.clone(),
+ name: self.name.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::AngleBracketedGenericArguments {
+ fn clone(&self) -> Self {
+ crate::AngleBracketedGenericArguments {
+ colon2_token: self.colon2_token.clone(),
+ lt_token: self.lt_token.clone(),
+ args: self.args.clone(),
+ gt_token: self.gt_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Arm {
+ fn clone(&self) -> Self {
+ crate::Arm {
+ attrs: self.attrs.clone(),
+ pat: self.pat.clone(),
+ guard: self.guard.clone(),
+ fat_arrow_token: self.fat_arrow_token.clone(),
+ body: self.body.clone(),
+ comma: self.comma.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::AssocConst {
+ fn clone(&self) -> Self {
+ crate::AssocConst {
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ eq_token: self.eq_token.clone(),
+ value: self.value.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::AssocType {
+ fn clone(&self) -> Self {
+ crate::AssocType {
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ eq_token: self.eq_token.clone(),
+ ty: self.ty.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Copy for crate::AttrStyle {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::AttrStyle {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Attribute {
+ fn clone(&self) -> Self {
+ crate::Attribute {
+ pound_token: self.pound_token.clone(),
+ style: self.style.clone(),
+ bracket_token: self.bracket_token.clone(),
+ meta: self.meta.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::BareFnArg {
+ fn clone(&self) -> Self {
+ crate::BareFnArg {
+ attrs: self.attrs.clone(),
+ name: self.name.clone(),
+ ty: self.ty.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::BareVariadic {
+ fn clone(&self) -> Self {
+ crate::BareVariadic {
+ attrs: self.attrs.clone(),
+ name: self.name.clone(),
+ dots: self.dots.clone(),
+ comma: self.comma.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Copy for crate::BinOp {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::BinOp {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Block {
+ fn clone(&self) -> Self {
+ crate::Block {
+ brace_token: self.brace_token.clone(),
+ stmts: self.stmts.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::BoundLifetimes {
+ fn clone(&self) -> Self {
+ crate::BoundLifetimes {
+ for_token: self.for_token.clone(),
+ lt_token: self.lt_token.clone(),
+ lifetimes: self.lifetimes.clone(),
+ gt_token: self.gt_token.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ConstParam {
+ fn clone(&self) -> Self {
+ crate::ConstParam {
+ attrs: self.attrs.clone(),
+ const_token: self.const_token.clone(),
+ ident: self.ident.clone(),
+ colon_token: self.colon_token.clone(),
+ ty: self.ty.clone(),
+ eq_token: self.eq_token.clone(),
+ default: self.default.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Constraint {
+ fn clone(&self) -> Self {
+ crate::Constraint {
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ colon_token: self.colon_token.clone(),
+ bounds: self.bounds.clone(),
+ }
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Data {
+ fn clone(&self) -> Self {
+ match self {
+ crate::Data::Struct(v0) => crate::Data::Struct(v0.clone()),
+ crate::Data::Enum(v0) => crate::Data::Enum(v0.clone()),
+ crate::Data::Union(v0) => crate::Data::Union(v0.clone()),
+ }
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::DataEnum {
+ fn clone(&self) -> Self {
+ crate::DataEnum {
+ enum_token: self.enum_token.clone(),
+ brace_token: self.brace_token.clone(),
+ variants: self.variants.clone(),
+ }
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::DataStruct {
+ fn clone(&self) -> Self {
+ crate::DataStruct {
+ struct_token: self.struct_token.clone(),
+ fields: self.fields.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::DataUnion {
+ fn clone(&self) -> Self {
+ crate::DataUnion {
+ union_token: self.union_token.clone(),
+ fields: self.fields.clone(),
+ }
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::DeriveInput {
+ fn clone(&self) -> Self {
+ crate::DeriveInput {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ data: self.data.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Expr {
+ fn clone(&self) -> Self {
+ match self {
+ #[cfg(feature = "full")]
+ crate::Expr::Array(v0) => crate::Expr::Array(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Assign(v0) => crate::Expr::Assign(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Async(v0) => crate::Expr::Async(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Await(v0) => crate::Expr::Await(v0.clone()),
+ crate::Expr::Binary(v0) => crate::Expr::Binary(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Block(v0) => crate::Expr::Block(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Break(v0) => crate::Expr::Break(v0.clone()),
+ crate::Expr::Call(v0) => crate::Expr::Call(v0.clone()),
+ crate::Expr::Cast(v0) => crate::Expr::Cast(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Closure(v0) => crate::Expr::Closure(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Const(v0) => crate::Expr::Const(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Continue(v0) => crate::Expr::Continue(v0.clone()),
+ crate::Expr::Field(v0) => crate::Expr::Field(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::ForLoop(v0) => crate::Expr::ForLoop(v0.clone()),
+ crate::Expr::Group(v0) => crate::Expr::Group(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::If(v0) => crate::Expr::If(v0.clone()),
+ crate::Expr::Index(v0) => crate::Expr::Index(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Infer(v0) => crate::Expr::Infer(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Let(v0) => crate::Expr::Let(v0.clone()),
+ crate::Expr::Lit(v0) => crate::Expr::Lit(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Loop(v0) => crate::Expr::Loop(v0.clone()),
+ crate::Expr::Macro(v0) => crate::Expr::Macro(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Match(v0) => crate::Expr::Match(v0.clone()),
+ crate::Expr::MethodCall(v0) => crate::Expr::MethodCall(v0.clone()),
+ crate::Expr::Paren(v0) => crate::Expr::Paren(v0.clone()),
+ crate::Expr::Path(v0) => crate::Expr::Path(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Range(v0) => crate::Expr::Range(v0.clone()),
+ crate::Expr::Reference(v0) => crate::Expr::Reference(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Repeat(v0) => crate::Expr::Repeat(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Return(v0) => crate::Expr::Return(v0.clone()),
+ crate::Expr::Struct(v0) => crate::Expr::Struct(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Try(v0) => crate::Expr::Try(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::TryBlock(v0) => crate::Expr::TryBlock(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Tuple(v0) => crate::Expr::Tuple(v0.clone()),
+ crate::Expr::Unary(v0) => crate::Expr::Unary(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Unsafe(v0) => crate::Expr::Unsafe(v0.clone()),
+ crate::Expr::Verbatim(v0) => crate::Expr::Verbatim(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::While(v0) => crate::Expr::While(v0.clone()),
+ #[cfg(feature = "full")]
+ crate::Expr::Yield(v0) => crate::Expr::Yield(v0.clone()),
+ #[cfg(not(feature = "full"))]
+ _ => unreachable!(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprArray {
+ fn clone(&self) -> Self {
+ crate::ExprArray {
+ attrs: self.attrs.clone(),
+ bracket_token: self.bracket_token.clone(),
+ elems: self.elems.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprAssign {
+ fn clone(&self) -> Self {
+ crate::ExprAssign {
+ attrs: self.attrs.clone(),
+ left: self.left.clone(),
+ eq_token: self.eq_token.clone(),
+ right: self.right.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprAsync {
+ fn clone(&self) -> Self {
+ crate::ExprAsync {
+ attrs: self.attrs.clone(),
+ async_token: self.async_token.clone(),
+ capture: self.capture.clone(),
+ block: self.block.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprAwait {
+ fn clone(&self) -> Self {
+ crate::ExprAwait {
+ attrs: self.attrs.clone(),
+ base: self.base.clone(),
+ dot_token: self.dot_token.clone(),
+ await_token: self.await_token.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprBinary {
+ fn clone(&self) -> Self {
+ crate::ExprBinary {
+ attrs: self.attrs.clone(),
+ left: self.left.clone(),
+ op: self.op.clone(),
+ right: self.right.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprBlock {
+ fn clone(&self) -> Self {
+ crate::ExprBlock {
+ attrs: self.attrs.clone(),
+ label: self.label.clone(),
+ block: self.block.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprBreak {
+ fn clone(&self) -> Self {
+ crate::ExprBreak {
+ attrs: self.attrs.clone(),
+ break_token: self.break_token.clone(),
+ label: self.label.clone(),
+ expr: self.expr.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprCall {
+ fn clone(&self) -> Self {
+ crate::ExprCall {
+ attrs: self.attrs.clone(),
+ func: self.func.clone(),
+ paren_token: self.paren_token.clone(),
+ args: self.args.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprCast {
+ fn clone(&self) -> Self {
+ crate::ExprCast {
+ attrs: self.attrs.clone(),
+ expr: self.expr.clone(),
+ as_token: self.as_token.clone(),
+ ty: self.ty.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprClosure {
+ fn clone(&self) -> Self {
+ crate::ExprClosure {
+ attrs: self.attrs.clone(),
+ lifetimes: self.lifetimes.clone(),
+ constness: self.constness.clone(),
+ movability: self.movability.clone(),
+ asyncness: self.asyncness.clone(),
+ capture: self.capture.clone(),
+ or1_token: self.or1_token.clone(),
+ inputs: self.inputs.clone(),
+ or2_token: self.or2_token.clone(),
+ output: self.output.clone(),
+ body: self.body.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprConst {
+ fn clone(&self) -> Self {
+ crate::ExprConst {
+ attrs: self.attrs.clone(),
+ const_token: self.const_token.clone(),
+ block: self.block.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprContinue {
+ fn clone(&self) -> Self {
+ crate::ExprContinue {
+ attrs: self.attrs.clone(),
+ continue_token: self.continue_token.clone(),
+ label: self.label.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprField {
+ fn clone(&self) -> Self {
+ crate::ExprField {
+ attrs: self.attrs.clone(),
+ base: self.base.clone(),
+ dot_token: self.dot_token.clone(),
+ member: self.member.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprForLoop {
+ fn clone(&self) -> Self {
+ crate::ExprForLoop {
+ attrs: self.attrs.clone(),
+ label: self.label.clone(),
+ for_token: self.for_token.clone(),
+ pat: self.pat.clone(),
+ in_token: self.in_token.clone(),
+ expr: self.expr.clone(),
+ body: self.body.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprGroup {
+ fn clone(&self) -> Self {
+ crate::ExprGroup {
+ attrs: self.attrs.clone(),
+ group_token: self.group_token.clone(),
+ expr: self.expr.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprIf {
+ fn clone(&self) -> Self {
+ crate::ExprIf {
+ attrs: self.attrs.clone(),
+ if_token: self.if_token.clone(),
+ cond: self.cond.clone(),
+ then_branch: self.then_branch.clone(),
+ else_branch: self.else_branch.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprIndex {
+ fn clone(&self) -> Self {
+ crate::ExprIndex {
+ attrs: self.attrs.clone(),
+ expr: self.expr.clone(),
+ bracket_token: self.bracket_token.clone(),
+ index: self.index.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprInfer {
+ fn clone(&self) -> Self {
+ crate::ExprInfer {
+ attrs: self.attrs.clone(),
+ underscore_token: self.underscore_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprLet {
+ fn clone(&self) -> Self {
+ crate::ExprLet {
+ attrs: self.attrs.clone(),
+ let_token: self.let_token.clone(),
+ pat: self.pat.clone(),
+ eq_token: self.eq_token.clone(),
+ expr: self.expr.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprLit {
+ fn clone(&self) -> Self {
+ crate::ExprLit {
+ attrs: self.attrs.clone(),
+ lit: self.lit.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprLoop {
+ fn clone(&self) -> Self {
+ crate::ExprLoop {
+ attrs: self.attrs.clone(),
+ label: self.label.clone(),
+ loop_token: self.loop_token.clone(),
+ body: self.body.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprMacro {
+ fn clone(&self) -> Self {
+ crate::ExprMacro {
+ attrs: self.attrs.clone(),
+ mac: self.mac.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprMatch {
+ fn clone(&self) -> Self {
+ crate::ExprMatch {
+ attrs: self.attrs.clone(),
+ match_token: self.match_token.clone(),
+ expr: self.expr.clone(),
+ brace_token: self.brace_token.clone(),
+ arms: self.arms.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprMethodCall {
+ fn clone(&self) -> Self {
+ crate::ExprMethodCall {
+ attrs: self.attrs.clone(),
+ receiver: self.receiver.clone(),
+ dot_token: self.dot_token.clone(),
+ method: self.method.clone(),
+ turbofish: self.turbofish.clone(),
+ paren_token: self.paren_token.clone(),
+ args: self.args.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprParen {
+ fn clone(&self) -> Self {
+ crate::ExprParen {
+ attrs: self.attrs.clone(),
+ paren_token: self.paren_token.clone(),
+ expr: self.expr.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprPath {
+ fn clone(&self) -> Self {
+ crate::ExprPath {
+ attrs: self.attrs.clone(),
+ qself: self.qself.clone(),
+ path: self.path.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprRange {
+ fn clone(&self) -> Self {
+ crate::ExprRange {
+ attrs: self.attrs.clone(),
+ start: self.start.clone(),
+ limits: self.limits.clone(),
+ end: self.end.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprReference {
+ fn clone(&self) -> Self {
+ crate::ExprReference {
+ attrs: self.attrs.clone(),
+ and_token: self.and_token.clone(),
+ mutability: self.mutability.clone(),
+ expr: self.expr.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprRepeat {
+ fn clone(&self) -> Self {
+ crate::ExprRepeat {
+ attrs: self.attrs.clone(),
+ bracket_token: self.bracket_token.clone(),
+ expr: self.expr.clone(),
+ semi_token: self.semi_token.clone(),
+ len: self.len.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprReturn {
+ fn clone(&self) -> Self {
+ crate::ExprReturn {
+ attrs: self.attrs.clone(),
+ return_token: self.return_token.clone(),
+ expr: self.expr.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprStruct {
+ fn clone(&self) -> Self {
+ crate::ExprStruct {
+ attrs: self.attrs.clone(),
+ qself: self.qself.clone(),
+ path: self.path.clone(),
+ brace_token: self.brace_token.clone(),
+ fields: self.fields.clone(),
+ dot2_token: self.dot2_token.clone(),
+ rest: self.rest.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprTry {
+ fn clone(&self) -> Self {
+ crate::ExprTry {
+ attrs: self.attrs.clone(),
+ expr: self.expr.clone(),
+ question_token: self.question_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprTryBlock {
+ fn clone(&self) -> Self {
+ crate::ExprTryBlock {
+ attrs: self.attrs.clone(),
+ try_token: self.try_token.clone(),
+ block: self.block.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprTuple {
+ fn clone(&self) -> Self {
+ crate::ExprTuple {
+ attrs: self.attrs.clone(),
+ paren_token: self.paren_token.clone(),
+ elems: self.elems.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprUnary {
+ fn clone(&self) -> Self {
+ crate::ExprUnary {
+ attrs: self.attrs.clone(),
+ op: self.op.clone(),
+ expr: self.expr.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprUnsafe {
+ fn clone(&self) -> Self {
+ crate::ExprUnsafe {
+ attrs: self.attrs.clone(),
+ unsafe_token: self.unsafe_token.clone(),
+ block: self.block.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprWhile {
+ fn clone(&self) -> Self {
+ crate::ExprWhile {
+ attrs: self.attrs.clone(),
+ label: self.label.clone(),
+ while_token: self.while_token.clone(),
+ cond: self.cond.clone(),
+ body: self.body.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ExprYield {
+ fn clone(&self) -> Self {
+ crate::ExprYield {
+ attrs: self.attrs.clone(),
+ yield_token: self.yield_token.clone(),
+ expr: self.expr.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Field {
+ fn clone(&self) -> Self {
+ crate::Field {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ mutability: self.mutability.clone(),
+ ident: self.ident.clone(),
+ colon_token: self.colon_token.clone(),
+ ty: self.ty.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::FieldMutability {
+ fn clone(&self) -> Self {
+ match self {
+ crate::FieldMutability::None => crate::FieldMutability::None,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::FieldPat {
+ fn clone(&self) -> Self {
+ crate::FieldPat {
+ attrs: self.attrs.clone(),
+ member: self.member.clone(),
+ colon_token: self.colon_token.clone(),
+ pat: self.pat.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::FieldValue {
+ fn clone(&self) -> Self {
+ crate::FieldValue {
+ attrs: self.attrs.clone(),
+ member: self.member.clone(),
+ colon_token: self.colon_token.clone(),
+ expr: self.expr.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Fields {
+ fn clone(&self) -> Self {
+ match self {
+ crate::Fields::Named(v0) => crate::Fields::Named(v0.clone()),
+ crate::Fields::Unnamed(v0) => crate::Fields::Unnamed(v0.clone()),
+ crate::Fields::Unit => crate::Fields::Unit,
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::FieldsNamed {
+ fn clone(&self) -> Self {
+ crate::FieldsNamed {
+ brace_token: self.brace_token.clone(),
+ named: self.named.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::FieldsUnnamed {
+ fn clone(&self) -> Self {
+ crate::FieldsUnnamed {
+ paren_token: self.paren_token.clone(),
+ unnamed: self.unnamed.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::File {
+ fn clone(&self) -> Self {
+ crate::File {
+ shebang: self.shebang.clone(),
+ attrs: self.attrs.clone(),
+ items: self.items.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::FnArg {
+ fn clone(&self) -> Self {
+ match self {
+ crate::FnArg::Receiver(v0) => crate::FnArg::Receiver(v0.clone()),
+ crate::FnArg::Typed(v0) => crate::FnArg::Typed(v0.clone()),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ForeignItem {
+ fn clone(&self) -> Self {
+ match self {
+ crate::ForeignItem::Fn(v0) => crate::ForeignItem::Fn(v0.clone()),
+ crate::ForeignItem::Static(v0) => crate::ForeignItem::Static(v0.clone()),
+ crate::ForeignItem::Type(v0) => crate::ForeignItem::Type(v0.clone()),
+ crate::ForeignItem::Macro(v0) => crate::ForeignItem::Macro(v0.clone()),
+ crate::ForeignItem::Verbatim(v0) => crate::ForeignItem::Verbatim(v0.clone()),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ForeignItemFn {
+ fn clone(&self) -> Self {
+ crate::ForeignItemFn {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ sig: self.sig.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ForeignItemMacro {
+ fn clone(&self) -> Self {
+ crate::ForeignItemMacro {
+ attrs: self.attrs.clone(),
+ mac: self.mac.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ForeignItemStatic {
+ fn clone(&self) -> Self {
+ crate::ForeignItemStatic {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ static_token: self.static_token.clone(),
+ mutability: self.mutability.clone(),
+ ident: self.ident.clone(),
+ colon_token: self.colon_token.clone(),
+ ty: self.ty.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ForeignItemType {
+ fn clone(&self) -> Self {
+ crate::ForeignItemType {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ type_token: self.type_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::GenericArgument {
+ fn clone(&self) -> Self {
+ match self {
+ crate::GenericArgument::Lifetime(v0) => {
+ crate::GenericArgument::Lifetime(v0.clone())
+ }
+ crate::GenericArgument::Type(v0) => crate::GenericArgument::Type(v0.clone()),
+ crate::GenericArgument::Const(v0) => {
+ crate::GenericArgument::Const(v0.clone())
+ }
+ crate::GenericArgument::AssocType(v0) => {
+ crate::GenericArgument::AssocType(v0.clone())
+ }
+ crate::GenericArgument::AssocConst(v0) => {
+ crate::GenericArgument::AssocConst(v0.clone())
+ }
+ crate::GenericArgument::Constraint(v0) => {
+ crate::GenericArgument::Constraint(v0.clone())
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::GenericParam {
+ fn clone(&self) -> Self {
+ match self {
+ crate::GenericParam::Lifetime(v0) => {
+ crate::GenericParam::Lifetime(v0.clone())
+ }
+ crate::GenericParam::Type(v0) => crate::GenericParam::Type(v0.clone()),
+ crate::GenericParam::Const(v0) => crate::GenericParam::Const(v0.clone()),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Generics {
+ fn clone(&self) -> Self {
+ crate::Generics {
+ lt_token: self.lt_token.clone(),
+ params: self.params.clone(),
+ gt_token: self.gt_token.clone(),
+ where_clause: self.where_clause.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ImplItem {
+ fn clone(&self) -> Self {
+ match self {
+ crate::ImplItem::Const(v0) => crate::ImplItem::Const(v0.clone()),
+ crate::ImplItem::Fn(v0) => crate::ImplItem::Fn(v0.clone()),
+ crate::ImplItem::Type(v0) => crate::ImplItem::Type(v0.clone()),
+ crate::ImplItem::Macro(v0) => crate::ImplItem::Macro(v0.clone()),
+ crate::ImplItem::Verbatim(v0) => crate::ImplItem::Verbatim(v0.clone()),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ImplItemConst {
+ fn clone(&self) -> Self {
+ crate::ImplItemConst {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ defaultness: self.defaultness.clone(),
+ const_token: self.const_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ colon_token: self.colon_token.clone(),
+ ty: self.ty.clone(),
+ eq_token: self.eq_token.clone(),
+ expr: self.expr.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ImplItemFn {
+ fn clone(&self) -> Self {
+ crate::ImplItemFn {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ defaultness: self.defaultness.clone(),
+ sig: self.sig.clone(),
+ block: self.block.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ImplItemMacro {
+ fn clone(&self) -> Self {
+ crate::ImplItemMacro {
+ attrs: self.attrs.clone(),
+ mac: self.mac.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ImplItemType {
+ fn clone(&self) -> Self {
+ crate::ImplItemType {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ defaultness: self.defaultness.clone(),
+ type_token: self.type_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ eq_token: self.eq_token.clone(),
+ ty: self.ty.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ImplRestriction {
+ fn clone(&self) -> Self {
+ match *self {}
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Index {
+ fn clone(&self) -> Self {
+ crate::Index {
+ index: self.index.clone(),
+ span: self.span.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Item {
+ fn clone(&self) -> Self {
+ match self {
+ crate::Item::Const(v0) => crate::Item::Const(v0.clone()),
+ crate::Item::Enum(v0) => crate::Item::Enum(v0.clone()),
+ crate::Item::ExternCrate(v0) => crate::Item::ExternCrate(v0.clone()),
+ crate::Item::Fn(v0) => crate::Item::Fn(v0.clone()),
+ crate::Item::ForeignMod(v0) => crate::Item::ForeignMod(v0.clone()),
+ crate::Item::Impl(v0) => crate::Item::Impl(v0.clone()),
+ crate::Item::Macro(v0) => crate::Item::Macro(v0.clone()),
+ crate::Item::Mod(v0) => crate::Item::Mod(v0.clone()),
+ crate::Item::Static(v0) => crate::Item::Static(v0.clone()),
+ crate::Item::Struct(v0) => crate::Item::Struct(v0.clone()),
+ crate::Item::Trait(v0) => crate::Item::Trait(v0.clone()),
+ crate::Item::TraitAlias(v0) => crate::Item::TraitAlias(v0.clone()),
+ crate::Item::Type(v0) => crate::Item::Type(v0.clone()),
+ crate::Item::Union(v0) => crate::Item::Union(v0.clone()),
+ crate::Item::Use(v0) => crate::Item::Use(v0.clone()),
+ crate::Item::Verbatim(v0) => crate::Item::Verbatim(v0.clone()),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemConst {
+ fn clone(&self) -> Self {
+ crate::ItemConst {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ const_token: self.const_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ colon_token: self.colon_token.clone(),
+ ty: self.ty.clone(),
+ eq_token: self.eq_token.clone(),
+ expr: self.expr.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemEnum {
+ fn clone(&self) -> Self {
+ crate::ItemEnum {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ enum_token: self.enum_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ brace_token: self.brace_token.clone(),
+ variants: self.variants.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemExternCrate {
+ fn clone(&self) -> Self {
+ crate::ItemExternCrate {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ extern_token: self.extern_token.clone(),
+ crate_token: self.crate_token.clone(),
+ ident: self.ident.clone(),
+ rename: self.rename.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemFn {
+ fn clone(&self) -> Self {
+ crate::ItemFn {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ sig: self.sig.clone(),
+ block: self.block.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemForeignMod {
+ fn clone(&self) -> Self {
+ crate::ItemForeignMod {
+ attrs: self.attrs.clone(),
+ unsafety: self.unsafety.clone(),
+ abi: self.abi.clone(),
+ brace_token: self.brace_token.clone(),
+ items: self.items.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemImpl {
+ fn clone(&self) -> Self {
+ crate::ItemImpl {
+ attrs: self.attrs.clone(),
+ defaultness: self.defaultness.clone(),
+ unsafety: self.unsafety.clone(),
+ impl_token: self.impl_token.clone(),
+ generics: self.generics.clone(),
+ trait_: self.trait_.clone(),
+ self_ty: self.self_ty.clone(),
+ brace_token: self.brace_token.clone(),
+ items: self.items.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemMacro {
+ fn clone(&self) -> Self {
+ crate::ItemMacro {
+ attrs: self.attrs.clone(),
+ ident: self.ident.clone(),
+ mac: self.mac.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemMod {
+ fn clone(&self) -> Self {
+ crate::ItemMod {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ unsafety: self.unsafety.clone(),
+ mod_token: self.mod_token.clone(),
+ ident: self.ident.clone(),
+ content: self.content.clone(),
+ semi: self.semi.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemStatic {
+ fn clone(&self) -> Self {
+ crate::ItemStatic {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ static_token: self.static_token.clone(),
+ mutability: self.mutability.clone(),
+ ident: self.ident.clone(),
+ colon_token: self.colon_token.clone(),
+ ty: self.ty.clone(),
+ eq_token: self.eq_token.clone(),
+ expr: self.expr.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemStruct {
+ fn clone(&self) -> Self {
+ crate::ItemStruct {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ struct_token: self.struct_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ fields: self.fields.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemTrait {
+ fn clone(&self) -> Self {
+ crate::ItemTrait {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ unsafety: self.unsafety.clone(),
+ auto_token: self.auto_token.clone(),
+ restriction: self.restriction.clone(),
+ trait_token: self.trait_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ colon_token: self.colon_token.clone(),
+ supertraits: self.supertraits.clone(),
+ brace_token: self.brace_token.clone(),
+ items: self.items.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemTraitAlias {
+ fn clone(&self) -> Self {
+ crate::ItemTraitAlias {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ trait_token: self.trait_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ eq_token: self.eq_token.clone(),
+ bounds: self.bounds.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemType {
+ fn clone(&self) -> Self {
+ crate::ItemType {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ type_token: self.type_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ eq_token: self.eq_token.clone(),
+ ty: self.ty.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemUnion {
+ fn clone(&self) -> Self {
+ crate::ItemUnion {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ union_token: self.union_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ fields: self.fields.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ItemUse {
+ fn clone(&self) -> Self {
+ crate::ItemUse {
+ attrs: self.attrs.clone(),
+ vis: self.vis.clone(),
+ use_token: self.use_token.clone(),
+ leading_colon: self.leading_colon.clone(),
+ tree: self.tree.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Label {
+ fn clone(&self) -> Self {
+ crate::Label {
+ name: self.name.clone(),
+ colon_token: self.colon_token.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::LifetimeParam {
+ fn clone(&self) -> Self {
+ crate::LifetimeParam {
+ attrs: self.attrs.clone(),
+ lifetime: self.lifetime.clone(),
+ colon_token: self.colon_token.clone(),
+ bounds: self.bounds.clone(),
+ }
+ }
+}
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Lit {
+ fn clone(&self) -> Self {
+ match self {
+ crate::Lit::Str(v0) => crate::Lit::Str(v0.clone()),
+ crate::Lit::ByteStr(v0) => crate::Lit::ByteStr(v0.clone()),
+ crate::Lit::CStr(v0) => crate::Lit::CStr(v0.clone()),
+ crate::Lit::Byte(v0) => crate::Lit::Byte(v0.clone()),
+ crate::Lit::Char(v0) => crate::Lit::Char(v0.clone()),
+ crate::Lit::Int(v0) => crate::Lit::Int(v0.clone()),
+ crate::Lit::Float(v0) => crate::Lit::Float(v0.clone()),
+ crate::Lit::Bool(v0) => crate::Lit::Bool(v0.clone()),
+ crate::Lit::Verbatim(v0) => crate::Lit::Verbatim(v0.clone()),
+ }
+ }
+}
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::LitBool {
+ fn clone(&self) -> Self {
+ crate::LitBool {
+ value: self.value.clone(),
+ span: self.span.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Local {
+ fn clone(&self) -> Self {
+ crate::Local {
+ attrs: self.attrs.clone(),
+ let_token: self.let_token.clone(),
+ pat: self.pat.clone(),
+ init: self.init.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::LocalInit {
+ fn clone(&self) -> Self {
+ crate::LocalInit {
+ eq_token: self.eq_token.clone(),
+ expr: self.expr.clone(),
+ diverge: self.diverge.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Macro {
+ fn clone(&self) -> Self {
+ crate::Macro {
+ path: self.path.clone(),
+ bang_token: self.bang_token.clone(),
+ delimiter: self.delimiter.clone(),
+ tokens: self.tokens.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::MacroDelimiter {
+ fn clone(&self) -> Self {
+ match self {
+ crate::MacroDelimiter::Paren(v0) => crate::MacroDelimiter::Paren(v0.clone()),
+ crate::MacroDelimiter::Brace(v0) => crate::MacroDelimiter::Brace(v0.clone()),
+ crate::MacroDelimiter::Bracket(v0) => {
+ crate::MacroDelimiter::Bracket(v0.clone())
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Member {
+ fn clone(&self) -> Self {
+ match self {
+ crate::Member::Named(v0) => crate::Member::Named(v0.clone()),
+ crate::Member::Unnamed(v0) => crate::Member::Unnamed(v0.clone()),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Meta {
+ fn clone(&self) -> Self {
+ match self {
+ crate::Meta::Path(v0) => crate::Meta::Path(v0.clone()),
+ crate::Meta::List(v0) => crate::Meta::List(v0.clone()),
+ crate::Meta::NameValue(v0) => crate::Meta::NameValue(v0.clone()),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::MetaList {
+ fn clone(&self) -> Self {
+ crate::MetaList {
+ path: self.path.clone(),
+ delimiter: self.delimiter.clone(),
+ tokens: self.tokens.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::MetaNameValue {
+ fn clone(&self) -> Self {
+ crate::MetaNameValue {
+ path: self.path.clone(),
+ eq_token: self.eq_token.clone(),
+ value: self.value.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ParenthesizedGenericArguments {
+ fn clone(&self) -> Self {
+ crate::ParenthesizedGenericArguments {
+ paren_token: self.paren_token.clone(),
+ inputs: self.inputs.clone(),
+ output: self.output.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Pat {
+ fn clone(&self) -> Self {
+ match self {
+ crate::Pat::Const(v0) => crate::Pat::Const(v0.clone()),
+ crate::Pat::Ident(v0) => crate::Pat::Ident(v0.clone()),
+ crate::Pat::Lit(v0) => crate::Pat::Lit(v0.clone()),
+ crate::Pat::Macro(v0) => crate::Pat::Macro(v0.clone()),
+ crate::Pat::Or(v0) => crate::Pat::Or(v0.clone()),
+ crate::Pat::Paren(v0) => crate::Pat::Paren(v0.clone()),
+ crate::Pat::Path(v0) => crate::Pat::Path(v0.clone()),
+ crate::Pat::Range(v0) => crate::Pat::Range(v0.clone()),
+ crate::Pat::Reference(v0) => crate::Pat::Reference(v0.clone()),
+ crate::Pat::Rest(v0) => crate::Pat::Rest(v0.clone()),
+ crate::Pat::Slice(v0) => crate::Pat::Slice(v0.clone()),
+ crate::Pat::Struct(v0) => crate::Pat::Struct(v0.clone()),
+ crate::Pat::Tuple(v0) => crate::Pat::Tuple(v0.clone()),
+ crate::Pat::TupleStruct(v0) => crate::Pat::TupleStruct(v0.clone()),
+ crate::Pat::Type(v0) => crate::Pat::Type(v0.clone()),
+ crate::Pat::Verbatim(v0) => crate::Pat::Verbatim(v0.clone()),
+ crate::Pat::Wild(v0) => crate::Pat::Wild(v0.clone()),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PatIdent {
+ fn clone(&self) -> Self {
+ crate::PatIdent {
+ attrs: self.attrs.clone(),
+ by_ref: self.by_ref.clone(),
+ mutability: self.mutability.clone(),
+ ident: self.ident.clone(),
+ subpat: self.subpat.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PatOr {
+ fn clone(&self) -> Self {
+ crate::PatOr {
+ attrs: self.attrs.clone(),
+ leading_vert: self.leading_vert.clone(),
+ cases: self.cases.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PatParen {
+ fn clone(&self) -> Self {
+ crate::PatParen {
+ attrs: self.attrs.clone(),
+ paren_token: self.paren_token.clone(),
+ pat: self.pat.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PatReference {
+ fn clone(&self) -> Self {
+ crate::PatReference {
+ attrs: self.attrs.clone(),
+ and_token: self.and_token.clone(),
+ mutability: self.mutability.clone(),
+ pat: self.pat.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PatRest {
+ fn clone(&self) -> Self {
+ crate::PatRest {
+ attrs: self.attrs.clone(),
+ dot2_token: self.dot2_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PatSlice {
+ fn clone(&self) -> Self {
+ crate::PatSlice {
+ attrs: self.attrs.clone(),
+ bracket_token: self.bracket_token.clone(),
+ elems: self.elems.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PatStruct {
+ fn clone(&self) -> Self {
+ crate::PatStruct {
+ attrs: self.attrs.clone(),
+ qself: self.qself.clone(),
+ path: self.path.clone(),
+ brace_token: self.brace_token.clone(),
+ fields: self.fields.clone(),
+ rest: self.rest.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PatTuple {
+ fn clone(&self) -> Self {
+ crate::PatTuple {
+ attrs: self.attrs.clone(),
+ paren_token: self.paren_token.clone(),
+ elems: self.elems.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PatTupleStruct {
+ fn clone(&self) -> Self {
+ crate::PatTupleStruct {
+ attrs: self.attrs.clone(),
+ qself: self.qself.clone(),
+ path: self.path.clone(),
+ paren_token: self.paren_token.clone(),
+ elems: self.elems.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PatType {
+ fn clone(&self) -> Self {
+ crate::PatType {
+ attrs: self.attrs.clone(),
+ pat: self.pat.clone(),
+ colon_token: self.colon_token.clone(),
+ ty: self.ty.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PatWild {
+ fn clone(&self) -> Self {
+ crate::PatWild {
+ attrs: self.attrs.clone(),
+ underscore_token: self.underscore_token.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Path {
+ fn clone(&self) -> Self {
+ crate::Path {
+ leading_colon: self.leading_colon.clone(),
+ segments: self.segments.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PathArguments {
+ fn clone(&self) -> Self {
+ match self {
+ crate::PathArguments::None => crate::PathArguments::None,
+ crate::PathArguments::AngleBracketed(v0) => {
+ crate::PathArguments::AngleBracketed(v0.clone())
+ }
+ crate::PathArguments::Parenthesized(v0) => {
+ crate::PathArguments::Parenthesized(v0.clone())
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PathSegment {
+ fn clone(&self) -> Self {
+ crate::PathSegment {
+ ident: self.ident.clone(),
+ arguments: self.arguments.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PredicateLifetime {
+ fn clone(&self) -> Self {
+ crate::PredicateLifetime {
+ lifetime: self.lifetime.clone(),
+ colon_token: self.colon_token.clone(),
+ bounds: self.bounds.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::PredicateType {
+ fn clone(&self) -> Self {
+ crate::PredicateType {
+ lifetimes: self.lifetimes.clone(),
+ bounded_ty: self.bounded_ty.clone(),
+ colon_token: self.colon_token.clone(),
+ bounds: self.bounds.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::QSelf {
+ fn clone(&self) -> Self {
+ crate::QSelf {
+ lt_token: self.lt_token.clone(),
+ ty: self.ty.clone(),
+ position: self.position.clone(),
+ as_token: self.as_token.clone(),
+ gt_token: self.gt_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Copy for crate::RangeLimits {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::RangeLimits {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Receiver {
+ fn clone(&self) -> Self {
+ crate::Receiver {
+ attrs: self.attrs.clone(),
+ reference: self.reference.clone(),
+ mutability: self.mutability.clone(),
+ self_token: self.self_token.clone(),
+ colon_token: self.colon_token.clone(),
+ ty: self.ty.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::ReturnType {
+ fn clone(&self) -> Self {
+ match self {
+ crate::ReturnType::Default => crate::ReturnType::Default,
+ crate::ReturnType::Type(v0, v1) => {
+ crate::ReturnType::Type(v0.clone(), v1.clone())
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Signature {
+ fn clone(&self) -> Self {
+ crate::Signature {
+ constness: self.constness.clone(),
+ asyncness: self.asyncness.clone(),
+ unsafety: self.unsafety.clone(),
+ abi: self.abi.clone(),
+ fn_token: self.fn_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ paren_token: self.paren_token.clone(),
+ inputs: self.inputs.clone(),
+ variadic: self.variadic.clone(),
+ output: self.output.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::StaticMutability {
+ fn clone(&self) -> Self {
+ match self {
+ crate::StaticMutability::Mut(v0) => crate::StaticMutability::Mut(v0.clone()),
+ crate::StaticMutability::None => crate::StaticMutability::None,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Stmt {
+ fn clone(&self) -> Self {
+ match self {
+ crate::Stmt::Local(v0) => crate::Stmt::Local(v0.clone()),
+ crate::Stmt::Item(v0) => crate::Stmt::Item(v0.clone()),
+ crate::Stmt::Expr(v0, v1) => crate::Stmt::Expr(v0.clone(), v1.clone()),
+ crate::Stmt::Macro(v0) => crate::Stmt::Macro(v0.clone()),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::StmtMacro {
+ fn clone(&self) -> Self {
+ crate::StmtMacro {
+ attrs: self.attrs.clone(),
+ mac: self.mac.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TraitBound {
+ fn clone(&self) -> Self {
+ crate::TraitBound {
+ paren_token: self.paren_token.clone(),
+ modifier: self.modifier.clone(),
+ lifetimes: self.lifetimes.clone(),
+ path: self.path.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Copy for crate::TraitBoundModifier {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TraitBoundModifier {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TraitItem {
+ fn clone(&self) -> Self {
+ match self {
+ crate::TraitItem::Const(v0) => crate::TraitItem::Const(v0.clone()),
+ crate::TraitItem::Fn(v0) => crate::TraitItem::Fn(v0.clone()),
+ crate::TraitItem::Type(v0) => crate::TraitItem::Type(v0.clone()),
+ crate::TraitItem::Macro(v0) => crate::TraitItem::Macro(v0.clone()),
+ crate::TraitItem::Verbatim(v0) => crate::TraitItem::Verbatim(v0.clone()),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TraitItemConst {
+ fn clone(&self) -> Self {
+ crate::TraitItemConst {
+ attrs: self.attrs.clone(),
+ const_token: self.const_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ colon_token: self.colon_token.clone(),
+ ty: self.ty.clone(),
+ default: self.default.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TraitItemFn {
+ fn clone(&self) -> Self {
+ crate::TraitItemFn {
+ attrs: self.attrs.clone(),
+ sig: self.sig.clone(),
+ default: self.default.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TraitItemMacro {
+ fn clone(&self) -> Self {
+ crate::TraitItemMacro {
+ attrs: self.attrs.clone(),
+ mac: self.mac.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TraitItemType {
+ fn clone(&self) -> Self {
+ crate::TraitItemType {
+ attrs: self.attrs.clone(),
+ type_token: self.type_token.clone(),
+ ident: self.ident.clone(),
+ generics: self.generics.clone(),
+ colon_token: self.colon_token.clone(),
+ bounds: self.bounds.clone(),
+ default: self.default.clone(),
+ semi_token: self.semi_token.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Type {
+ fn clone(&self) -> Self {
+ match self {
+ crate::Type::Array(v0) => crate::Type::Array(v0.clone()),
+ crate::Type::BareFn(v0) => crate::Type::BareFn(v0.clone()),
+ crate::Type::Group(v0) => crate::Type::Group(v0.clone()),
+ crate::Type::ImplTrait(v0) => crate::Type::ImplTrait(v0.clone()),
+ crate::Type::Infer(v0) => crate::Type::Infer(v0.clone()),
+ crate::Type::Macro(v0) => crate::Type::Macro(v0.clone()),
+ crate::Type::Never(v0) => crate::Type::Never(v0.clone()),
+ crate::Type::Paren(v0) => crate::Type::Paren(v0.clone()),
+ crate::Type::Path(v0) => crate::Type::Path(v0.clone()),
+ crate::Type::Ptr(v0) => crate::Type::Ptr(v0.clone()),
+ crate::Type::Reference(v0) => crate::Type::Reference(v0.clone()),
+ crate::Type::Slice(v0) => crate::Type::Slice(v0.clone()),
+ crate::Type::TraitObject(v0) => crate::Type::TraitObject(v0.clone()),
+ crate::Type::Tuple(v0) => crate::Type::Tuple(v0.clone()),
+ crate::Type::Verbatim(v0) => crate::Type::Verbatim(v0.clone()),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeArray {
+ fn clone(&self) -> Self {
+ crate::TypeArray {
+ bracket_token: self.bracket_token.clone(),
+ elem: self.elem.clone(),
+ semi_token: self.semi_token.clone(),
+ len: self.len.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeBareFn {
+ fn clone(&self) -> Self {
+ crate::TypeBareFn {
+ lifetimes: self.lifetimes.clone(),
+ unsafety: self.unsafety.clone(),
+ abi: self.abi.clone(),
+ fn_token: self.fn_token.clone(),
+ paren_token: self.paren_token.clone(),
+ inputs: self.inputs.clone(),
+ variadic: self.variadic.clone(),
+ output: self.output.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeGroup {
+ fn clone(&self) -> Self {
+ crate::TypeGroup {
+ group_token: self.group_token.clone(),
+ elem: self.elem.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeImplTrait {
+ fn clone(&self) -> Self {
+ crate::TypeImplTrait {
+ impl_token: self.impl_token.clone(),
+ bounds: self.bounds.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeInfer {
+ fn clone(&self) -> Self {
+ crate::TypeInfer {
+ underscore_token: self.underscore_token.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeMacro {
+ fn clone(&self) -> Self {
+ crate::TypeMacro {
+ mac: self.mac.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeNever {
+ fn clone(&self) -> Self {
+ crate::TypeNever {
+ bang_token: self.bang_token.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeParam {
+ fn clone(&self) -> Self {
+ crate::TypeParam {
+ attrs: self.attrs.clone(),
+ ident: self.ident.clone(),
+ colon_token: self.colon_token.clone(),
+ bounds: self.bounds.clone(),
+ eq_token: self.eq_token.clone(),
+ default: self.default.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeParamBound {
+ fn clone(&self) -> Self {
+ match self {
+ crate::TypeParamBound::Trait(v0) => crate::TypeParamBound::Trait(v0.clone()),
+ crate::TypeParamBound::Lifetime(v0) => {
+ crate::TypeParamBound::Lifetime(v0.clone())
+ }
+ crate::TypeParamBound::Verbatim(v0) => {
+ crate::TypeParamBound::Verbatim(v0.clone())
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeParen {
+ fn clone(&self) -> Self {
+ crate::TypeParen {
+ paren_token: self.paren_token.clone(),
+ elem: self.elem.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypePath {
+ fn clone(&self) -> Self {
+ crate::TypePath {
+ qself: self.qself.clone(),
+ path: self.path.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypePtr {
+ fn clone(&self) -> Self {
+ crate::TypePtr {
+ star_token: self.star_token.clone(),
+ const_token: self.const_token.clone(),
+ mutability: self.mutability.clone(),
+ elem: self.elem.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeReference {
+ fn clone(&self) -> Self {
+ crate::TypeReference {
+ and_token: self.and_token.clone(),
+ lifetime: self.lifetime.clone(),
+ mutability: self.mutability.clone(),
+ elem: self.elem.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeSlice {
+ fn clone(&self) -> Self {
+ crate::TypeSlice {
+ bracket_token: self.bracket_token.clone(),
+ elem: self.elem.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeTraitObject {
+ fn clone(&self) -> Self {
+ crate::TypeTraitObject {
+ dyn_token: self.dyn_token.clone(),
+ bounds: self.bounds.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::TypeTuple {
+ fn clone(&self) -> Self {
+ crate::TypeTuple {
+ paren_token: self.paren_token.clone(),
+ elems: self.elems.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Copy for crate::UnOp {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::UnOp {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::UseGlob {
+ fn clone(&self) -> Self {
+ crate::UseGlob {
+ star_token: self.star_token.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::UseGroup {
+ fn clone(&self) -> Self {
+ crate::UseGroup {
+ brace_token: self.brace_token.clone(),
+ items: self.items.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::UseName {
+ fn clone(&self) -> Self {
+ crate::UseName {
+ ident: self.ident.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::UsePath {
+ fn clone(&self) -> Self {
+ crate::UsePath {
+ ident: self.ident.clone(),
+ colon2_token: self.colon2_token.clone(),
+ tree: self.tree.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::UseRename {
+ fn clone(&self) -> Self {
+ crate::UseRename {
+ ident: self.ident.clone(),
+ as_token: self.as_token.clone(),
+ rename: self.rename.clone(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::UseTree {
+ fn clone(&self) -> Self {
+ match self {
+ crate::UseTree::Path(v0) => crate::UseTree::Path(v0.clone()),
+ crate::UseTree::Name(v0) => crate::UseTree::Name(v0.clone()),
+ crate::UseTree::Rename(v0) => crate::UseTree::Rename(v0.clone()),
+ crate::UseTree::Glob(v0) => crate::UseTree::Glob(v0.clone()),
+ crate::UseTree::Group(v0) => crate::UseTree::Group(v0.clone()),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Variadic {
+ fn clone(&self) -> Self {
+ crate::Variadic {
+ attrs: self.attrs.clone(),
+ pat: self.pat.clone(),
+ dots: self.dots.clone(),
+ comma: self.comma.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Variant {
+ fn clone(&self) -> Self {
+ crate::Variant {
+ attrs: self.attrs.clone(),
+ ident: self.ident.clone(),
+ fields: self.fields.clone(),
+ discriminant: self.discriminant.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::VisRestricted {
+ fn clone(&self) -> Self {
+ crate::VisRestricted {
+ pub_token: self.pub_token.clone(),
+ paren_token: self.paren_token.clone(),
+ in_token: self.in_token.clone(),
+ path: self.path.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::Visibility {
+ fn clone(&self) -> Self {
+ match self {
+ crate::Visibility::Public(v0) => crate::Visibility::Public(v0.clone()),
+ crate::Visibility::Restricted(v0) => {
+ crate::Visibility::Restricted(v0.clone())
+ }
+ crate::Visibility::Inherited => crate::Visibility::Inherited,
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::WhereClause {
+ fn clone(&self) -> Self {
+ crate::WhereClause {
+ where_token: self.where_token.clone(),
+ predicates: self.predicates.clone(),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for crate::WherePredicate {
+ fn clone(&self) -> Self {
+ match self {
+ crate::WherePredicate::Lifetime(v0) => {
+ crate::WherePredicate::Lifetime(v0.clone())
+ }
+ crate::WherePredicate::Type(v0) => crate::WherePredicate::Type(v0.clone()),
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/gen/debug.rs b/rust/hw/char/pl011/vendor/syn/src/gen/debug.rs
new file mode 100644
index 0000000000..9232ece8ac
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/gen/debug.rs
@@ -0,0 +1,3160 @@
+// This file is @generated by syn-internal-codegen.
+// It is not intended for manual editing.
+
+#![allow(unknown_lints, non_local_definitions)]
+use std::fmt::{self, Debug};
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Abi {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Abi");
+ formatter.field("extern_token", &self.extern_token);
+ formatter.field("name", &self.name);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::AngleBracketedGenericArguments {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "AngleBracketedGenericArguments")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::AngleBracketedGenericArguments {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("colon2_token", &self.colon2_token);
+ formatter.field("lt_token", &self.lt_token);
+ formatter.field("args", &self.args);
+ formatter.field("gt_token", &self.gt_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Arm {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Arm");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("pat", &self.pat);
+ formatter.field("guard", &self.guard);
+ formatter.field("fat_arrow_token", &self.fat_arrow_token);
+ formatter.field("body", &self.body);
+ formatter.field("comma", &self.comma);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::AssocConst {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("AssocConst");
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("value", &self.value);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::AssocType {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("AssocType");
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("ty", &self.ty);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::AttrStyle {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("AttrStyle::")?;
+ match self {
+ crate::AttrStyle::Outer => formatter.write_str("Outer"),
+ crate::AttrStyle::Inner(v0) => {
+ let mut formatter = formatter.debug_tuple("Inner");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Attribute {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Attribute");
+ formatter.field("pound_token", &self.pound_token);
+ formatter.field("style", &self.style);
+ formatter.field("bracket_token", &self.bracket_token);
+ formatter.field("meta", &self.meta);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::BareFnArg {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("BareFnArg");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("name", &self.name);
+ formatter.field("ty", &self.ty);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::BareVariadic {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("BareVariadic");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("name", &self.name);
+ formatter.field("dots", &self.dots);
+ formatter.field("comma", &self.comma);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::BinOp {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("BinOp::")?;
+ match self {
+ crate::BinOp::Add(v0) => {
+ let mut formatter = formatter.debug_tuple("Add");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Sub(v0) => {
+ let mut formatter = formatter.debug_tuple("Sub");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Mul(v0) => {
+ let mut formatter = formatter.debug_tuple("Mul");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Div(v0) => {
+ let mut formatter = formatter.debug_tuple("Div");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Rem(v0) => {
+ let mut formatter = formatter.debug_tuple("Rem");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::And(v0) => {
+ let mut formatter = formatter.debug_tuple("And");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Or(v0) => {
+ let mut formatter = formatter.debug_tuple("Or");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::BitXor(v0) => {
+ let mut formatter = formatter.debug_tuple("BitXor");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::BitAnd(v0) => {
+ let mut formatter = formatter.debug_tuple("BitAnd");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::BitOr(v0) => {
+ let mut formatter = formatter.debug_tuple("BitOr");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Shl(v0) => {
+ let mut formatter = formatter.debug_tuple("Shl");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Shr(v0) => {
+ let mut formatter = formatter.debug_tuple("Shr");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Eq(v0) => {
+ let mut formatter = formatter.debug_tuple("Eq");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Lt(v0) => {
+ let mut formatter = formatter.debug_tuple("Lt");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Le(v0) => {
+ let mut formatter = formatter.debug_tuple("Le");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Ne(v0) => {
+ let mut formatter = formatter.debug_tuple("Ne");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Ge(v0) => {
+ let mut formatter = formatter.debug_tuple("Ge");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::Gt(v0) => {
+ let mut formatter = formatter.debug_tuple("Gt");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::AddAssign(v0) => {
+ let mut formatter = formatter.debug_tuple("AddAssign");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::SubAssign(v0) => {
+ let mut formatter = formatter.debug_tuple("SubAssign");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::MulAssign(v0) => {
+ let mut formatter = formatter.debug_tuple("MulAssign");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::DivAssign(v0) => {
+ let mut formatter = formatter.debug_tuple("DivAssign");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::RemAssign(v0) => {
+ let mut formatter = formatter.debug_tuple("RemAssign");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::BitXorAssign(v0) => {
+ let mut formatter = formatter.debug_tuple("BitXorAssign");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::BitAndAssign(v0) => {
+ let mut formatter = formatter.debug_tuple("BitAndAssign");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::BitOrAssign(v0) => {
+ let mut formatter = formatter.debug_tuple("BitOrAssign");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::ShlAssign(v0) => {
+ let mut formatter = formatter.debug_tuple("ShlAssign");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::BinOp::ShrAssign(v0) => {
+ let mut formatter = formatter.debug_tuple("ShrAssign");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Block {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Block");
+ formatter.field("brace_token", &self.brace_token);
+ formatter.field("stmts", &self.stmts);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::BoundLifetimes {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("BoundLifetimes");
+ formatter.field("for_token", &self.for_token);
+ formatter.field("lt_token", &self.lt_token);
+ formatter.field("lifetimes", &self.lifetimes);
+ formatter.field("gt_token", &self.gt_token);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ConstParam {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ConstParam");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("const_token", &self.const_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("ty", &self.ty);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("default", &self.default);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Constraint {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Constraint");
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("bounds", &self.bounds);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Data {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Data::")?;
+ match self {
+ crate::Data::Struct(v0) => v0.debug(formatter, "Struct"),
+ crate::Data::Enum(v0) => v0.debug(formatter, "Enum"),
+ crate::Data::Union(v0) => v0.debug(formatter, "Union"),
+ }
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::DataEnum {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "DataEnum")
+ }
+}
+#[cfg(feature = "derive")]
+impl crate::DataEnum {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("enum_token", &self.enum_token);
+ formatter.field("brace_token", &self.brace_token);
+ formatter.field("variants", &self.variants);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::DataStruct {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "DataStruct")
+ }
+}
+#[cfg(feature = "derive")]
+impl crate::DataStruct {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("struct_token", &self.struct_token);
+ formatter.field("fields", &self.fields);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::DataUnion {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "DataUnion")
+ }
+}
+#[cfg(feature = "derive")]
+impl crate::DataUnion {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("union_token", &self.union_token);
+ formatter.field("fields", &self.fields);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::DeriveInput {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("DeriveInput");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("data", &self.data);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Expr {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Expr::")?;
+ match self {
+ #[cfg(feature = "full")]
+ crate::Expr::Array(v0) => v0.debug(formatter, "Array"),
+ #[cfg(feature = "full")]
+ crate::Expr::Assign(v0) => v0.debug(formatter, "Assign"),
+ #[cfg(feature = "full")]
+ crate::Expr::Async(v0) => v0.debug(formatter, "Async"),
+ #[cfg(feature = "full")]
+ crate::Expr::Await(v0) => v0.debug(formatter, "Await"),
+ crate::Expr::Binary(v0) => v0.debug(formatter, "Binary"),
+ #[cfg(feature = "full")]
+ crate::Expr::Block(v0) => v0.debug(formatter, "Block"),
+ #[cfg(feature = "full")]
+ crate::Expr::Break(v0) => v0.debug(formatter, "Break"),
+ crate::Expr::Call(v0) => v0.debug(formatter, "Call"),
+ crate::Expr::Cast(v0) => v0.debug(formatter, "Cast"),
+ #[cfg(feature = "full")]
+ crate::Expr::Closure(v0) => v0.debug(formatter, "Closure"),
+ #[cfg(feature = "full")]
+ crate::Expr::Const(v0) => v0.debug(formatter, "Const"),
+ #[cfg(feature = "full")]
+ crate::Expr::Continue(v0) => v0.debug(formatter, "Continue"),
+ crate::Expr::Field(v0) => v0.debug(formatter, "Field"),
+ #[cfg(feature = "full")]
+ crate::Expr::ForLoop(v0) => v0.debug(formatter, "ForLoop"),
+ crate::Expr::Group(v0) => v0.debug(formatter, "Group"),
+ #[cfg(feature = "full")]
+ crate::Expr::If(v0) => v0.debug(formatter, "If"),
+ crate::Expr::Index(v0) => v0.debug(formatter, "Index"),
+ #[cfg(feature = "full")]
+ crate::Expr::Infer(v0) => v0.debug(formatter, "Infer"),
+ #[cfg(feature = "full")]
+ crate::Expr::Let(v0) => v0.debug(formatter, "Let"),
+ crate::Expr::Lit(v0) => v0.debug(formatter, "Lit"),
+ #[cfg(feature = "full")]
+ crate::Expr::Loop(v0) => v0.debug(formatter, "Loop"),
+ crate::Expr::Macro(v0) => v0.debug(formatter, "Macro"),
+ #[cfg(feature = "full")]
+ crate::Expr::Match(v0) => v0.debug(formatter, "Match"),
+ crate::Expr::MethodCall(v0) => v0.debug(formatter, "MethodCall"),
+ crate::Expr::Paren(v0) => v0.debug(formatter, "Paren"),
+ crate::Expr::Path(v0) => v0.debug(formatter, "Path"),
+ #[cfg(feature = "full")]
+ crate::Expr::Range(v0) => v0.debug(formatter, "Range"),
+ crate::Expr::Reference(v0) => v0.debug(formatter, "Reference"),
+ #[cfg(feature = "full")]
+ crate::Expr::Repeat(v0) => v0.debug(formatter, "Repeat"),
+ #[cfg(feature = "full")]
+ crate::Expr::Return(v0) => v0.debug(formatter, "Return"),
+ crate::Expr::Struct(v0) => v0.debug(formatter, "Struct"),
+ #[cfg(feature = "full")]
+ crate::Expr::Try(v0) => v0.debug(formatter, "Try"),
+ #[cfg(feature = "full")]
+ crate::Expr::TryBlock(v0) => v0.debug(formatter, "TryBlock"),
+ #[cfg(feature = "full")]
+ crate::Expr::Tuple(v0) => v0.debug(formatter, "Tuple"),
+ crate::Expr::Unary(v0) => v0.debug(formatter, "Unary"),
+ #[cfg(feature = "full")]
+ crate::Expr::Unsafe(v0) => v0.debug(formatter, "Unsafe"),
+ crate::Expr::Verbatim(v0) => {
+ let mut formatter = formatter.debug_tuple("Verbatim");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::While(v0) => v0.debug(formatter, "While"),
+ #[cfg(feature = "full")]
+ crate::Expr::Yield(v0) => v0.debug(formatter, "Yield"),
+ #[cfg(not(feature = "full"))]
+ _ => unreachable!(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprArray {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprArray")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprArray {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("bracket_token", &self.bracket_token);
+ formatter.field("elems", &self.elems);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprAssign {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprAssign")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprAssign {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("left", &self.left);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("right", &self.right);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprAsync {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprAsync")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprAsync {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("async_token", &self.async_token);
+ formatter.field("capture", &self.capture);
+ formatter.field("block", &self.block);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprAwait {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprAwait")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprAwait {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("base", &self.base);
+ formatter.field("dot_token", &self.dot_token);
+ formatter.field("await_token", &self.await_token);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprBinary {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprBinary")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprBinary {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("left", &self.left);
+ formatter.field("op", &self.op);
+ formatter.field("right", &self.right);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprBlock {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprBlock")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprBlock {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("label", &self.label);
+ formatter.field("block", &self.block);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprBreak {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprBreak")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprBreak {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("break_token", &self.break_token);
+ formatter.field("label", &self.label);
+ formatter.field("expr", &self.expr);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprCall {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprCall")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprCall {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("func", &self.func);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("args", &self.args);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprCast {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprCast")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprCast {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("expr", &self.expr);
+ formatter.field("as_token", &self.as_token);
+ formatter.field("ty", &self.ty);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprClosure {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprClosure")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprClosure {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("lifetimes", &self.lifetimes);
+ formatter.field("constness", &self.constness);
+ formatter.field("movability", &self.movability);
+ formatter.field("asyncness", &self.asyncness);
+ formatter.field("capture", &self.capture);
+ formatter.field("or1_token", &self.or1_token);
+ formatter.field("inputs", &self.inputs);
+ formatter.field("or2_token", &self.or2_token);
+ formatter.field("output", &self.output);
+ formatter.field("body", &self.body);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprConst {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprConst")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprConst {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("const_token", &self.const_token);
+ formatter.field("block", &self.block);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprContinue {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprContinue")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprContinue {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("continue_token", &self.continue_token);
+ formatter.field("label", &self.label);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprField {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprField")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprField {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("base", &self.base);
+ formatter.field("dot_token", &self.dot_token);
+ formatter.field("member", &self.member);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprForLoop {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprForLoop")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprForLoop {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("label", &self.label);
+ formatter.field("for_token", &self.for_token);
+ formatter.field("pat", &self.pat);
+ formatter.field("in_token", &self.in_token);
+ formatter.field("expr", &self.expr);
+ formatter.field("body", &self.body);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprGroup {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprGroup")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprGroup {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("group_token", &self.group_token);
+ formatter.field("expr", &self.expr);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprIf {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprIf")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprIf {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("if_token", &self.if_token);
+ formatter.field("cond", &self.cond);
+ formatter.field("then_branch", &self.then_branch);
+ formatter.field("else_branch", &self.else_branch);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprIndex {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprIndex")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprIndex {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("expr", &self.expr);
+ formatter.field("bracket_token", &self.bracket_token);
+ formatter.field("index", &self.index);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprInfer {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprInfer")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprInfer {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("underscore_token", &self.underscore_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprLet {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprLet")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprLet {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("let_token", &self.let_token);
+ formatter.field("pat", &self.pat);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("expr", &self.expr);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprLit {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprLit")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprLit {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("lit", &self.lit);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprLoop {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprLoop")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprLoop {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("label", &self.label);
+ formatter.field("loop_token", &self.loop_token);
+ formatter.field("body", &self.body);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprMacro {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprMacro")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprMacro {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("mac", &self.mac);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprMatch {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprMatch")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprMatch {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("match_token", &self.match_token);
+ formatter.field("expr", &self.expr);
+ formatter.field("brace_token", &self.brace_token);
+ formatter.field("arms", &self.arms);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprMethodCall {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprMethodCall")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprMethodCall {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("receiver", &self.receiver);
+ formatter.field("dot_token", &self.dot_token);
+ formatter.field("method", &self.method);
+ formatter.field("turbofish", &self.turbofish);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("args", &self.args);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprParen {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprParen")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprParen {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("expr", &self.expr);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprPath {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprPath")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprPath {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("qself", &self.qself);
+ formatter.field("path", &self.path);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprRange {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprRange")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprRange {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("start", &self.start);
+ formatter.field("limits", &self.limits);
+ formatter.field("end", &self.end);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprReference {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprReference")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprReference {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("and_token", &self.and_token);
+ formatter.field("mutability", &self.mutability);
+ formatter.field("expr", &self.expr);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprRepeat {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprRepeat")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprRepeat {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("bracket_token", &self.bracket_token);
+ formatter.field("expr", &self.expr);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.field("len", &self.len);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprReturn {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprReturn")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprReturn {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("return_token", &self.return_token);
+ formatter.field("expr", &self.expr);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprStruct {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprStruct")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprStruct {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("qself", &self.qself);
+ formatter.field("path", &self.path);
+ formatter.field("brace_token", &self.brace_token);
+ formatter.field("fields", &self.fields);
+ formatter.field("dot2_token", &self.dot2_token);
+ formatter.field("rest", &self.rest);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprTry {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprTry")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprTry {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("expr", &self.expr);
+ formatter.field("question_token", &self.question_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprTryBlock {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprTryBlock")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprTryBlock {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("try_token", &self.try_token);
+ formatter.field("block", &self.block);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprTuple {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprTuple")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprTuple {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("elems", &self.elems);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprUnary {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprUnary")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ExprUnary {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("op", &self.op);
+ formatter.field("expr", &self.expr);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprUnsafe {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprUnsafe")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprUnsafe {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("unsafe_token", &self.unsafe_token);
+ formatter.field("block", &self.block);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprWhile {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprWhile")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprWhile {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("label", &self.label);
+ formatter.field("while_token", &self.while_token);
+ formatter.field("cond", &self.cond);
+ formatter.field("body", &self.body);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ExprYield {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ExprYield")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ExprYield {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("yield_token", &self.yield_token);
+ formatter.field("expr", &self.expr);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Field {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Field");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("mutability", &self.mutability);
+ formatter.field("ident", &self.ident);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("ty", &self.ty);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::FieldMutability {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("FieldMutability::")?;
+ match self {
+ crate::FieldMutability::None => formatter.write_str("None"),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::FieldPat {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("FieldPat");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("member", &self.member);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("pat", &self.pat);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::FieldValue {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("FieldValue");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("member", &self.member);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("expr", &self.expr);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Fields {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Fields::")?;
+ match self {
+ crate::Fields::Named(v0) => v0.debug(formatter, "Named"),
+ crate::Fields::Unnamed(v0) => v0.debug(formatter, "Unnamed"),
+ crate::Fields::Unit => formatter.write_str("Unit"),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::FieldsNamed {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "FieldsNamed")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::FieldsNamed {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("brace_token", &self.brace_token);
+ formatter.field("named", &self.named);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::FieldsUnnamed {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "FieldsUnnamed")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::FieldsUnnamed {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("unnamed", &self.unnamed);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::File {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("File");
+ formatter.field("shebang", &self.shebang);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("items", &self.items);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::FnArg {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("FnArg::")?;
+ match self {
+ crate::FnArg::Receiver(v0) => {
+ let mut formatter = formatter.debug_tuple("Receiver");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::FnArg::Typed(v0) => {
+ let mut formatter = formatter.debug_tuple("Typed");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ForeignItem {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("ForeignItem::")?;
+ match self {
+ crate::ForeignItem::Fn(v0) => v0.debug(formatter, "Fn"),
+ crate::ForeignItem::Static(v0) => v0.debug(formatter, "Static"),
+ crate::ForeignItem::Type(v0) => v0.debug(formatter, "Type"),
+ crate::ForeignItem::Macro(v0) => v0.debug(formatter, "Macro"),
+ crate::ForeignItem::Verbatim(v0) => {
+ let mut formatter = formatter.debug_tuple("Verbatim");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ForeignItemFn {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ForeignItemFn")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ForeignItemFn {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("sig", &self.sig);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ForeignItemMacro {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ForeignItemMacro")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ForeignItemMacro {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("mac", &self.mac);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ForeignItemStatic {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ForeignItemStatic")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ForeignItemStatic {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("static_token", &self.static_token);
+ formatter.field("mutability", &self.mutability);
+ formatter.field("ident", &self.ident);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("ty", &self.ty);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ForeignItemType {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ForeignItemType")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ForeignItemType {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("type_token", &self.type_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::GenericArgument {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("GenericArgument::")?;
+ match self {
+ crate::GenericArgument::Lifetime(v0) => {
+ let mut formatter = formatter.debug_tuple("Lifetime");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::GenericArgument::Type(v0) => {
+ let mut formatter = formatter.debug_tuple("Type");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::GenericArgument::Const(v0) => {
+ let mut formatter = formatter.debug_tuple("Const");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::GenericArgument::AssocType(v0) => {
+ let mut formatter = formatter.debug_tuple("AssocType");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::GenericArgument::AssocConst(v0) => {
+ let mut formatter = formatter.debug_tuple("AssocConst");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::GenericArgument::Constraint(v0) => {
+ let mut formatter = formatter.debug_tuple("Constraint");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::GenericParam {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("GenericParam::")?;
+ match self {
+ crate::GenericParam::Lifetime(v0) => {
+ let mut formatter = formatter.debug_tuple("Lifetime");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::GenericParam::Type(v0) => {
+ let mut formatter = formatter.debug_tuple("Type");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::GenericParam::Const(v0) => {
+ let mut formatter = formatter.debug_tuple("Const");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Generics {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Generics");
+ formatter.field("lt_token", &self.lt_token);
+ formatter.field("params", &self.params);
+ formatter.field("gt_token", &self.gt_token);
+ formatter.field("where_clause", &self.where_clause);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ImplItem {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("ImplItem::")?;
+ match self {
+ crate::ImplItem::Const(v0) => v0.debug(formatter, "Const"),
+ crate::ImplItem::Fn(v0) => v0.debug(formatter, "Fn"),
+ crate::ImplItem::Type(v0) => v0.debug(formatter, "Type"),
+ crate::ImplItem::Macro(v0) => v0.debug(formatter, "Macro"),
+ crate::ImplItem::Verbatim(v0) => {
+ let mut formatter = formatter.debug_tuple("Verbatim");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ImplItemConst {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ImplItemConst")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ImplItemConst {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("defaultness", &self.defaultness);
+ formatter.field("const_token", &self.const_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("ty", &self.ty);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("expr", &self.expr);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ImplItemFn {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ImplItemFn")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ImplItemFn {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("defaultness", &self.defaultness);
+ formatter.field("sig", &self.sig);
+ formatter.field("block", &self.block);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ImplItemMacro {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ImplItemMacro")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ImplItemMacro {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("mac", &self.mac);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ImplItemType {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ImplItemType")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ImplItemType {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("defaultness", &self.defaultness);
+ formatter.field("type_token", &self.type_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("ty", &self.ty);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ImplRestriction {
+ fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
+ match *self {}
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Index {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Index");
+ formatter.field("index", &self.index);
+ formatter.field("span", &self.span);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Item {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Item::")?;
+ match self {
+ crate::Item::Const(v0) => v0.debug(formatter, "Const"),
+ crate::Item::Enum(v0) => v0.debug(formatter, "Enum"),
+ crate::Item::ExternCrate(v0) => v0.debug(formatter, "ExternCrate"),
+ crate::Item::Fn(v0) => v0.debug(formatter, "Fn"),
+ crate::Item::ForeignMod(v0) => v0.debug(formatter, "ForeignMod"),
+ crate::Item::Impl(v0) => v0.debug(formatter, "Impl"),
+ crate::Item::Macro(v0) => v0.debug(formatter, "Macro"),
+ crate::Item::Mod(v0) => v0.debug(formatter, "Mod"),
+ crate::Item::Static(v0) => v0.debug(formatter, "Static"),
+ crate::Item::Struct(v0) => v0.debug(formatter, "Struct"),
+ crate::Item::Trait(v0) => v0.debug(formatter, "Trait"),
+ crate::Item::TraitAlias(v0) => v0.debug(formatter, "TraitAlias"),
+ crate::Item::Type(v0) => v0.debug(formatter, "Type"),
+ crate::Item::Union(v0) => v0.debug(formatter, "Union"),
+ crate::Item::Use(v0) => v0.debug(formatter, "Use"),
+ crate::Item::Verbatim(v0) => {
+ let mut formatter = formatter.debug_tuple("Verbatim");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemConst {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemConst")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemConst {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("const_token", &self.const_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("ty", &self.ty);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("expr", &self.expr);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemEnum {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemEnum")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemEnum {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("enum_token", &self.enum_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("brace_token", &self.brace_token);
+ formatter.field("variants", &self.variants);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemExternCrate {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemExternCrate")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemExternCrate {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("extern_token", &self.extern_token);
+ formatter.field("crate_token", &self.crate_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("rename", &self.rename);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemFn {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemFn")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemFn {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("sig", &self.sig);
+ formatter.field("block", &self.block);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemForeignMod {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemForeignMod")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemForeignMod {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("unsafety", &self.unsafety);
+ formatter.field("abi", &self.abi);
+ formatter.field("brace_token", &self.brace_token);
+ formatter.field("items", &self.items);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemImpl {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemImpl")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemImpl {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("defaultness", &self.defaultness);
+ formatter.field("unsafety", &self.unsafety);
+ formatter.field("impl_token", &self.impl_token);
+ formatter.field("generics", &self.generics);
+ formatter.field("trait_", &self.trait_);
+ formatter.field("self_ty", &self.self_ty);
+ formatter.field("brace_token", &self.brace_token);
+ formatter.field("items", &self.items);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemMacro {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemMacro")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemMacro {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("ident", &self.ident);
+ formatter.field("mac", &self.mac);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemMod {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemMod")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemMod {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("unsafety", &self.unsafety);
+ formatter.field("mod_token", &self.mod_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("content", &self.content);
+ formatter.field("semi", &self.semi);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemStatic {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemStatic")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemStatic {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("static_token", &self.static_token);
+ formatter.field("mutability", &self.mutability);
+ formatter.field("ident", &self.ident);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("ty", &self.ty);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("expr", &self.expr);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemStruct {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemStruct")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemStruct {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("struct_token", &self.struct_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("fields", &self.fields);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemTrait {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemTrait")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemTrait {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("unsafety", &self.unsafety);
+ formatter.field("auto_token", &self.auto_token);
+ formatter.field("restriction", &self.restriction);
+ formatter.field("trait_token", &self.trait_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("supertraits", &self.supertraits);
+ formatter.field("brace_token", &self.brace_token);
+ formatter.field("items", &self.items);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemTraitAlias {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemTraitAlias")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemTraitAlias {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("trait_token", &self.trait_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("bounds", &self.bounds);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemType {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemType")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemType {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("type_token", &self.type_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("ty", &self.ty);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemUnion {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemUnion")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemUnion {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("union_token", &self.union_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("fields", &self.fields);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ItemUse {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ItemUse")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::ItemUse {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("vis", &self.vis);
+ formatter.field("use_token", &self.use_token);
+ formatter.field("leading_colon", &self.leading_colon);
+ formatter.field("tree", &self.tree);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Label {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Label");
+ formatter.field("name", &self.name);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.finish()
+ }
+}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Lifetime {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "Lifetime")
+ }
+}
+impl crate::Lifetime {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("apostrophe", &self.apostrophe);
+ formatter.field("ident", &self.ident);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::LifetimeParam {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("LifetimeParam");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("lifetime", &self.lifetime);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("bounds", &self.bounds);
+ formatter.finish()
+ }
+}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Lit {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Lit::")?;
+ match self {
+ crate::Lit::Str(v0) => v0.debug(formatter, "Str"),
+ crate::Lit::ByteStr(v0) => v0.debug(formatter, "ByteStr"),
+ crate::Lit::CStr(v0) => v0.debug(formatter, "CStr"),
+ crate::Lit::Byte(v0) => v0.debug(formatter, "Byte"),
+ crate::Lit::Char(v0) => v0.debug(formatter, "Char"),
+ crate::Lit::Int(v0) => v0.debug(formatter, "Int"),
+ crate::Lit::Float(v0) => v0.debug(formatter, "Float"),
+ crate::Lit::Bool(v0) => v0.debug(formatter, "Bool"),
+ crate::Lit::Verbatim(v0) => {
+ let mut formatter = formatter.debug_tuple("Verbatim");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Local {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "Local")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::Local {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("let_token", &self.let_token);
+ formatter.field("pat", &self.pat);
+ formatter.field("init", &self.init);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::LocalInit {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("LocalInit");
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("expr", &self.expr);
+ formatter.field("diverge", &self.diverge);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Macro {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Macro");
+ formatter.field("path", &self.path);
+ formatter.field("bang_token", &self.bang_token);
+ formatter.field("delimiter", &self.delimiter);
+ formatter.field("tokens", &self.tokens);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::MacroDelimiter {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("MacroDelimiter::")?;
+ match self {
+ crate::MacroDelimiter::Paren(v0) => {
+ let mut formatter = formatter.debug_tuple("Paren");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::MacroDelimiter::Brace(v0) => {
+ let mut formatter = formatter.debug_tuple("Brace");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::MacroDelimiter::Bracket(v0) => {
+ let mut formatter = formatter.debug_tuple("Bracket");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Member {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Member::")?;
+ match self {
+ crate::Member::Named(v0) => {
+ let mut formatter = formatter.debug_tuple("Named");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::Member::Unnamed(v0) => {
+ let mut formatter = formatter.debug_tuple("Unnamed");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Meta {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Meta::")?;
+ match self {
+ crate::Meta::Path(v0) => v0.debug(formatter, "Path"),
+ crate::Meta::List(v0) => v0.debug(formatter, "List"),
+ crate::Meta::NameValue(v0) => v0.debug(formatter, "NameValue"),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::MetaList {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "MetaList")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::MetaList {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("path", &self.path);
+ formatter.field("delimiter", &self.delimiter);
+ formatter.field("tokens", &self.tokens);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::MetaNameValue {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "MetaNameValue")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::MetaNameValue {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("path", &self.path);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("value", &self.value);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ParenthesizedGenericArguments {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "ParenthesizedGenericArguments")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::ParenthesizedGenericArguments {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("inputs", &self.inputs);
+ formatter.field("output", &self.output);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Pat {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Pat::")?;
+ match self {
+ crate::Pat::Const(v0) => v0.debug(formatter, "Const"),
+ crate::Pat::Ident(v0) => v0.debug(formatter, "Ident"),
+ crate::Pat::Lit(v0) => v0.debug(formatter, "Lit"),
+ crate::Pat::Macro(v0) => v0.debug(formatter, "Macro"),
+ crate::Pat::Or(v0) => v0.debug(formatter, "Or"),
+ crate::Pat::Paren(v0) => v0.debug(formatter, "Paren"),
+ crate::Pat::Path(v0) => v0.debug(formatter, "Path"),
+ crate::Pat::Range(v0) => v0.debug(formatter, "Range"),
+ crate::Pat::Reference(v0) => v0.debug(formatter, "Reference"),
+ crate::Pat::Rest(v0) => v0.debug(formatter, "Rest"),
+ crate::Pat::Slice(v0) => v0.debug(formatter, "Slice"),
+ crate::Pat::Struct(v0) => v0.debug(formatter, "Struct"),
+ crate::Pat::Tuple(v0) => v0.debug(formatter, "Tuple"),
+ crate::Pat::TupleStruct(v0) => v0.debug(formatter, "TupleStruct"),
+ crate::Pat::Type(v0) => v0.debug(formatter, "Type"),
+ crate::Pat::Verbatim(v0) => {
+ let mut formatter = formatter.debug_tuple("Verbatim");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::Pat::Wild(v0) => v0.debug(formatter, "Wild"),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PatIdent {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "PatIdent")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::PatIdent {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("by_ref", &self.by_ref);
+ formatter.field("mutability", &self.mutability);
+ formatter.field("ident", &self.ident);
+ formatter.field("subpat", &self.subpat);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PatOr {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "PatOr")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::PatOr {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("leading_vert", &self.leading_vert);
+ formatter.field("cases", &self.cases);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PatParen {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "PatParen")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::PatParen {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("pat", &self.pat);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PatReference {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "PatReference")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::PatReference {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("and_token", &self.and_token);
+ formatter.field("mutability", &self.mutability);
+ formatter.field("pat", &self.pat);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PatRest {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "PatRest")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::PatRest {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("dot2_token", &self.dot2_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PatSlice {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "PatSlice")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::PatSlice {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("bracket_token", &self.bracket_token);
+ formatter.field("elems", &self.elems);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PatStruct {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "PatStruct")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::PatStruct {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("qself", &self.qself);
+ formatter.field("path", &self.path);
+ formatter.field("brace_token", &self.brace_token);
+ formatter.field("fields", &self.fields);
+ formatter.field("rest", &self.rest);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PatTuple {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "PatTuple")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::PatTuple {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("elems", &self.elems);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PatTupleStruct {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "PatTupleStruct")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::PatTupleStruct {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("qself", &self.qself);
+ formatter.field("path", &self.path);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("elems", &self.elems);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PatType {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "PatType")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::PatType {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("pat", &self.pat);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("ty", &self.ty);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PatWild {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "PatWild")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::PatWild {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("underscore_token", &self.underscore_token);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Path {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "Path")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::Path {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("leading_colon", &self.leading_colon);
+ formatter.field("segments", &self.segments);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PathArguments {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("PathArguments::")?;
+ match self {
+ crate::PathArguments::None => formatter.write_str("None"),
+ crate::PathArguments::AngleBracketed(v0) => {
+ v0.debug(formatter, "AngleBracketed")
+ }
+ crate::PathArguments::Parenthesized(v0) => {
+ v0.debug(formatter, "Parenthesized")
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PathSegment {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PathSegment");
+ formatter.field("ident", &self.ident);
+ formatter.field("arguments", &self.arguments);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PredicateLifetime {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PredicateLifetime");
+ formatter.field("lifetime", &self.lifetime);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("bounds", &self.bounds);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::PredicateType {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PredicateType");
+ formatter.field("lifetimes", &self.lifetimes);
+ formatter.field("bounded_ty", &self.bounded_ty);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("bounds", &self.bounds);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::QSelf {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("QSelf");
+ formatter.field("lt_token", &self.lt_token);
+ formatter.field("ty", &self.ty);
+ formatter.field("position", &self.position);
+ formatter.field("as_token", &self.as_token);
+ formatter.field("gt_token", &self.gt_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::RangeLimits {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("RangeLimits::")?;
+ match self {
+ crate::RangeLimits::HalfOpen(v0) => {
+ let mut formatter = formatter.debug_tuple("HalfOpen");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::RangeLimits::Closed(v0) => {
+ let mut formatter = formatter.debug_tuple("Closed");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Receiver {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Receiver");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("reference", &self.reference);
+ formatter.field("mutability", &self.mutability);
+ formatter.field("self_token", &self.self_token);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("ty", &self.ty);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::ReturnType {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("ReturnType::")?;
+ match self {
+ crate::ReturnType::Default => formatter.write_str("Default"),
+ crate::ReturnType::Type(v0, v1) => {
+ let mut formatter = formatter.debug_tuple("Type");
+ formatter.field(v0);
+ formatter.field(v1);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Signature {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Signature");
+ formatter.field("constness", &self.constness);
+ formatter.field("asyncness", &self.asyncness);
+ formatter.field("unsafety", &self.unsafety);
+ formatter.field("abi", &self.abi);
+ formatter.field("fn_token", &self.fn_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("inputs", &self.inputs);
+ formatter.field("variadic", &self.variadic);
+ formatter.field("output", &self.output);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::StaticMutability {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("StaticMutability::")?;
+ match self {
+ crate::StaticMutability::Mut(v0) => {
+ let mut formatter = formatter.debug_tuple("Mut");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::StaticMutability::None => formatter.write_str("None"),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Stmt {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Stmt::")?;
+ match self {
+ crate::Stmt::Local(v0) => v0.debug(formatter, "Local"),
+ crate::Stmt::Item(v0) => {
+ let mut formatter = formatter.debug_tuple("Item");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::Stmt::Expr(v0, v1) => {
+ let mut formatter = formatter.debug_tuple("Expr");
+ formatter.field(v0);
+ formatter.field(v1);
+ formatter.finish()
+ }
+ crate::Stmt::Macro(v0) => v0.debug(formatter, "Macro"),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::StmtMacro {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "StmtMacro")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::StmtMacro {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("mac", &self.mac);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TraitBound {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TraitBound");
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("modifier", &self.modifier);
+ formatter.field("lifetimes", &self.lifetimes);
+ formatter.field("path", &self.path);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TraitBoundModifier {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("TraitBoundModifier::")?;
+ match self {
+ crate::TraitBoundModifier::None => formatter.write_str("None"),
+ crate::TraitBoundModifier::Maybe(v0) => {
+ let mut formatter = formatter.debug_tuple("Maybe");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TraitItem {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("TraitItem::")?;
+ match self {
+ crate::TraitItem::Const(v0) => v0.debug(formatter, "Const"),
+ crate::TraitItem::Fn(v0) => v0.debug(formatter, "Fn"),
+ crate::TraitItem::Type(v0) => v0.debug(formatter, "Type"),
+ crate::TraitItem::Macro(v0) => v0.debug(formatter, "Macro"),
+ crate::TraitItem::Verbatim(v0) => {
+ let mut formatter = formatter.debug_tuple("Verbatim");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TraitItemConst {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TraitItemConst")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::TraitItemConst {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("const_token", &self.const_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("ty", &self.ty);
+ formatter.field("default", &self.default);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TraitItemFn {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TraitItemFn")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::TraitItemFn {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("sig", &self.sig);
+ formatter.field("default", &self.default);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TraitItemMacro {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TraitItemMacro")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::TraitItemMacro {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("mac", &self.mac);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TraitItemType {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TraitItemType")
+ }
+}
+#[cfg(feature = "full")]
+impl crate::TraitItemType {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("attrs", &self.attrs);
+ formatter.field("type_token", &self.type_token);
+ formatter.field("ident", &self.ident);
+ formatter.field("generics", &self.generics);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("bounds", &self.bounds);
+ formatter.field("default", &self.default);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Type {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Type::")?;
+ match self {
+ crate::Type::Array(v0) => v0.debug(formatter, "Array"),
+ crate::Type::BareFn(v0) => v0.debug(formatter, "BareFn"),
+ crate::Type::Group(v0) => v0.debug(formatter, "Group"),
+ crate::Type::ImplTrait(v0) => v0.debug(formatter, "ImplTrait"),
+ crate::Type::Infer(v0) => v0.debug(formatter, "Infer"),
+ crate::Type::Macro(v0) => v0.debug(formatter, "Macro"),
+ crate::Type::Never(v0) => v0.debug(formatter, "Never"),
+ crate::Type::Paren(v0) => v0.debug(formatter, "Paren"),
+ crate::Type::Path(v0) => v0.debug(formatter, "Path"),
+ crate::Type::Ptr(v0) => v0.debug(formatter, "Ptr"),
+ crate::Type::Reference(v0) => v0.debug(formatter, "Reference"),
+ crate::Type::Slice(v0) => v0.debug(formatter, "Slice"),
+ crate::Type::TraitObject(v0) => v0.debug(formatter, "TraitObject"),
+ crate::Type::Tuple(v0) => v0.debug(formatter, "Tuple"),
+ crate::Type::Verbatim(v0) => {
+ let mut formatter = formatter.debug_tuple("Verbatim");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeArray {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypeArray")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypeArray {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("bracket_token", &self.bracket_token);
+ formatter.field("elem", &self.elem);
+ formatter.field("semi_token", &self.semi_token);
+ formatter.field("len", &self.len);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeBareFn {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypeBareFn")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypeBareFn {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("lifetimes", &self.lifetimes);
+ formatter.field("unsafety", &self.unsafety);
+ formatter.field("abi", &self.abi);
+ formatter.field("fn_token", &self.fn_token);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("inputs", &self.inputs);
+ formatter.field("variadic", &self.variadic);
+ formatter.field("output", &self.output);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeGroup {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypeGroup")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypeGroup {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("group_token", &self.group_token);
+ formatter.field("elem", &self.elem);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeImplTrait {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypeImplTrait")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypeImplTrait {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("impl_token", &self.impl_token);
+ formatter.field("bounds", &self.bounds);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeInfer {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypeInfer")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypeInfer {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("underscore_token", &self.underscore_token);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeMacro {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypeMacro")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypeMacro {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("mac", &self.mac);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeNever {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypeNever")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypeNever {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("bang_token", &self.bang_token);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeParam {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeParam");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("ident", &self.ident);
+ formatter.field("colon_token", &self.colon_token);
+ formatter.field("bounds", &self.bounds);
+ formatter.field("eq_token", &self.eq_token);
+ formatter.field("default", &self.default);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeParamBound {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("TypeParamBound::")?;
+ match self {
+ crate::TypeParamBound::Trait(v0) => {
+ let mut formatter = formatter.debug_tuple("Trait");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::TypeParamBound::Lifetime(v0) => v0.debug(formatter, "Lifetime"),
+ crate::TypeParamBound::Verbatim(v0) => {
+ let mut formatter = formatter.debug_tuple("Verbatim");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeParen {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypeParen")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypeParen {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("elem", &self.elem);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypePath {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypePath")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypePath {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("qself", &self.qself);
+ formatter.field("path", &self.path);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypePtr {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypePtr")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypePtr {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("star_token", &self.star_token);
+ formatter.field("const_token", &self.const_token);
+ formatter.field("mutability", &self.mutability);
+ formatter.field("elem", &self.elem);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeReference {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypeReference")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypeReference {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("and_token", &self.and_token);
+ formatter.field("lifetime", &self.lifetime);
+ formatter.field("mutability", &self.mutability);
+ formatter.field("elem", &self.elem);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeSlice {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypeSlice")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypeSlice {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("bracket_token", &self.bracket_token);
+ formatter.field("elem", &self.elem);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeTraitObject {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypeTraitObject")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypeTraitObject {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("dyn_token", &self.dyn_token);
+ formatter.field("bounds", &self.bounds);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::TypeTuple {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "TypeTuple")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::TypeTuple {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("elems", &self.elems);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::UnOp {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("UnOp::")?;
+ match self {
+ crate::UnOp::Deref(v0) => {
+ let mut formatter = formatter.debug_tuple("Deref");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::UnOp::Not(v0) => {
+ let mut formatter = formatter.debug_tuple("Not");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::UnOp::Neg(v0) => {
+ let mut formatter = formatter.debug_tuple("Neg");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::UseGlob {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("UseGlob");
+ formatter.field("star_token", &self.star_token);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::UseGroup {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("UseGroup");
+ formatter.field("brace_token", &self.brace_token);
+ formatter.field("items", &self.items);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::UseName {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("UseName");
+ formatter.field("ident", &self.ident);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::UsePath {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("UsePath");
+ formatter.field("ident", &self.ident);
+ formatter.field("colon2_token", &self.colon2_token);
+ formatter.field("tree", &self.tree);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::UseRename {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("UseRename");
+ formatter.field("ident", &self.ident);
+ formatter.field("as_token", &self.as_token);
+ formatter.field("rename", &self.rename);
+ formatter.finish()
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::UseTree {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("UseTree::")?;
+ match self {
+ crate::UseTree::Path(v0) => {
+ let mut formatter = formatter.debug_tuple("Path");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::UseTree::Name(v0) => {
+ let mut formatter = formatter.debug_tuple("Name");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::UseTree::Rename(v0) => {
+ let mut formatter = formatter.debug_tuple("Rename");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::UseTree::Glob(v0) => {
+ let mut formatter = formatter.debug_tuple("Glob");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::UseTree::Group(v0) => {
+ let mut formatter = formatter.debug_tuple("Group");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Variadic {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Variadic");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("pat", &self.pat);
+ formatter.field("dots", &self.dots);
+ formatter.field("comma", &self.comma);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Variant {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Variant");
+ formatter.field("attrs", &self.attrs);
+ formatter.field("ident", &self.ident);
+ formatter.field("fields", &self.fields);
+ formatter.field("discriminant", &self.discriminant);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::VisRestricted {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "VisRestricted")
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+impl crate::VisRestricted {
+ fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ let mut formatter = formatter.debug_struct(name);
+ formatter.field("pub_token", &self.pub_token);
+ formatter.field("paren_token", &self.paren_token);
+ formatter.field("in_token", &self.in_token);
+ formatter.field("path", &self.path);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::Visibility {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Visibility::")?;
+ match self {
+ crate::Visibility::Public(v0) => {
+ let mut formatter = formatter.debug_tuple("Public");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::Visibility::Restricted(v0) => v0.debug(formatter, "Restricted"),
+ crate::Visibility::Inherited => formatter.write_str("Inherited"),
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::WhereClause {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("WhereClause");
+ formatter.field("where_token", &self.where_token);
+ formatter.field("predicates", &self.predicates);
+ formatter.finish()
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for crate::WherePredicate {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("WherePredicate::")?;
+ match self {
+ crate::WherePredicate::Lifetime(v0) => {
+ let mut formatter = formatter.debug_tuple("Lifetime");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ crate::WherePredicate::Type(v0) => {
+ let mut formatter = formatter.debug_tuple("Type");
+ formatter.field(v0);
+ formatter.finish()
+ }
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/gen/eq.rs b/rust/hw/char/pl011/vendor/syn/src/gen/eq.rs
new file mode 100644
index 0000000000..bbcca47281
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/gen/eq.rs
@@ -0,0 +1,2242 @@
+// This file is @generated by syn-internal-codegen.
+// It is not intended for manual editing.
+
+#[cfg(any(feature = "derive", feature = "full"))]
+use crate::tt::TokenStreamHelper;
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Abi {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Abi {
+ fn eq(&self, other: &Self) -> bool {
+ self.name == other.name
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::AngleBracketedGenericArguments {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::AngleBracketedGenericArguments {
+ fn eq(&self, other: &Self) -> bool {
+ self.colon2_token == other.colon2_token && self.args == other.args
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Arm {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Arm {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.pat == other.pat && self.guard == other.guard
+ && self.body == other.body && self.comma == other.comma
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::AssocConst {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::AssocConst {
+ fn eq(&self, other: &Self) -> bool {
+ self.ident == other.ident && self.generics == other.generics
+ && self.value == other.value
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::AssocType {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::AssocType {
+ fn eq(&self, other: &Self) -> bool {
+ self.ident == other.ident && self.generics == other.generics
+ && self.ty == other.ty
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::AttrStyle {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::AttrStyle {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::AttrStyle::Outer, crate::AttrStyle::Outer) => true,
+ (crate::AttrStyle::Inner(_), crate::AttrStyle::Inner(_)) => true,
+ _ => false,
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Attribute {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Attribute {
+ fn eq(&self, other: &Self) -> bool {
+ self.style == other.style && self.meta == other.meta
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::BareFnArg {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::BareFnArg {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.name == other.name && self.ty == other.ty
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::BareVariadic {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::BareVariadic {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.name == other.name && self.comma == other.comma
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::BinOp {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::BinOp {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::BinOp::Add(_), crate::BinOp::Add(_)) => true,
+ (crate::BinOp::Sub(_), crate::BinOp::Sub(_)) => true,
+ (crate::BinOp::Mul(_), crate::BinOp::Mul(_)) => true,
+ (crate::BinOp::Div(_), crate::BinOp::Div(_)) => true,
+ (crate::BinOp::Rem(_), crate::BinOp::Rem(_)) => true,
+ (crate::BinOp::And(_), crate::BinOp::And(_)) => true,
+ (crate::BinOp::Or(_), crate::BinOp::Or(_)) => true,
+ (crate::BinOp::BitXor(_), crate::BinOp::BitXor(_)) => true,
+ (crate::BinOp::BitAnd(_), crate::BinOp::BitAnd(_)) => true,
+ (crate::BinOp::BitOr(_), crate::BinOp::BitOr(_)) => true,
+ (crate::BinOp::Shl(_), crate::BinOp::Shl(_)) => true,
+ (crate::BinOp::Shr(_), crate::BinOp::Shr(_)) => true,
+ (crate::BinOp::Eq(_), crate::BinOp::Eq(_)) => true,
+ (crate::BinOp::Lt(_), crate::BinOp::Lt(_)) => true,
+ (crate::BinOp::Le(_), crate::BinOp::Le(_)) => true,
+ (crate::BinOp::Ne(_), crate::BinOp::Ne(_)) => true,
+ (crate::BinOp::Ge(_), crate::BinOp::Ge(_)) => true,
+ (crate::BinOp::Gt(_), crate::BinOp::Gt(_)) => true,
+ (crate::BinOp::AddAssign(_), crate::BinOp::AddAssign(_)) => true,
+ (crate::BinOp::SubAssign(_), crate::BinOp::SubAssign(_)) => true,
+ (crate::BinOp::MulAssign(_), crate::BinOp::MulAssign(_)) => true,
+ (crate::BinOp::DivAssign(_), crate::BinOp::DivAssign(_)) => true,
+ (crate::BinOp::RemAssign(_), crate::BinOp::RemAssign(_)) => true,
+ (crate::BinOp::BitXorAssign(_), crate::BinOp::BitXorAssign(_)) => true,
+ (crate::BinOp::BitAndAssign(_), crate::BinOp::BitAndAssign(_)) => true,
+ (crate::BinOp::BitOrAssign(_), crate::BinOp::BitOrAssign(_)) => true,
+ (crate::BinOp::ShlAssign(_), crate::BinOp::ShlAssign(_)) => true,
+ (crate::BinOp::ShrAssign(_), crate::BinOp::ShrAssign(_)) => true,
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Block {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Block {
+ fn eq(&self, other: &Self) -> bool {
+ self.stmts == other.stmts
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::BoundLifetimes {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::BoundLifetimes {
+ fn eq(&self, other: &Self) -> bool {
+ self.lifetimes == other.lifetimes
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ConstParam {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ConstParam {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.ident == other.ident && self.ty == other.ty
+ && self.eq_token == other.eq_token && self.default == other.default
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Constraint {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Constraint {
+ fn eq(&self, other: &Self) -> bool {
+ self.ident == other.ident && self.generics == other.generics
+ && self.bounds == other.bounds
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Data {}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Data {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::Data::Struct(self0), crate::Data::Struct(other0)) => self0 == other0,
+ (crate::Data::Enum(self0), crate::Data::Enum(other0)) => self0 == other0,
+ (crate::Data::Union(self0), crate::Data::Union(other0)) => self0 == other0,
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::DataEnum {}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::DataEnum {
+ fn eq(&self, other: &Self) -> bool {
+ self.variants == other.variants
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::DataStruct {}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::DataStruct {
+ fn eq(&self, other: &Self) -> bool {
+ self.fields == other.fields && self.semi_token == other.semi_token
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::DataUnion {}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::DataUnion {
+ fn eq(&self, other: &Self) -> bool {
+ self.fields == other.fields
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::DeriveInput {}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::DeriveInput {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis && self.ident == other.ident
+ && self.generics == other.generics && self.data == other.data
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Expr {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Expr {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ #[cfg(feature = "full")]
+ (crate::Expr::Array(self0), crate::Expr::Array(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Assign(self0), crate::Expr::Assign(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Async(self0), crate::Expr::Async(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Await(self0), crate::Expr::Await(other0)) => self0 == other0,
+ (crate::Expr::Binary(self0), crate::Expr::Binary(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Block(self0), crate::Expr::Block(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Break(self0), crate::Expr::Break(other0)) => self0 == other0,
+ (crate::Expr::Call(self0), crate::Expr::Call(other0)) => self0 == other0,
+ (crate::Expr::Cast(self0), crate::Expr::Cast(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Closure(self0), crate::Expr::Closure(other0)) => {
+ self0 == other0
+ }
+ #[cfg(feature = "full")]
+ (crate::Expr::Const(self0), crate::Expr::Const(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Continue(self0), crate::Expr::Continue(other0)) => {
+ self0 == other0
+ }
+ (crate::Expr::Field(self0), crate::Expr::Field(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::ForLoop(self0), crate::Expr::ForLoop(other0)) => {
+ self0 == other0
+ }
+ (crate::Expr::Group(self0), crate::Expr::Group(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::If(self0), crate::Expr::If(other0)) => self0 == other0,
+ (crate::Expr::Index(self0), crate::Expr::Index(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Infer(self0), crate::Expr::Infer(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Let(self0), crate::Expr::Let(other0)) => self0 == other0,
+ (crate::Expr::Lit(self0), crate::Expr::Lit(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Loop(self0), crate::Expr::Loop(other0)) => self0 == other0,
+ (crate::Expr::Macro(self0), crate::Expr::Macro(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Match(self0), crate::Expr::Match(other0)) => self0 == other0,
+ (crate::Expr::MethodCall(self0), crate::Expr::MethodCall(other0)) => {
+ self0 == other0
+ }
+ (crate::Expr::Paren(self0), crate::Expr::Paren(other0)) => self0 == other0,
+ (crate::Expr::Path(self0), crate::Expr::Path(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Range(self0), crate::Expr::Range(other0)) => self0 == other0,
+ (crate::Expr::Reference(self0), crate::Expr::Reference(other0)) => {
+ self0 == other0
+ }
+ #[cfg(feature = "full")]
+ (crate::Expr::Repeat(self0), crate::Expr::Repeat(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Return(self0), crate::Expr::Return(other0)) => self0 == other0,
+ (crate::Expr::Struct(self0), crate::Expr::Struct(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Try(self0), crate::Expr::Try(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::TryBlock(self0), crate::Expr::TryBlock(other0)) => {
+ self0 == other0
+ }
+ #[cfg(feature = "full")]
+ (crate::Expr::Tuple(self0), crate::Expr::Tuple(other0)) => self0 == other0,
+ (crate::Expr::Unary(self0), crate::Expr::Unary(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Unsafe(self0), crate::Expr::Unsafe(other0)) => self0 == other0,
+ (crate::Expr::Verbatim(self0), crate::Expr::Verbatim(other0)) => {
+ TokenStreamHelper(self0) == TokenStreamHelper(other0)
+ }
+ #[cfg(feature = "full")]
+ (crate::Expr::While(self0), crate::Expr::While(other0)) => self0 == other0,
+ #[cfg(feature = "full")]
+ (crate::Expr::Yield(self0), crate::Expr::Yield(other0)) => self0 == other0,
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprArray {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprArray {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.elems == other.elems
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprAssign {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprAssign {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.left == other.left && self.right == other.right
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprAsync {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprAsync {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.capture == other.capture
+ && self.block == other.block
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprAwait {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprAwait {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.base == other.base
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprBinary {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprBinary {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.left == other.left && self.op == other.op
+ && self.right == other.right
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprBlock {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprBlock {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.label == other.label
+ && self.block == other.block
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprBreak {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprBreak {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.label == other.label && self.expr == other.expr
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprCall {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprCall {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.func == other.func && self.args == other.args
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprCast {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprCast {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.expr == other.expr && self.ty == other.ty
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprClosure {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprClosure {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.lifetimes == other.lifetimes
+ && self.constness == other.constness && self.movability == other.movability
+ && self.asyncness == other.asyncness && self.capture == other.capture
+ && self.inputs == other.inputs && self.output == other.output
+ && self.body == other.body
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprConst {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprConst {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.block == other.block
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprContinue {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprContinue {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.label == other.label
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprField {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprField {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.base == other.base
+ && self.member == other.member
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprForLoop {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprForLoop {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.label == other.label && self.pat == other.pat
+ && self.expr == other.expr && self.body == other.body
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprGroup {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprGroup {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.expr == other.expr
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprIf {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprIf {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.cond == other.cond
+ && self.then_branch == other.then_branch
+ && self.else_branch == other.else_branch
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprIndex {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprIndex {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.expr == other.expr && self.index == other.index
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprInfer {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprInfer {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprLet {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprLet {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.pat == other.pat && self.expr == other.expr
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprLit {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprLit {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.lit == other.lit
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprLoop {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprLoop {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.label == other.label && self.body == other.body
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprMacro {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprMacro {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.mac == other.mac
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprMatch {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprMatch {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.expr == other.expr && self.arms == other.arms
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprMethodCall {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprMethodCall {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.receiver == other.receiver
+ && self.method == other.method && self.turbofish == other.turbofish
+ && self.args == other.args
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprParen {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprParen {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.expr == other.expr
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprPath {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprPath {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.qself == other.qself && self.path == other.path
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprRange {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprRange {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.start == other.start
+ && self.limits == other.limits && self.end == other.end
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprReference {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprReference {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.mutability == other.mutability
+ && self.expr == other.expr
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprRepeat {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprRepeat {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.expr == other.expr && self.len == other.len
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprReturn {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprReturn {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.expr == other.expr
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprStruct {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprStruct {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.qself == other.qself && self.path == other.path
+ && self.fields == other.fields && self.dot2_token == other.dot2_token
+ && self.rest == other.rest
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprTry {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprTry {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.expr == other.expr
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprTryBlock {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprTryBlock {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.block == other.block
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprTuple {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprTuple {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.elems == other.elems
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprUnary {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprUnary {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.op == other.op && self.expr == other.expr
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprUnsafe {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprUnsafe {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.block == other.block
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprWhile {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprWhile {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.label == other.label && self.cond == other.cond
+ && self.body == other.body
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ExprYield {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ExprYield {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.expr == other.expr
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Field {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Field {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis
+ && self.mutability == other.mutability && self.ident == other.ident
+ && self.colon_token == other.colon_token && self.ty == other.ty
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::FieldMutability {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::FieldMutability {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::FieldMutability::None, crate::FieldMutability::None) => true,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::FieldPat {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::FieldPat {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.member == other.member
+ && self.colon_token == other.colon_token && self.pat == other.pat
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::FieldValue {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::FieldValue {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.member == other.member
+ && self.colon_token == other.colon_token && self.expr == other.expr
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Fields {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Fields {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::Fields::Named(self0), crate::Fields::Named(other0)) => {
+ self0 == other0
+ }
+ (crate::Fields::Unnamed(self0), crate::Fields::Unnamed(other0)) => {
+ self0 == other0
+ }
+ (crate::Fields::Unit, crate::Fields::Unit) => true,
+ _ => false,
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::FieldsNamed {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::FieldsNamed {
+ fn eq(&self, other: &Self) -> bool {
+ self.named == other.named
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::FieldsUnnamed {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::FieldsUnnamed {
+ fn eq(&self, other: &Self) -> bool {
+ self.unnamed == other.unnamed
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::File {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::File {
+ fn eq(&self, other: &Self) -> bool {
+ self.shebang == other.shebang && self.attrs == other.attrs
+ && self.items == other.items
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::FnArg {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::FnArg {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::FnArg::Receiver(self0), crate::FnArg::Receiver(other0)) => {
+ self0 == other0
+ }
+ (crate::FnArg::Typed(self0), crate::FnArg::Typed(other0)) => self0 == other0,
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ForeignItem {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ForeignItem {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::ForeignItem::Fn(self0), crate::ForeignItem::Fn(other0)) => {
+ self0 == other0
+ }
+ (crate::ForeignItem::Static(self0), crate::ForeignItem::Static(other0)) => {
+ self0 == other0
+ }
+ (crate::ForeignItem::Type(self0), crate::ForeignItem::Type(other0)) => {
+ self0 == other0
+ }
+ (crate::ForeignItem::Macro(self0), crate::ForeignItem::Macro(other0)) => {
+ self0 == other0
+ }
+ (
+ crate::ForeignItem::Verbatim(self0),
+ crate::ForeignItem::Verbatim(other0),
+ ) => TokenStreamHelper(self0) == TokenStreamHelper(other0),
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ForeignItemFn {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ForeignItemFn {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis && self.sig == other.sig
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ForeignItemMacro {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ForeignItemMacro {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.mac == other.mac
+ && self.semi_token == other.semi_token
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ForeignItemStatic {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ForeignItemStatic {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis
+ && self.mutability == other.mutability && self.ident == other.ident
+ && self.ty == other.ty
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ForeignItemType {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ForeignItemType {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis && self.ident == other.ident
+ && self.generics == other.generics
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::GenericArgument {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::GenericArgument {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (
+ crate::GenericArgument::Lifetime(self0),
+ crate::GenericArgument::Lifetime(other0),
+ ) => self0 == other0,
+ (
+ crate::GenericArgument::Type(self0),
+ crate::GenericArgument::Type(other0),
+ ) => self0 == other0,
+ (
+ crate::GenericArgument::Const(self0),
+ crate::GenericArgument::Const(other0),
+ ) => self0 == other0,
+ (
+ crate::GenericArgument::AssocType(self0),
+ crate::GenericArgument::AssocType(other0),
+ ) => self0 == other0,
+ (
+ crate::GenericArgument::AssocConst(self0),
+ crate::GenericArgument::AssocConst(other0),
+ ) => self0 == other0,
+ (
+ crate::GenericArgument::Constraint(self0),
+ crate::GenericArgument::Constraint(other0),
+ ) => self0 == other0,
+ _ => false,
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::GenericParam {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::GenericParam {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (
+ crate::GenericParam::Lifetime(self0),
+ crate::GenericParam::Lifetime(other0),
+ ) => self0 == other0,
+ (crate::GenericParam::Type(self0), crate::GenericParam::Type(other0)) => {
+ self0 == other0
+ }
+ (crate::GenericParam::Const(self0), crate::GenericParam::Const(other0)) => {
+ self0 == other0
+ }
+ _ => false,
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Generics {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Generics {
+ fn eq(&self, other: &Self) -> bool {
+ self.lt_token == other.lt_token && self.params == other.params
+ && self.gt_token == other.gt_token && self.where_clause == other.where_clause
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ImplItem {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ImplItem {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::ImplItem::Const(self0), crate::ImplItem::Const(other0)) => {
+ self0 == other0
+ }
+ (crate::ImplItem::Fn(self0), crate::ImplItem::Fn(other0)) => self0 == other0,
+ (crate::ImplItem::Type(self0), crate::ImplItem::Type(other0)) => {
+ self0 == other0
+ }
+ (crate::ImplItem::Macro(self0), crate::ImplItem::Macro(other0)) => {
+ self0 == other0
+ }
+ (crate::ImplItem::Verbatim(self0), crate::ImplItem::Verbatim(other0)) => {
+ TokenStreamHelper(self0) == TokenStreamHelper(other0)
+ }
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ImplItemConst {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ImplItemConst {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis
+ && self.defaultness == other.defaultness && self.ident == other.ident
+ && self.generics == other.generics && self.ty == other.ty
+ && self.expr == other.expr
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ImplItemFn {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ImplItemFn {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis
+ && self.defaultness == other.defaultness && self.sig == other.sig
+ && self.block == other.block
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ImplItemMacro {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ImplItemMacro {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.mac == other.mac
+ && self.semi_token == other.semi_token
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ImplItemType {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ImplItemType {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis
+ && self.defaultness == other.defaultness && self.ident == other.ident
+ && self.generics == other.generics && self.ty == other.ty
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ImplRestriction {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ImplRestriction {
+ fn eq(&self, _other: &Self) -> bool {
+ match *self {}
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Item {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Item {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::Item::Const(self0), crate::Item::Const(other0)) => self0 == other0,
+ (crate::Item::Enum(self0), crate::Item::Enum(other0)) => self0 == other0,
+ (crate::Item::ExternCrate(self0), crate::Item::ExternCrate(other0)) => {
+ self0 == other0
+ }
+ (crate::Item::Fn(self0), crate::Item::Fn(other0)) => self0 == other0,
+ (crate::Item::ForeignMod(self0), crate::Item::ForeignMod(other0)) => {
+ self0 == other0
+ }
+ (crate::Item::Impl(self0), crate::Item::Impl(other0)) => self0 == other0,
+ (crate::Item::Macro(self0), crate::Item::Macro(other0)) => self0 == other0,
+ (crate::Item::Mod(self0), crate::Item::Mod(other0)) => self0 == other0,
+ (crate::Item::Static(self0), crate::Item::Static(other0)) => self0 == other0,
+ (crate::Item::Struct(self0), crate::Item::Struct(other0)) => self0 == other0,
+ (crate::Item::Trait(self0), crate::Item::Trait(other0)) => self0 == other0,
+ (crate::Item::TraitAlias(self0), crate::Item::TraitAlias(other0)) => {
+ self0 == other0
+ }
+ (crate::Item::Type(self0), crate::Item::Type(other0)) => self0 == other0,
+ (crate::Item::Union(self0), crate::Item::Union(other0)) => self0 == other0,
+ (crate::Item::Use(self0), crate::Item::Use(other0)) => self0 == other0,
+ (crate::Item::Verbatim(self0), crate::Item::Verbatim(other0)) => {
+ TokenStreamHelper(self0) == TokenStreamHelper(other0)
+ }
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemConst {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemConst {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis && self.ident == other.ident
+ && self.generics == other.generics && self.ty == other.ty
+ && self.expr == other.expr
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemEnum {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemEnum {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis && self.ident == other.ident
+ && self.generics == other.generics && self.variants == other.variants
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemExternCrate {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemExternCrate {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis && self.ident == other.ident
+ && self.rename == other.rename
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemFn {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemFn {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis && self.sig == other.sig
+ && self.block == other.block
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemForeignMod {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemForeignMod {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.unsafety == other.unsafety
+ && self.abi == other.abi && self.items == other.items
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemImpl {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemImpl {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.defaultness == other.defaultness
+ && self.unsafety == other.unsafety && self.generics == other.generics
+ && self.trait_ == other.trait_ && self.self_ty == other.self_ty
+ && self.items == other.items
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemMacro {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemMacro {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.ident == other.ident && self.mac == other.mac
+ && self.semi_token == other.semi_token
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemMod {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemMod {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis
+ && self.unsafety == other.unsafety && self.ident == other.ident
+ && self.content == other.content && self.semi == other.semi
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemStatic {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemStatic {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis
+ && self.mutability == other.mutability && self.ident == other.ident
+ && self.ty == other.ty && self.expr == other.expr
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemStruct {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemStruct {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis && self.ident == other.ident
+ && self.generics == other.generics && self.fields == other.fields
+ && self.semi_token == other.semi_token
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemTrait {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemTrait {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis
+ && self.unsafety == other.unsafety && self.auto_token == other.auto_token
+ && self.restriction == other.restriction && self.ident == other.ident
+ && self.generics == other.generics && self.colon_token == other.colon_token
+ && self.supertraits == other.supertraits && self.items == other.items
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemTraitAlias {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemTraitAlias {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis && self.ident == other.ident
+ && self.generics == other.generics && self.bounds == other.bounds
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemType {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemType {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis && self.ident == other.ident
+ && self.generics == other.generics && self.ty == other.ty
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemUnion {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemUnion {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis && self.ident == other.ident
+ && self.generics == other.generics && self.fields == other.fields
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ItemUse {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ItemUse {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.vis == other.vis
+ && self.leading_colon == other.leading_colon && self.tree == other.tree
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Label {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Label {
+ fn eq(&self, other: &Self) -> bool {
+ self.name == other.name
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::LifetimeParam {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::LifetimeParam {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.lifetime == other.lifetime
+ && self.colon_token == other.colon_token && self.bounds == other.bounds
+ }
+}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Lit {}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Lit {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::Lit::Str(self0), crate::Lit::Str(other0)) => self0 == other0,
+ (crate::Lit::ByteStr(self0), crate::Lit::ByteStr(other0)) => self0 == other0,
+ (crate::Lit::CStr(self0), crate::Lit::CStr(other0)) => self0 == other0,
+ (crate::Lit::Byte(self0), crate::Lit::Byte(other0)) => self0 == other0,
+ (crate::Lit::Char(self0), crate::Lit::Char(other0)) => self0 == other0,
+ (crate::Lit::Int(self0), crate::Lit::Int(other0)) => self0 == other0,
+ (crate::Lit::Float(self0), crate::Lit::Float(other0)) => self0 == other0,
+ (crate::Lit::Bool(self0), crate::Lit::Bool(other0)) => self0 == other0,
+ (crate::Lit::Verbatim(self0), crate::Lit::Verbatim(other0)) => {
+ self0.to_string() == other0.to_string()
+ }
+ _ => false,
+ }
+ }
+}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::LitBool {}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::LitBool {
+ fn eq(&self, other: &Self) -> bool {
+ self.value == other.value
+ }
+}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::LitByte {}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::LitByteStr {}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::LitCStr {}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::LitChar {}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::LitFloat {}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::LitInt {}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::LitStr {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Local {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Local {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.pat == other.pat && self.init == other.init
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::LocalInit {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::LocalInit {
+ fn eq(&self, other: &Self) -> bool {
+ self.expr == other.expr && self.diverge == other.diverge
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Macro {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Macro {
+ fn eq(&self, other: &Self) -> bool {
+ self.path == other.path && self.delimiter == other.delimiter
+ && TokenStreamHelper(&self.tokens) == TokenStreamHelper(&other.tokens)
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::MacroDelimiter {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::MacroDelimiter {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::MacroDelimiter::Paren(_), crate::MacroDelimiter::Paren(_)) => true,
+ (crate::MacroDelimiter::Brace(_), crate::MacroDelimiter::Brace(_)) => true,
+ (crate::MacroDelimiter::Bracket(_), crate::MacroDelimiter::Bracket(_)) => {
+ true
+ }
+ _ => false,
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Meta {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Meta {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::Meta::Path(self0), crate::Meta::Path(other0)) => self0 == other0,
+ (crate::Meta::List(self0), crate::Meta::List(other0)) => self0 == other0,
+ (crate::Meta::NameValue(self0), crate::Meta::NameValue(other0)) => {
+ self0 == other0
+ }
+ _ => false,
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::MetaList {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::MetaList {
+ fn eq(&self, other: &Self) -> bool {
+ self.path == other.path && self.delimiter == other.delimiter
+ && TokenStreamHelper(&self.tokens) == TokenStreamHelper(&other.tokens)
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::MetaNameValue {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::MetaNameValue {
+ fn eq(&self, other: &Self) -> bool {
+ self.path == other.path && self.value == other.value
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ParenthesizedGenericArguments {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ParenthesizedGenericArguments {
+ fn eq(&self, other: &Self) -> bool {
+ self.inputs == other.inputs && self.output == other.output
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Pat {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Pat {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::Pat::Const(self0), crate::Pat::Const(other0)) => self0 == other0,
+ (crate::Pat::Ident(self0), crate::Pat::Ident(other0)) => self0 == other0,
+ (crate::Pat::Lit(self0), crate::Pat::Lit(other0)) => self0 == other0,
+ (crate::Pat::Macro(self0), crate::Pat::Macro(other0)) => self0 == other0,
+ (crate::Pat::Or(self0), crate::Pat::Or(other0)) => self0 == other0,
+ (crate::Pat::Paren(self0), crate::Pat::Paren(other0)) => self0 == other0,
+ (crate::Pat::Path(self0), crate::Pat::Path(other0)) => self0 == other0,
+ (crate::Pat::Range(self0), crate::Pat::Range(other0)) => self0 == other0,
+ (crate::Pat::Reference(self0), crate::Pat::Reference(other0)) => {
+ self0 == other0
+ }
+ (crate::Pat::Rest(self0), crate::Pat::Rest(other0)) => self0 == other0,
+ (crate::Pat::Slice(self0), crate::Pat::Slice(other0)) => self0 == other0,
+ (crate::Pat::Struct(self0), crate::Pat::Struct(other0)) => self0 == other0,
+ (crate::Pat::Tuple(self0), crate::Pat::Tuple(other0)) => self0 == other0,
+ (crate::Pat::TupleStruct(self0), crate::Pat::TupleStruct(other0)) => {
+ self0 == other0
+ }
+ (crate::Pat::Type(self0), crate::Pat::Type(other0)) => self0 == other0,
+ (crate::Pat::Verbatim(self0), crate::Pat::Verbatim(other0)) => {
+ TokenStreamHelper(self0) == TokenStreamHelper(other0)
+ }
+ (crate::Pat::Wild(self0), crate::Pat::Wild(other0)) => self0 == other0,
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PatIdent {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PatIdent {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.by_ref == other.by_ref
+ && self.mutability == other.mutability && self.ident == other.ident
+ && self.subpat == other.subpat
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PatOr {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PatOr {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.leading_vert == other.leading_vert
+ && self.cases == other.cases
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PatParen {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PatParen {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.pat == other.pat
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PatReference {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PatReference {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.mutability == other.mutability
+ && self.pat == other.pat
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PatRest {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PatRest {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PatSlice {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PatSlice {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.elems == other.elems
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PatStruct {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PatStruct {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.qself == other.qself && self.path == other.path
+ && self.fields == other.fields && self.rest == other.rest
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PatTuple {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PatTuple {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.elems == other.elems
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PatTupleStruct {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PatTupleStruct {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.qself == other.qself && self.path == other.path
+ && self.elems == other.elems
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PatType {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PatType {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.pat == other.pat && self.ty == other.ty
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PatWild {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PatWild {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Path {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Path {
+ fn eq(&self, other: &Self) -> bool {
+ self.leading_colon == other.leading_colon && self.segments == other.segments
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PathArguments {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PathArguments {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::PathArguments::None, crate::PathArguments::None) => true,
+ (
+ crate::PathArguments::AngleBracketed(self0),
+ crate::PathArguments::AngleBracketed(other0),
+ ) => self0 == other0,
+ (
+ crate::PathArguments::Parenthesized(self0),
+ crate::PathArguments::Parenthesized(other0),
+ ) => self0 == other0,
+ _ => false,
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PathSegment {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PathSegment {
+ fn eq(&self, other: &Self) -> bool {
+ self.ident == other.ident && self.arguments == other.arguments
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PredicateLifetime {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PredicateLifetime {
+ fn eq(&self, other: &Self) -> bool {
+ self.lifetime == other.lifetime && self.bounds == other.bounds
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::PredicateType {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::PredicateType {
+ fn eq(&self, other: &Self) -> bool {
+ self.lifetimes == other.lifetimes && self.bounded_ty == other.bounded_ty
+ && self.bounds == other.bounds
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::QSelf {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::QSelf {
+ fn eq(&self, other: &Self) -> bool {
+ self.ty == other.ty && self.position == other.position
+ && self.as_token == other.as_token
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::RangeLimits {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::RangeLimits {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::RangeLimits::HalfOpen(_), crate::RangeLimits::HalfOpen(_)) => true,
+ (crate::RangeLimits::Closed(_), crate::RangeLimits::Closed(_)) => true,
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Receiver {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Receiver {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.reference == other.reference
+ && self.mutability == other.mutability
+ && self.colon_token == other.colon_token && self.ty == other.ty
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::ReturnType {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::ReturnType {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::ReturnType::Default, crate::ReturnType::Default) => true,
+ (crate::ReturnType::Type(_, self1), crate::ReturnType::Type(_, other1)) => {
+ self1 == other1
+ }
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Signature {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Signature {
+ fn eq(&self, other: &Self) -> bool {
+ self.constness == other.constness && self.asyncness == other.asyncness
+ && self.unsafety == other.unsafety && self.abi == other.abi
+ && self.ident == other.ident && self.generics == other.generics
+ && self.inputs == other.inputs && self.variadic == other.variadic
+ && self.output == other.output
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::StaticMutability {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::StaticMutability {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::StaticMutability::Mut(_), crate::StaticMutability::Mut(_)) => true,
+ (crate::StaticMutability::None, crate::StaticMutability::None) => true,
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Stmt {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Stmt {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::Stmt::Local(self0), crate::Stmt::Local(other0)) => self0 == other0,
+ (crate::Stmt::Item(self0), crate::Stmt::Item(other0)) => self0 == other0,
+ (crate::Stmt::Expr(self0, self1), crate::Stmt::Expr(other0, other1)) => {
+ self0 == other0 && self1 == other1
+ }
+ (crate::Stmt::Macro(self0), crate::Stmt::Macro(other0)) => self0 == other0,
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::StmtMacro {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::StmtMacro {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.mac == other.mac
+ && self.semi_token == other.semi_token
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TraitBound {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TraitBound {
+ fn eq(&self, other: &Self) -> bool {
+ self.paren_token == other.paren_token && self.modifier == other.modifier
+ && self.lifetimes == other.lifetimes && self.path == other.path
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TraitBoundModifier {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TraitBoundModifier {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::TraitBoundModifier::None, crate::TraitBoundModifier::None) => true,
+ (
+ crate::TraitBoundModifier::Maybe(_),
+ crate::TraitBoundModifier::Maybe(_),
+ ) => true,
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TraitItem {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TraitItem {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::TraitItem::Const(self0), crate::TraitItem::Const(other0)) => {
+ self0 == other0
+ }
+ (crate::TraitItem::Fn(self0), crate::TraitItem::Fn(other0)) => {
+ self0 == other0
+ }
+ (crate::TraitItem::Type(self0), crate::TraitItem::Type(other0)) => {
+ self0 == other0
+ }
+ (crate::TraitItem::Macro(self0), crate::TraitItem::Macro(other0)) => {
+ self0 == other0
+ }
+ (crate::TraitItem::Verbatim(self0), crate::TraitItem::Verbatim(other0)) => {
+ TokenStreamHelper(self0) == TokenStreamHelper(other0)
+ }
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TraitItemConst {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TraitItemConst {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.ident == other.ident
+ && self.generics == other.generics && self.ty == other.ty
+ && self.default == other.default
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TraitItemFn {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TraitItemFn {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.sig == other.sig
+ && self.default == other.default && self.semi_token == other.semi_token
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TraitItemMacro {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TraitItemMacro {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.mac == other.mac
+ && self.semi_token == other.semi_token
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TraitItemType {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TraitItemType {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.ident == other.ident
+ && self.generics == other.generics && self.colon_token == other.colon_token
+ && self.bounds == other.bounds && self.default == other.default
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Type {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Type {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::Type::Array(self0), crate::Type::Array(other0)) => self0 == other0,
+ (crate::Type::BareFn(self0), crate::Type::BareFn(other0)) => self0 == other0,
+ (crate::Type::Group(self0), crate::Type::Group(other0)) => self0 == other0,
+ (crate::Type::ImplTrait(self0), crate::Type::ImplTrait(other0)) => {
+ self0 == other0
+ }
+ (crate::Type::Infer(self0), crate::Type::Infer(other0)) => self0 == other0,
+ (crate::Type::Macro(self0), crate::Type::Macro(other0)) => self0 == other0,
+ (crate::Type::Never(self0), crate::Type::Never(other0)) => self0 == other0,
+ (crate::Type::Paren(self0), crate::Type::Paren(other0)) => self0 == other0,
+ (crate::Type::Path(self0), crate::Type::Path(other0)) => self0 == other0,
+ (crate::Type::Ptr(self0), crate::Type::Ptr(other0)) => self0 == other0,
+ (crate::Type::Reference(self0), crate::Type::Reference(other0)) => {
+ self0 == other0
+ }
+ (crate::Type::Slice(self0), crate::Type::Slice(other0)) => self0 == other0,
+ (crate::Type::TraitObject(self0), crate::Type::TraitObject(other0)) => {
+ self0 == other0
+ }
+ (crate::Type::Tuple(self0), crate::Type::Tuple(other0)) => self0 == other0,
+ (crate::Type::Verbatim(self0), crate::Type::Verbatim(other0)) => {
+ TokenStreamHelper(self0) == TokenStreamHelper(other0)
+ }
+ _ => false,
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeArray {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeArray {
+ fn eq(&self, other: &Self) -> bool {
+ self.elem == other.elem && self.len == other.len
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeBareFn {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeBareFn {
+ fn eq(&self, other: &Self) -> bool {
+ self.lifetimes == other.lifetimes && self.unsafety == other.unsafety
+ && self.abi == other.abi && self.inputs == other.inputs
+ && self.variadic == other.variadic && self.output == other.output
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeGroup {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeGroup {
+ fn eq(&self, other: &Self) -> bool {
+ self.elem == other.elem
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeImplTrait {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeImplTrait {
+ fn eq(&self, other: &Self) -> bool {
+ self.bounds == other.bounds
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeInfer {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeInfer {
+ fn eq(&self, _other: &Self) -> bool {
+ true
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeMacro {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeMacro {
+ fn eq(&self, other: &Self) -> bool {
+ self.mac == other.mac
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeNever {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeNever {
+ fn eq(&self, _other: &Self) -> bool {
+ true
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeParam {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeParam {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.ident == other.ident
+ && self.colon_token == other.colon_token && self.bounds == other.bounds
+ && self.eq_token == other.eq_token && self.default == other.default
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeParamBound {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeParamBound {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (
+ crate::TypeParamBound::Trait(self0),
+ crate::TypeParamBound::Trait(other0),
+ ) => self0 == other0,
+ (
+ crate::TypeParamBound::Lifetime(self0),
+ crate::TypeParamBound::Lifetime(other0),
+ ) => self0 == other0,
+ (
+ crate::TypeParamBound::Verbatim(self0),
+ crate::TypeParamBound::Verbatim(other0),
+ ) => TokenStreamHelper(self0) == TokenStreamHelper(other0),
+ _ => false,
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeParen {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeParen {
+ fn eq(&self, other: &Self) -> bool {
+ self.elem == other.elem
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypePath {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypePath {
+ fn eq(&self, other: &Self) -> bool {
+ self.qself == other.qself && self.path == other.path
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypePtr {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypePtr {
+ fn eq(&self, other: &Self) -> bool {
+ self.const_token == other.const_token && self.mutability == other.mutability
+ && self.elem == other.elem
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeReference {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeReference {
+ fn eq(&self, other: &Self) -> bool {
+ self.lifetime == other.lifetime && self.mutability == other.mutability
+ && self.elem == other.elem
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeSlice {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeSlice {
+ fn eq(&self, other: &Self) -> bool {
+ self.elem == other.elem
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeTraitObject {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeTraitObject {
+ fn eq(&self, other: &Self) -> bool {
+ self.dyn_token == other.dyn_token && self.bounds == other.bounds
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::TypeTuple {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::TypeTuple {
+ fn eq(&self, other: &Self) -> bool {
+ self.elems == other.elems
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::UnOp {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::UnOp {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::UnOp::Deref(_), crate::UnOp::Deref(_)) => true,
+ (crate::UnOp::Not(_), crate::UnOp::Not(_)) => true,
+ (crate::UnOp::Neg(_), crate::UnOp::Neg(_)) => true,
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::UseGlob {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::UseGlob {
+ fn eq(&self, _other: &Self) -> bool {
+ true
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::UseGroup {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::UseGroup {
+ fn eq(&self, other: &Self) -> bool {
+ self.items == other.items
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::UseName {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::UseName {
+ fn eq(&self, other: &Self) -> bool {
+ self.ident == other.ident
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::UsePath {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::UsePath {
+ fn eq(&self, other: &Self) -> bool {
+ self.ident == other.ident && self.tree == other.tree
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::UseRename {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::UseRename {
+ fn eq(&self, other: &Self) -> bool {
+ self.ident == other.ident && self.rename == other.rename
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::UseTree {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::UseTree {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::UseTree::Path(self0), crate::UseTree::Path(other0)) => {
+ self0 == other0
+ }
+ (crate::UseTree::Name(self0), crate::UseTree::Name(other0)) => {
+ self0 == other0
+ }
+ (crate::UseTree::Rename(self0), crate::UseTree::Rename(other0)) => {
+ self0 == other0
+ }
+ (crate::UseTree::Glob(self0), crate::UseTree::Glob(other0)) => {
+ self0 == other0
+ }
+ (crate::UseTree::Group(self0), crate::UseTree::Group(other0)) => {
+ self0 == other0
+ }
+ _ => false,
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Variadic {}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Variadic {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.pat == other.pat && self.comma == other.comma
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Variant {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Variant {
+ fn eq(&self, other: &Self) -> bool {
+ self.attrs == other.attrs && self.ident == other.ident
+ && self.fields == other.fields && self.discriminant == other.discriminant
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::VisRestricted {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::VisRestricted {
+ fn eq(&self, other: &Self) -> bool {
+ self.in_token == other.in_token && self.path == other.path
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::Visibility {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::Visibility {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (crate::Visibility::Public(_), crate::Visibility::Public(_)) => true,
+ (
+ crate::Visibility::Restricted(self0),
+ crate::Visibility::Restricted(other0),
+ ) => self0 == other0,
+ (crate::Visibility::Inherited, crate::Visibility::Inherited) => true,
+ _ => false,
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::WhereClause {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::WhereClause {
+ fn eq(&self, other: &Self) -> bool {
+ self.predicates == other.predicates
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for crate::WherePredicate {}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for crate::WherePredicate {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (
+ crate::WherePredicate::Lifetime(self0),
+ crate::WherePredicate::Lifetime(other0),
+ ) => self0 == other0,
+ (crate::WherePredicate::Type(self0), crate::WherePredicate::Type(other0)) => {
+ self0 == other0
+ }
+ _ => false,
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/gen/fold.rs b/rust/hw/char/pl011/vendor/syn/src/gen/fold.rs
new file mode 100644
index 0000000000..e5662f5834
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/gen/fold.rs
@@ -0,0 +1,3779 @@
+// This file is @generated by syn-internal-codegen.
+// It is not intended for manual editing.
+
+#![allow(unreachable_code, unused_variables)]
+#![allow(
+ clippy::match_wildcard_for_single_variants,
+ clippy::needless_match,
+ clippy::needless_pass_by_ref_mut,
+)]
+#[cfg(feature = "full")]
+macro_rules! full {
+ ($e:expr) => {
+ $e
+ };
+}
+#[cfg(all(feature = "derive", not(feature = "full")))]
+macro_rules! full {
+ ($e:expr) => {
+ unreachable!()
+ };
+}
+/// Syntax tree traversal to transform the nodes of an owned syntax tree.
+///
+/// See the [module documentation] for details.
+///
+/// [module documentation]: self
+pub trait Fold {
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_abi(&mut self, i: crate::Abi) -> crate::Abi {
+ fold_abi(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_angle_bracketed_generic_arguments(
+ &mut self,
+ i: crate::AngleBracketedGenericArguments,
+ ) -> crate::AngleBracketedGenericArguments {
+ fold_angle_bracketed_generic_arguments(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_arm(&mut self, i: crate::Arm) -> crate::Arm {
+ fold_arm(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_assoc_const(&mut self, i: crate::AssocConst) -> crate::AssocConst {
+ fold_assoc_const(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_assoc_type(&mut self, i: crate::AssocType) -> crate::AssocType {
+ fold_assoc_type(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_attr_style(&mut self, i: crate::AttrStyle) -> crate::AttrStyle {
+ fold_attr_style(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_attribute(&mut self, i: crate::Attribute) -> crate::Attribute {
+ fold_attribute(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_bare_fn_arg(&mut self, i: crate::BareFnArg) -> crate::BareFnArg {
+ fold_bare_fn_arg(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_bare_variadic(&mut self, i: crate::BareVariadic) -> crate::BareVariadic {
+ fold_bare_variadic(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_bin_op(&mut self, i: crate::BinOp) -> crate::BinOp {
+ fold_bin_op(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_block(&mut self, i: crate::Block) -> crate::Block {
+ fold_block(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_bound_lifetimes(
+ &mut self,
+ i: crate::BoundLifetimes,
+ ) -> crate::BoundLifetimes {
+ fold_bound_lifetimes(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_const_param(&mut self, i: crate::ConstParam) -> crate::ConstParam {
+ fold_const_param(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_constraint(&mut self, i: crate::Constraint) -> crate::Constraint {
+ fold_constraint(self, i)
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn fold_data(&mut self, i: crate::Data) -> crate::Data {
+ fold_data(self, i)
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn fold_data_enum(&mut self, i: crate::DataEnum) -> crate::DataEnum {
+ fold_data_enum(self, i)
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn fold_data_struct(&mut self, i: crate::DataStruct) -> crate::DataStruct {
+ fold_data_struct(self, i)
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn fold_data_union(&mut self, i: crate::DataUnion) -> crate::DataUnion {
+ fold_data_union(self, i)
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn fold_derive_input(&mut self, i: crate::DeriveInput) -> crate::DeriveInput {
+ fold_derive_input(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr(&mut self, i: crate::Expr) -> crate::Expr {
+ fold_expr(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_array(&mut self, i: crate::ExprArray) -> crate::ExprArray {
+ fold_expr_array(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_assign(&mut self, i: crate::ExprAssign) -> crate::ExprAssign {
+ fold_expr_assign(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_async(&mut self, i: crate::ExprAsync) -> crate::ExprAsync {
+ fold_expr_async(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_await(&mut self, i: crate::ExprAwait) -> crate::ExprAwait {
+ fold_expr_await(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_binary(&mut self, i: crate::ExprBinary) -> crate::ExprBinary {
+ fold_expr_binary(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_block(&mut self, i: crate::ExprBlock) -> crate::ExprBlock {
+ fold_expr_block(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_break(&mut self, i: crate::ExprBreak) -> crate::ExprBreak {
+ fold_expr_break(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_call(&mut self, i: crate::ExprCall) -> crate::ExprCall {
+ fold_expr_call(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_cast(&mut self, i: crate::ExprCast) -> crate::ExprCast {
+ fold_expr_cast(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_closure(&mut self, i: crate::ExprClosure) -> crate::ExprClosure {
+ fold_expr_closure(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_const(&mut self, i: crate::ExprConst) -> crate::ExprConst {
+ fold_expr_const(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_continue(&mut self, i: crate::ExprContinue) -> crate::ExprContinue {
+ fold_expr_continue(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_field(&mut self, i: crate::ExprField) -> crate::ExprField {
+ fold_expr_field(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_for_loop(&mut self, i: crate::ExprForLoop) -> crate::ExprForLoop {
+ fold_expr_for_loop(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_group(&mut self, i: crate::ExprGroup) -> crate::ExprGroup {
+ fold_expr_group(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_if(&mut self, i: crate::ExprIf) -> crate::ExprIf {
+ fold_expr_if(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_index(&mut self, i: crate::ExprIndex) -> crate::ExprIndex {
+ fold_expr_index(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_infer(&mut self, i: crate::ExprInfer) -> crate::ExprInfer {
+ fold_expr_infer(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_let(&mut self, i: crate::ExprLet) -> crate::ExprLet {
+ fold_expr_let(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_lit(&mut self, i: crate::ExprLit) -> crate::ExprLit {
+ fold_expr_lit(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_loop(&mut self, i: crate::ExprLoop) -> crate::ExprLoop {
+ fold_expr_loop(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_macro(&mut self, i: crate::ExprMacro) -> crate::ExprMacro {
+ fold_expr_macro(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_match(&mut self, i: crate::ExprMatch) -> crate::ExprMatch {
+ fold_expr_match(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_method_call(
+ &mut self,
+ i: crate::ExprMethodCall,
+ ) -> crate::ExprMethodCall {
+ fold_expr_method_call(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_paren(&mut self, i: crate::ExprParen) -> crate::ExprParen {
+ fold_expr_paren(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_path(&mut self, i: crate::ExprPath) -> crate::ExprPath {
+ fold_expr_path(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_range(&mut self, i: crate::ExprRange) -> crate::ExprRange {
+ fold_expr_range(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_reference(&mut self, i: crate::ExprReference) -> crate::ExprReference {
+ fold_expr_reference(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_repeat(&mut self, i: crate::ExprRepeat) -> crate::ExprRepeat {
+ fold_expr_repeat(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_return(&mut self, i: crate::ExprReturn) -> crate::ExprReturn {
+ fold_expr_return(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_struct(&mut self, i: crate::ExprStruct) -> crate::ExprStruct {
+ fold_expr_struct(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_try(&mut self, i: crate::ExprTry) -> crate::ExprTry {
+ fold_expr_try(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_try_block(&mut self, i: crate::ExprTryBlock) -> crate::ExprTryBlock {
+ fold_expr_try_block(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_tuple(&mut self, i: crate::ExprTuple) -> crate::ExprTuple {
+ fold_expr_tuple(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_expr_unary(&mut self, i: crate::ExprUnary) -> crate::ExprUnary {
+ fold_expr_unary(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_unsafe(&mut self, i: crate::ExprUnsafe) -> crate::ExprUnsafe {
+ fold_expr_unsafe(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_while(&mut self, i: crate::ExprWhile) -> crate::ExprWhile {
+ fold_expr_while(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_expr_yield(&mut self, i: crate::ExprYield) -> crate::ExprYield {
+ fold_expr_yield(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_field(&mut self, i: crate::Field) -> crate::Field {
+ fold_field(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_field_mutability(
+ &mut self,
+ i: crate::FieldMutability,
+ ) -> crate::FieldMutability {
+ fold_field_mutability(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_field_pat(&mut self, i: crate::FieldPat) -> crate::FieldPat {
+ fold_field_pat(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_field_value(&mut self, i: crate::FieldValue) -> crate::FieldValue {
+ fold_field_value(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_fields(&mut self, i: crate::Fields) -> crate::Fields {
+ fold_fields(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_fields_named(&mut self, i: crate::FieldsNamed) -> crate::FieldsNamed {
+ fold_fields_named(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_fields_unnamed(&mut self, i: crate::FieldsUnnamed) -> crate::FieldsUnnamed {
+ fold_fields_unnamed(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_file(&mut self, i: crate::File) -> crate::File {
+ fold_file(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_fn_arg(&mut self, i: crate::FnArg) -> crate::FnArg {
+ fold_fn_arg(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_foreign_item(&mut self, i: crate::ForeignItem) -> crate::ForeignItem {
+ fold_foreign_item(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_foreign_item_fn(&mut self, i: crate::ForeignItemFn) -> crate::ForeignItemFn {
+ fold_foreign_item_fn(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_foreign_item_macro(
+ &mut self,
+ i: crate::ForeignItemMacro,
+ ) -> crate::ForeignItemMacro {
+ fold_foreign_item_macro(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_foreign_item_static(
+ &mut self,
+ i: crate::ForeignItemStatic,
+ ) -> crate::ForeignItemStatic {
+ fold_foreign_item_static(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_foreign_item_type(
+ &mut self,
+ i: crate::ForeignItemType,
+ ) -> crate::ForeignItemType {
+ fold_foreign_item_type(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_generic_argument(
+ &mut self,
+ i: crate::GenericArgument,
+ ) -> crate::GenericArgument {
+ fold_generic_argument(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_generic_param(&mut self, i: crate::GenericParam) -> crate::GenericParam {
+ fold_generic_param(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_generics(&mut self, i: crate::Generics) -> crate::Generics {
+ fold_generics(self, i)
+ }
+ fn fold_ident(&mut self, i: proc_macro2::Ident) -> proc_macro2::Ident {
+ fold_ident(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_impl_item(&mut self, i: crate::ImplItem) -> crate::ImplItem {
+ fold_impl_item(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_impl_item_const(&mut self, i: crate::ImplItemConst) -> crate::ImplItemConst {
+ fold_impl_item_const(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_impl_item_fn(&mut self, i: crate::ImplItemFn) -> crate::ImplItemFn {
+ fold_impl_item_fn(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_impl_item_macro(&mut self, i: crate::ImplItemMacro) -> crate::ImplItemMacro {
+ fold_impl_item_macro(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_impl_item_type(&mut self, i: crate::ImplItemType) -> crate::ImplItemType {
+ fold_impl_item_type(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_impl_restriction(
+ &mut self,
+ i: crate::ImplRestriction,
+ ) -> crate::ImplRestriction {
+ fold_impl_restriction(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_index(&mut self, i: crate::Index) -> crate::Index {
+ fold_index(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item(&mut self, i: crate::Item) -> crate::Item {
+ fold_item(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_const(&mut self, i: crate::ItemConst) -> crate::ItemConst {
+ fold_item_const(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_enum(&mut self, i: crate::ItemEnum) -> crate::ItemEnum {
+ fold_item_enum(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_extern_crate(
+ &mut self,
+ i: crate::ItemExternCrate,
+ ) -> crate::ItemExternCrate {
+ fold_item_extern_crate(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_fn(&mut self, i: crate::ItemFn) -> crate::ItemFn {
+ fold_item_fn(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_foreign_mod(
+ &mut self,
+ i: crate::ItemForeignMod,
+ ) -> crate::ItemForeignMod {
+ fold_item_foreign_mod(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_impl(&mut self, i: crate::ItemImpl) -> crate::ItemImpl {
+ fold_item_impl(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_macro(&mut self, i: crate::ItemMacro) -> crate::ItemMacro {
+ fold_item_macro(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_mod(&mut self, i: crate::ItemMod) -> crate::ItemMod {
+ fold_item_mod(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_static(&mut self, i: crate::ItemStatic) -> crate::ItemStatic {
+ fold_item_static(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_struct(&mut self, i: crate::ItemStruct) -> crate::ItemStruct {
+ fold_item_struct(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_trait(&mut self, i: crate::ItemTrait) -> crate::ItemTrait {
+ fold_item_trait(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_trait_alias(
+ &mut self,
+ i: crate::ItemTraitAlias,
+ ) -> crate::ItemTraitAlias {
+ fold_item_trait_alias(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_type(&mut self, i: crate::ItemType) -> crate::ItemType {
+ fold_item_type(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_union(&mut self, i: crate::ItemUnion) -> crate::ItemUnion {
+ fold_item_union(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_item_use(&mut self, i: crate::ItemUse) -> crate::ItemUse {
+ fold_item_use(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_label(&mut self, i: crate::Label) -> crate::Label {
+ fold_label(self, i)
+ }
+ fn fold_lifetime(&mut self, i: crate::Lifetime) -> crate::Lifetime {
+ fold_lifetime(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_lifetime_param(&mut self, i: crate::LifetimeParam) -> crate::LifetimeParam {
+ fold_lifetime_param(self, i)
+ }
+ fn fold_lit(&mut self, i: crate::Lit) -> crate::Lit {
+ fold_lit(self, i)
+ }
+ fn fold_lit_bool(&mut self, i: crate::LitBool) -> crate::LitBool {
+ fold_lit_bool(self, i)
+ }
+ fn fold_lit_byte(&mut self, i: crate::LitByte) -> crate::LitByte {
+ fold_lit_byte(self, i)
+ }
+ fn fold_lit_byte_str(&mut self, i: crate::LitByteStr) -> crate::LitByteStr {
+ fold_lit_byte_str(self, i)
+ }
+ fn fold_lit_cstr(&mut self, i: crate::LitCStr) -> crate::LitCStr {
+ fold_lit_cstr(self, i)
+ }
+ fn fold_lit_char(&mut self, i: crate::LitChar) -> crate::LitChar {
+ fold_lit_char(self, i)
+ }
+ fn fold_lit_float(&mut self, i: crate::LitFloat) -> crate::LitFloat {
+ fold_lit_float(self, i)
+ }
+ fn fold_lit_int(&mut self, i: crate::LitInt) -> crate::LitInt {
+ fold_lit_int(self, i)
+ }
+ fn fold_lit_str(&mut self, i: crate::LitStr) -> crate::LitStr {
+ fold_lit_str(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_local(&mut self, i: crate::Local) -> crate::Local {
+ fold_local(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_local_init(&mut self, i: crate::LocalInit) -> crate::LocalInit {
+ fold_local_init(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_macro(&mut self, i: crate::Macro) -> crate::Macro {
+ fold_macro(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_macro_delimiter(
+ &mut self,
+ i: crate::MacroDelimiter,
+ ) -> crate::MacroDelimiter {
+ fold_macro_delimiter(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_member(&mut self, i: crate::Member) -> crate::Member {
+ fold_member(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_meta(&mut self, i: crate::Meta) -> crate::Meta {
+ fold_meta(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_meta_list(&mut self, i: crate::MetaList) -> crate::MetaList {
+ fold_meta_list(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_meta_name_value(&mut self, i: crate::MetaNameValue) -> crate::MetaNameValue {
+ fold_meta_name_value(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_parenthesized_generic_arguments(
+ &mut self,
+ i: crate::ParenthesizedGenericArguments,
+ ) -> crate::ParenthesizedGenericArguments {
+ fold_parenthesized_generic_arguments(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_pat(&mut self, i: crate::Pat) -> crate::Pat {
+ fold_pat(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_pat_ident(&mut self, i: crate::PatIdent) -> crate::PatIdent {
+ fold_pat_ident(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_pat_or(&mut self, i: crate::PatOr) -> crate::PatOr {
+ fold_pat_or(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_pat_paren(&mut self, i: crate::PatParen) -> crate::PatParen {
+ fold_pat_paren(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_pat_reference(&mut self, i: crate::PatReference) -> crate::PatReference {
+ fold_pat_reference(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_pat_rest(&mut self, i: crate::PatRest) -> crate::PatRest {
+ fold_pat_rest(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_pat_slice(&mut self, i: crate::PatSlice) -> crate::PatSlice {
+ fold_pat_slice(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_pat_struct(&mut self, i: crate::PatStruct) -> crate::PatStruct {
+ fold_pat_struct(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_pat_tuple(&mut self, i: crate::PatTuple) -> crate::PatTuple {
+ fold_pat_tuple(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_pat_tuple_struct(
+ &mut self,
+ i: crate::PatTupleStruct,
+ ) -> crate::PatTupleStruct {
+ fold_pat_tuple_struct(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_pat_type(&mut self, i: crate::PatType) -> crate::PatType {
+ fold_pat_type(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_pat_wild(&mut self, i: crate::PatWild) -> crate::PatWild {
+ fold_pat_wild(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_path(&mut self, i: crate::Path) -> crate::Path {
+ fold_path(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_path_arguments(&mut self, i: crate::PathArguments) -> crate::PathArguments {
+ fold_path_arguments(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_path_segment(&mut self, i: crate::PathSegment) -> crate::PathSegment {
+ fold_path_segment(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_predicate_lifetime(
+ &mut self,
+ i: crate::PredicateLifetime,
+ ) -> crate::PredicateLifetime {
+ fold_predicate_lifetime(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_predicate_type(&mut self, i: crate::PredicateType) -> crate::PredicateType {
+ fold_predicate_type(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_qself(&mut self, i: crate::QSelf) -> crate::QSelf {
+ fold_qself(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_range_limits(&mut self, i: crate::RangeLimits) -> crate::RangeLimits {
+ fold_range_limits(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_receiver(&mut self, i: crate::Receiver) -> crate::Receiver {
+ fold_receiver(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_return_type(&mut self, i: crate::ReturnType) -> crate::ReturnType {
+ fold_return_type(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_signature(&mut self, i: crate::Signature) -> crate::Signature {
+ fold_signature(self, i)
+ }
+ fn fold_span(&mut self, i: proc_macro2::Span) -> proc_macro2::Span {
+ fold_span(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_static_mutability(
+ &mut self,
+ i: crate::StaticMutability,
+ ) -> crate::StaticMutability {
+ fold_static_mutability(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_stmt(&mut self, i: crate::Stmt) -> crate::Stmt {
+ fold_stmt(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_stmt_macro(&mut self, i: crate::StmtMacro) -> crate::StmtMacro {
+ fold_stmt_macro(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_trait_bound(&mut self, i: crate::TraitBound) -> crate::TraitBound {
+ fold_trait_bound(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_trait_bound_modifier(
+ &mut self,
+ i: crate::TraitBoundModifier,
+ ) -> crate::TraitBoundModifier {
+ fold_trait_bound_modifier(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_trait_item(&mut self, i: crate::TraitItem) -> crate::TraitItem {
+ fold_trait_item(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_trait_item_const(
+ &mut self,
+ i: crate::TraitItemConst,
+ ) -> crate::TraitItemConst {
+ fold_trait_item_const(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_trait_item_fn(&mut self, i: crate::TraitItemFn) -> crate::TraitItemFn {
+ fold_trait_item_fn(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_trait_item_macro(
+ &mut self,
+ i: crate::TraitItemMacro,
+ ) -> crate::TraitItemMacro {
+ fold_trait_item_macro(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_trait_item_type(&mut self, i: crate::TraitItemType) -> crate::TraitItemType {
+ fold_trait_item_type(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type(&mut self, i: crate::Type) -> crate::Type {
+ fold_type(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_array(&mut self, i: crate::TypeArray) -> crate::TypeArray {
+ fold_type_array(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_bare_fn(&mut self, i: crate::TypeBareFn) -> crate::TypeBareFn {
+ fold_type_bare_fn(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_group(&mut self, i: crate::TypeGroup) -> crate::TypeGroup {
+ fold_type_group(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_impl_trait(&mut self, i: crate::TypeImplTrait) -> crate::TypeImplTrait {
+ fold_type_impl_trait(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_infer(&mut self, i: crate::TypeInfer) -> crate::TypeInfer {
+ fold_type_infer(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_macro(&mut self, i: crate::TypeMacro) -> crate::TypeMacro {
+ fold_type_macro(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_never(&mut self, i: crate::TypeNever) -> crate::TypeNever {
+ fold_type_never(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_param(&mut self, i: crate::TypeParam) -> crate::TypeParam {
+ fold_type_param(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_param_bound(
+ &mut self,
+ i: crate::TypeParamBound,
+ ) -> crate::TypeParamBound {
+ fold_type_param_bound(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_paren(&mut self, i: crate::TypeParen) -> crate::TypeParen {
+ fold_type_paren(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_path(&mut self, i: crate::TypePath) -> crate::TypePath {
+ fold_type_path(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_ptr(&mut self, i: crate::TypePtr) -> crate::TypePtr {
+ fold_type_ptr(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_reference(&mut self, i: crate::TypeReference) -> crate::TypeReference {
+ fold_type_reference(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_slice(&mut self, i: crate::TypeSlice) -> crate::TypeSlice {
+ fold_type_slice(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_trait_object(
+ &mut self,
+ i: crate::TypeTraitObject,
+ ) -> crate::TypeTraitObject {
+ fold_type_trait_object(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_type_tuple(&mut self, i: crate::TypeTuple) -> crate::TypeTuple {
+ fold_type_tuple(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_un_op(&mut self, i: crate::UnOp) -> crate::UnOp {
+ fold_un_op(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_use_glob(&mut self, i: crate::UseGlob) -> crate::UseGlob {
+ fold_use_glob(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_use_group(&mut self, i: crate::UseGroup) -> crate::UseGroup {
+ fold_use_group(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_use_name(&mut self, i: crate::UseName) -> crate::UseName {
+ fold_use_name(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_use_path(&mut self, i: crate::UsePath) -> crate::UsePath {
+ fold_use_path(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_use_rename(&mut self, i: crate::UseRename) -> crate::UseRename {
+ fold_use_rename(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_use_tree(&mut self, i: crate::UseTree) -> crate::UseTree {
+ fold_use_tree(self, i)
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn fold_variadic(&mut self, i: crate::Variadic) -> crate::Variadic {
+ fold_variadic(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_variant(&mut self, i: crate::Variant) -> crate::Variant {
+ fold_variant(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_vis_restricted(&mut self, i: crate::VisRestricted) -> crate::VisRestricted {
+ fold_vis_restricted(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_visibility(&mut self, i: crate::Visibility) -> crate::Visibility {
+ fold_visibility(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_where_clause(&mut self, i: crate::WhereClause) -> crate::WhereClause {
+ fold_where_clause(self, i)
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn fold_where_predicate(
+ &mut self,
+ i: crate::WherePredicate,
+ ) -> crate::WherePredicate {
+ fold_where_predicate(self, i)
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_abi<F>(f: &mut F, node: crate::Abi) -> crate::Abi
+where
+ F: Fold + ?Sized,
+{
+ crate::Abi {
+ extern_token: node.extern_token,
+ name: (node.name).map(|it| f.fold_lit_str(it)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_angle_bracketed_generic_arguments<F>(
+ f: &mut F,
+ node: crate::AngleBracketedGenericArguments,
+) -> crate::AngleBracketedGenericArguments
+where
+ F: Fold + ?Sized,
+{
+ crate::AngleBracketedGenericArguments {
+ colon2_token: node.colon2_token,
+ lt_token: node.lt_token,
+ args: crate::punctuated::fold(node.args, f, F::fold_generic_argument),
+ gt_token: node.gt_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_arm<F>(f: &mut F, node: crate::Arm) -> crate::Arm
+where
+ F: Fold + ?Sized,
+{
+ crate::Arm {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ pat: f.fold_pat(node.pat),
+ guard: (node.guard).map(|it| ((it).0, Box::new(f.fold_expr(*(it).1)))),
+ fat_arrow_token: node.fat_arrow_token,
+ body: Box::new(f.fold_expr(*node.body)),
+ comma: node.comma,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_assoc_const<F>(f: &mut F, node: crate::AssocConst) -> crate::AssocConst
+where
+ F: Fold + ?Sized,
+{
+ crate::AssocConst {
+ ident: f.fold_ident(node.ident),
+ generics: (node.generics).map(|it| f.fold_angle_bracketed_generic_arguments(it)),
+ eq_token: node.eq_token,
+ value: f.fold_expr(node.value),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_assoc_type<F>(f: &mut F, node: crate::AssocType) -> crate::AssocType
+where
+ F: Fold + ?Sized,
+{
+ crate::AssocType {
+ ident: f.fold_ident(node.ident),
+ generics: (node.generics).map(|it| f.fold_angle_bracketed_generic_arguments(it)),
+ eq_token: node.eq_token,
+ ty: f.fold_type(node.ty),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_attr_style<F>(f: &mut F, node: crate::AttrStyle) -> crate::AttrStyle
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::AttrStyle::Outer => crate::AttrStyle::Outer,
+ crate::AttrStyle::Inner(_binding_0) => crate::AttrStyle::Inner(_binding_0),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_attribute<F>(f: &mut F, node: crate::Attribute) -> crate::Attribute
+where
+ F: Fold + ?Sized,
+{
+ crate::Attribute {
+ pound_token: node.pound_token,
+ style: f.fold_attr_style(node.style),
+ bracket_token: node.bracket_token,
+ meta: f.fold_meta(node.meta),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_bare_fn_arg<F>(f: &mut F, node: crate::BareFnArg) -> crate::BareFnArg
+where
+ F: Fold + ?Sized,
+{
+ crate::BareFnArg {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ name: (node.name).map(|it| (f.fold_ident((it).0), (it).1)),
+ ty: f.fold_type(node.ty),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_bare_variadic<F>(f: &mut F, node: crate::BareVariadic) -> crate::BareVariadic
+where
+ F: Fold + ?Sized,
+{
+ crate::BareVariadic {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ name: (node.name).map(|it| (f.fold_ident((it).0), (it).1)),
+ dots: node.dots,
+ comma: node.comma,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_bin_op<F>(f: &mut F, node: crate::BinOp) -> crate::BinOp
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::BinOp::Add(_binding_0) => crate::BinOp::Add(_binding_0),
+ crate::BinOp::Sub(_binding_0) => crate::BinOp::Sub(_binding_0),
+ crate::BinOp::Mul(_binding_0) => crate::BinOp::Mul(_binding_0),
+ crate::BinOp::Div(_binding_0) => crate::BinOp::Div(_binding_0),
+ crate::BinOp::Rem(_binding_0) => crate::BinOp::Rem(_binding_0),
+ crate::BinOp::And(_binding_0) => crate::BinOp::And(_binding_0),
+ crate::BinOp::Or(_binding_0) => crate::BinOp::Or(_binding_0),
+ crate::BinOp::BitXor(_binding_0) => crate::BinOp::BitXor(_binding_0),
+ crate::BinOp::BitAnd(_binding_0) => crate::BinOp::BitAnd(_binding_0),
+ crate::BinOp::BitOr(_binding_0) => crate::BinOp::BitOr(_binding_0),
+ crate::BinOp::Shl(_binding_0) => crate::BinOp::Shl(_binding_0),
+ crate::BinOp::Shr(_binding_0) => crate::BinOp::Shr(_binding_0),
+ crate::BinOp::Eq(_binding_0) => crate::BinOp::Eq(_binding_0),
+ crate::BinOp::Lt(_binding_0) => crate::BinOp::Lt(_binding_0),
+ crate::BinOp::Le(_binding_0) => crate::BinOp::Le(_binding_0),
+ crate::BinOp::Ne(_binding_0) => crate::BinOp::Ne(_binding_0),
+ crate::BinOp::Ge(_binding_0) => crate::BinOp::Ge(_binding_0),
+ crate::BinOp::Gt(_binding_0) => crate::BinOp::Gt(_binding_0),
+ crate::BinOp::AddAssign(_binding_0) => crate::BinOp::AddAssign(_binding_0),
+ crate::BinOp::SubAssign(_binding_0) => crate::BinOp::SubAssign(_binding_0),
+ crate::BinOp::MulAssign(_binding_0) => crate::BinOp::MulAssign(_binding_0),
+ crate::BinOp::DivAssign(_binding_0) => crate::BinOp::DivAssign(_binding_0),
+ crate::BinOp::RemAssign(_binding_0) => crate::BinOp::RemAssign(_binding_0),
+ crate::BinOp::BitXorAssign(_binding_0) => crate::BinOp::BitXorAssign(_binding_0),
+ crate::BinOp::BitAndAssign(_binding_0) => crate::BinOp::BitAndAssign(_binding_0),
+ crate::BinOp::BitOrAssign(_binding_0) => crate::BinOp::BitOrAssign(_binding_0),
+ crate::BinOp::ShlAssign(_binding_0) => crate::BinOp::ShlAssign(_binding_0),
+ crate::BinOp::ShrAssign(_binding_0) => crate::BinOp::ShrAssign(_binding_0),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_block<F>(f: &mut F, node: crate::Block) -> crate::Block
+where
+ F: Fold + ?Sized,
+{
+ crate::Block {
+ brace_token: node.brace_token,
+ stmts: fold_vec(node.stmts, f, F::fold_stmt),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_bound_lifetimes<F>(
+ f: &mut F,
+ node: crate::BoundLifetimes,
+) -> crate::BoundLifetimes
+where
+ F: Fold + ?Sized,
+{
+ crate::BoundLifetimes {
+ for_token: node.for_token,
+ lt_token: node.lt_token,
+ lifetimes: crate::punctuated::fold(node.lifetimes, f, F::fold_generic_param),
+ gt_token: node.gt_token,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_const_param<F>(f: &mut F, node: crate::ConstParam) -> crate::ConstParam
+where
+ F: Fold + ?Sized,
+{
+ crate::ConstParam {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ const_token: node.const_token,
+ ident: f.fold_ident(node.ident),
+ colon_token: node.colon_token,
+ ty: f.fold_type(node.ty),
+ eq_token: node.eq_token,
+ default: (node.default).map(|it| f.fold_expr(it)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_constraint<F>(f: &mut F, node: crate::Constraint) -> crate::Constraint
+where
+ F: Fold + ?Sized,
+{
+ crate::Constraint {
+ ident: f.fold_ident(node.ident),
+ generics: (node.generics).map(|it| f.fold_angle_bracketed_generic_arguments(it)),
+ colon_token: node.colon_token,
+ bounds: crate::punctuated::fold(node.bounds, f, F::fold_type_param_bound),
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn fold_data<F>(f: &mut F, node: crate::Data) -> crate::Data
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::Data::Struct(_binding_0) => {
+ crate::Data::Struct(f.fold_data_struct(_binding_0))
+ }
+ crate::Data::Enum(_binding_0) => crate::Data::Enum(f.fold_data_enum(_binding_0)),
+ crate::Data::Union(_binding_0) => {
+ crate::Data::Union(f.fold_data_union(_binding_0))
+ }
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn fold_data_enum<F>(f: &mut F, node: crate::DataEnum) -> crate::DataEnum
+where
+ F: Fold + ?Sized,
+{
+ crate::DataEnum {
+ enum_token: node.enum_token,
+ brace_token: node.brace_token,
+ variants: crate::punctuated::fold(node.variants, f, F::fold_variant),
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn fold_data_struct<F>(f: &mut F, node: crate::DataStruct) -> crate::DataStruct
+where
+ F: Fold + ?Sized,
+{
+ crate::DataStruct {
+ struct_token: node.struct_token,
+ fields: f.fold_fields(node.fields),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn fold_data_union<F>(f: &mut F, node: crate::DataUnion) -> crate::DataUnion
+where
+ F: Fold + ?Sized,
+{
+ crate::DataUnion {
+ union_token: node.union_token,
+ fields: f.fold_fields_named(node.fields),
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn fold_derive_input<F>(f: &mut F, node: crate::DeriveInput) -> crate::DeriveInput
+where
+ F: Fold + ?Sized,
+{
+ crate::DeriveInput {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ data: f.fold_data(node.data),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr<F>(f: &mut F, node: crate::Expr) -> crate::Expr
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::Expr::Array(_binding_0) => {
+ crate::Expr::Array(full!(f.fold_expr_array(_binding_0)))
+ }
+ crate::Expr::Assign(_binding_0) => {
+ crate::Expr::Assign(full!(f.fold_expr_assign(_binding_0)))
+ }
+ crate::Expr::Async(_binding_0) => {
+ crate::Expr::Async(full!(f.fold_expr_async(_binding_0)))
+ }
+ crate::Expr::Await(_binding_0) => {
+ crate::Expr::Await(full!(f.fold_expr_await(_binding_0)))
+ }
+ crate::Expr::Binary(_binding_0) => {
+ crate::Expr::Binary(f.fold_expr_binary(_binding_0))
+ }
+ crate::Expr::Block(_binding_0) => {
+ crate::Expr::Block(full!(f.fold_expr_block(_binding_0)))
+ }
+ crate::Expr::Break(_binding_0) => {
+ crate::Expr::Break(full!(f.fold_expr_break(_binding_0)))
+ }
+ crate::Expr::Call(_binding_0) => crate::Expr::Call(f.fold_expr_call(_binding_0)),
+ crate::Expr::Cast(_binding_0) => crate::Expr::Cast(f.fold_expr_cast(_binding_0)),
+ crate::Expr::Closure(_binding_0) => {
+ crate::Expr::Closure(full!(f.fold_expr_closure(_binding_0)))
+ }
+ crate::Expr::Const(_binding_0) => {
+ crate::Expr::Const(full!(f.fold_expr_const(_binding_0)))
+ }
+ crate::Expr::Continue(_binding_0) => {
+ crate::Expr::Continue(full!(f.fold_expr_continue(_binding_0)))
+ }
+ crate::Expr::Field(_binding_0) => {
+ crate::Expr::Field(f.fold_expr_field(_binding_0))
+ }
+ crate::Expr::ForLoop(_binding_0) => {
+ crate::Expr::ForLoop(full!(f.fold_expr_for_loop(_binding_0)))
+ }
+ crate::Expr::Group(_binding_0) => {
+ crate::Expr::Group(f.fold_expr_group(_binding_0))
+ }
+ crate::Expr::If(_binding_0) => crate::Expr::If(full!(f.fold_expr_if(_binding_0))),
+ crate::Expr::Index(_binding_0) => {
+ crate::Expr::Index(f.fold_expr_index(_binding_0))
+ }
+ crate::Expr::Infer(_binding_0) => {
+ crate::Expr::Infer(full!(f.fold_expr_infer(_binding_0)))
+ }
+ crate::Expr::Let(_binding_0) => {
+ crate::Expr::Let(full!(f.fold_expr_let(_binding_0)))
+ }
+ crate::Expr::Lit(_binding_0) => crate::Expr::Lit(f.fold_expr_lit(_binding_0)),
+ crate::Expr::Loop(_binding_0) => {
+ crate::Expr::Loop(full!(f.fold_expr_loop(_binding_0)))
+ }
+ crate::Expr::Macro(_binding_0) => {
+ crate::Expr::Macro(f.fold_expr_macro(_binding_0))
+ }
+ crate::Expr::Match(_binding_0) => {
+ crate::Expr::Match(full!(f.fold_expr_match(_binding_0)))
+ }
+ crate::Expr::MethodCall(_binding_0) => {
+ crate::Expr::MethodCall(f.fold_expr_method_call(_binding_0))
+ }
+ crate::Expr::Paren(_binding_0) => {
+ crate::Expr::Paren(f.fold_expr_paren(_binding_0))
+ }
+ crate::Expr::Path(_binding_0) => crate::Expr::Path(f.fold_expr_path(_binding_0)),
+ crate::Expr::Range(_binding_0) => {
+ crate::Expr::Range(full!(f.fold_expr_range(_binding_0)))
+ }
+ crate::Expr::Reference(_binding_0) => {
+ crate::Expr::Reference(f.fold_expr_reference(_binding_0))
+ }
+ crate::Expr::Repeat(_binding_0) => {
+ crate::Expr::Repeat(full!(f.fold_expr_repeat(_binding_0)))
+ }
+ crate::Expr::Return(_binding_0) => {
+ crate::Expr::Return(full!(f.fold_expr_return(_binding_0)))
+ }
+ crate::Expr::Struct(_binding_0) => {
+ crate::Expr::Struct(f.fold_expr_struct(_binding_0))
+ }
+ crate::Expr::Try(_binding_0) => {
+ crate::Expr::Try(full!(f.fold_expr_try(_binding_0)))
+ }
+ crate::Expr::TryBlock(_binding_0) => {
+ crate::Expr::TryBlock(full!(f.fold_expr_try_block(_binding_0)))
+ }
+ crate::Expr::Tuple(_binding_0) => {
+ crate::Expr::Tuple(full!(f.fold_expr_tuple(_binding_0)))
+ }
+ crate::Expr::Unary(_binding_0) => {
+ crate::Expr::Unary(f.fold_expr_unary(_binding_0))
+ }
+ crate::Expr::Unsafe(_binding_0) => {
+ crate::Expr::Unsafe(full!(f.fold_expr_unsafe(_binding_0)))
+ }
+ crate::Expr::Verbatim(_binding_0) => crate::Expr::Verbatim(_binding_0),
+ crate::Expr::While(_binding_0) => {
+ crate::Expr::While(full!(f.fold_expr_while(_binding_0)))
+ }
+ crate::Expr::Yield(_binding_0) => {
+ crate::Expr::Yield(full!(f.fold_expr_yield(_binding_0)))
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_array<F>(f: &mut F, node: crate::ExprArray) -> crate::ExprArray
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprArray {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ bracket_token: node.bracket_token,
+ elems: crate::punctuated::fold(node.elems, f, F::fold_expr),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_assign<F>(f: &mut F, node: crate::ExprAssign) -> crate::ExprAssign
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprAssign {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ left: Box::new(f.fold_expr(*node.left)),
+ eq_token: node.eq_token,
+ right: Box::new(f.fold_expr(*node.right)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_async<F>(f: &mut F, node: crate::ExprAsync) -> crate::ExprAsync
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprAsync {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ async_token: node.async_token,
+ capture: node.capture,
+ block: f.fold_block(node.block),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_await<F>(f: &mut F, node: crate::ExprAwait) -> crate::ExprAwait
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprAwait {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ base: Box::new(f.fold_expr(*node.base)),
+ dot_token: node.dot_token,
+ await_token: node.await_token,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_binary<F>(f: &mut F, node: crate::ExprBinary) -> crate::ExprBinary
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprBinary {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ left: Box::new(f.fold_expr(*node.left)),
+ op: f.fold_bin_op(node.op),
+ right: Box::new(f.fold_expr(*node.right)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_block<F>(f: &mut F, node: crate::ExprBlock) -> crate::ExprBlock
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprBlock {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ label: (node.label).map(|it| f.fold_label(it)),
+ block: f.fold_block(node.block),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_break<F>(f: &mut F, node: crate::ExprBreak) -> crate::ExprBreak
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprBreak {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ break_token: node.break_token,
+ label: (node.label).map(|it| f.fold_lifetime(it)),
+ expr: (node.expr).map(|it| Box::new(f.fold_expr(*it))),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_call<F>(f: &mut F, node: crate::ExprCall) -> crate::ExprCall
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprCall {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ func: Box::new(f.fold_expr(*node.func)),
+ paren_token: node.paren_token,
+ args: crate::punctuated::fold(node.args, f, F::fold_expr),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_cast<F>(f: &mut F, node: crate::ExprCast) -> crate::ExprCast
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprCast {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ expr: Box::new(f.fold_expr(*node.expr)),
+ as_token: node.as_token,
+ ty: Box::new(f.fold_type(*node.ty)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_closure<F>(f: &mut F, node: crate::ExprClosure) -> crate::ExprClosure
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprClosure {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ lifetimes: (node.lifetimes).map(|it| f.fold_bound_lifetimes(it)),
+ constness: node.constness,
+ movability: node.movability,
+ asyncness: node.asyncness,
+ capture: node.capture,
+ or1_token: node.or1_token,
+ inputs: crate::punctuated::fold(node.inputs, f, F::fold_pat),
+ or2_token: node.or2_token,
+ output: f.fold_return_type(node.output),
+ body: Box::new(f.fold_expr(*node.body)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_const<F>(f: &mut F, node: crate::ExprConst) -> crate::ExprConst
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprConst {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ const_token: node.const_token,
+ block: f.fold_block(node.block),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_continue<F>(f: &mut F, node: crate::ExprContinue) -> crate::ExprContinue
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprContinue {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ continue_token: node.continue_token,
+ label: (node.label).map(|it| f.fold_lifetime(it)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_field<F>(f: &mut F, node: crate::ExprField) -> crate::ExprField
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprField {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ base: Box::new(f.fold_expr(*node.base)),
+ dot_token: node.dot_token,
+ member: f.fold_member(node.member),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_for_loop<F>(f: &mut F, node: crate::ExprForLoop) -> crate::ExprForLoop
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprForLoop {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ label: (node.label).map(|it| f.fold_label(it)),
+ for_token: node.for_token,
+ pat: Box::new(f.fold_pat(*node.pat)),
+ in_token: node.in_token,
+ expr: Box::new(f.fold_expr(*node.expr)),
+ body: f.fold_block(node.body),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_group<F>(f: &mut F, node: crate::ExprGroup) -> crate::ExprGroup
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprGroup {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ group_token: node.group_token,
+ expr: Box::new(f.fold_expr(*node.expr)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_if<F>(f: &mut F, node: crate::ExprIf) -> crate::ExprIf
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprIf {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ if_token: node.if_token,
+ cond: Box::new(f.fold_expr(*node.cond)),
+ then_branch: f.fold_block(node.then_branch),
+ else_branch: (node.else_branch)
+ .map(|it| ((it).0, Box::new(f.fold_expr(*(it).1)))),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_index<F>(f: &mut F, node: crate::ExprIndex) -> crate::ExprIndex
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprIndex {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ expr: Box::new(f.fold_expr(*node.expr)),
+ bracket_token: node.bracket_token,
+ index: Box::new(f.fold_expr(*node.index)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_infer<F>(f: &mut F, node: crate::ExprInfer) -> crate::ExprInfer
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprInfer {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ underscore_token: node.underscore_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_let<F>(f: &mut F, node: crate::ExprLet) -> crate::ExprLet
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprLet {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ let_token: node.let_token,
+ pat: Box::new(f.fold_pat(*node.pat)),
+ eq_token: node.eq_token,
+ expr: Box::new(f.fold_expr(*node.expr)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_lit<F>(f: &mut F, node: crate::ExprLit) -> crate::ExprLit
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprLit {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ lit: f.fold_lit(node.lit),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_loop<F>(f: &mut F, node: crate::ExprLoop) -> crate::ExprLoop
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprLoop {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ label: (node.label).map(|it| f.fold_label(it)),
+ loop_token: node.loop_token,
+ body: f.fold_block(node.body),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_macro<F>(f: &mut F, node: crate::ExprMacro) -> crate::ExprMacro
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprMacro {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ mac: f.fold_macro(node.mac),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_match<F>(f: &mut F, node: crate::ExprMatch) -> crate::ExprMatch
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprMatch {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ match_token: node.match_token,
+ expr: Box::new(f.fold_expr(*node.expr)),
+ brace_token: node.brace_token,
+ arms: fold_vec(node.arms, f, F::fold_arm),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_method_call<F>(
+ f: &mut F,
+ node: crate::ExprMethodCall,
+) -> crate::ExprMethodCall
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprMethodCall {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ receiver: Box::new(f.fold_expr(*node.receiver)),
+ dot_token: node.dot_token,
+ method: f.fold_ident(node.method),
+ turbofish: (node.turbofish)
+ .map(|it| f.fold_angle_bracketed_generic_arguments(it)),
+ paren_token: node.paren_token,
+ args: crate::punctuated::fold(node.args, f, F::fold_expr),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_paren<F>(f: &mut F, node: crate::ExprParen) -> crate::ExprParen
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprParen {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ paren_token: node.paren_token,
+ expr: Box::new(f.fold_expr(*node.expr)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_path<F>(f: &mut F, node: crate::ExprPath) -> crate::ExprPath
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprPath {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ qself: (node.qself).map(|it| f.fold_qself(it)),
+ path: f.fold_path(node.path),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_range<F>(f: &mut F, node: crate::ExprRange) -> crate::ExprRange
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprRange {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ start: (node.start).map(|it| Box::new(f.fold_expr(*it))),
+ limits: f.fold_range_limits(node.limits),
+ end: (node.end).map(|it| Box::new(f.fold_expr(*it))),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_reference<F>(
+ f: &mut F,
+ node: crate::ExprReference,
+) -> crate::ExprReference
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprReference {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ and_token: node.and_token,
+ mutability: node.mutability,
+ expr: Box::new(f.fold_expr(*node.expr)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_repeat<F>(f: &mut F, node: crate::ExprRepeat) -> crate::ExprRepeat
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprRepeat {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ bracket_token: node.bracket_token,
+ expr: Box::new(f.fold_expr(*node.expr)),
+ semi_token: node.semi_token,
+ len: Box::new(f.fold_expr(*node.len)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_return<F>(f: &mut F, node: crate::ExprReturn) -> crate::ExprReturn
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprReturn {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ return_token: node.return_token,
+ expr: (node.expr).map(|it| Box::new(f.fold_expr(*it))),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_struct<F>(f: &mut F, node: crate::ExprStruct) -> crate::ExprStruct
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprStruct {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ qself: (node.qself).map(|it| f.fold_qself(it)),
+ path: f.fold_path(node.path),
+ brace_token: node.brace_token,
+ fields: crate::punctuated::fold(node.fields, f, F::fold_field_value),
+ dot2_token: node.dot2_token,
+ rest: (node.rest).map(|it| Box::new(f.fold_expr(*it))),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_try<F>(f: &mut F, node: crate::ExprTry) -> crate::ExprTry
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprTry {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ expr: Box::new(f.fold_expr(*node.expr)),
+ question_token: node.question_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_try_block<F>(
+ f: &mut F,
+ node: crate::ExprTryBlock,
+) -> crate::ExprTryBlock
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprTryBlock {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ try_token: node.try_token,
+ block: f.fold_block(node.block),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_tuple<F>(f: &mut F, node: crate::ExprTuple) -> crate::ExprTuple
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprTuple {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ paren_token: node.paren_token,
+ elems: crate::punctuated::fold(node.elems, f, F::fold_expr),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_expr_unary<F>(f: &mut F, node: crate::ExprUnary) -> crate::ExprUnary
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprUnary {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ op: f.fold_un_op(node.op),
+ expr: Box::new(f.fold_expr(*node.expr)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_unsafe<F>(f: &mut F, node: crate::ExprUnsafe) -> crate::ExprUnsafe
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprUnsafe {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ unsafe_token: node.unsafe_token,
+ block: f.fold_block(node.block),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_while<F>(f: &mut F, node: crate::ExprWhile) -> crate::ExprWhile
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprWhile {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ label: (node.label).map(|it| f.fold_label(it)),
+ while_token: node.while_token,
+ cond: Box::new(f.fold_expr(*node.cond)),
+ body: f.fold_block(node.body),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_expr_yield<F>(f: &mut F, node: crate::ExprYield) -> crate::ExprYield
+where
+ F: Fold + ?Sized,
+{
+ crate::ExprYield {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ yield_token: node.yield_token,
+ expr: (node.expr).map(|it| Box::new(f.fold_expr(*it))),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_field<F>(f: &mut F, node: crate::Field) -> crate::Field
+where
+ F: Fold + ?Sized,
+{
+ crate::Field {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ mutability: f.fold_field_mutability(node.mutability),
+ ident: (node.ident).map(|it| f.fold_ident(it)),
+ colon_token: node.colon_token,
+ ty: f.fold_type(node.ty),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_field_mutability<F>(
+ f: &mut F,
+ node: crate::FieldMutability,
+) -> crate::FieldMutability
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::FieldMutability::None => crate::FieldMutability::None,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_field_pat<F>(f: &mut F, node: crate::FieldPat) -> crate::FieldPat
+where
+ F: Fold + ?Sized,
+{
+ crate::FieldPat {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ member: f.fold_member(node.member),
+ colon_token: node.colon_token,
+ pat: Box::new(f.fold_pat(*node.pat)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_field_value<F>(f: &mut F, node: crate::FieldValue) -> crate::FieldValue
+where
+ F: Fold + ?Sized,
+{
+ crate::FieldValue {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ member: f.fold_member(node.member),
+ colon_token: node.colon_token,
+ expr: f.fold_expr(node.expr),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_fields<F>(f: &mut F, node: crate::Fields) -> crate::Fields
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::Fields::Named(_binding_0) => {
+ crate::Fields::Named(f.fold_fields_named(_binding_0))
+ }
+ crate::Fields::Unnamed(_binding_0) => {
+ crate::Fields::Unnamed(f.fold_fields_unnamed(_binding_0))
+ }
+ crate::Fields::Unit => crate::Fields::Unit,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_fields_named<F>(f: &mut F, node: crate::FieldsNamed) -> crate::FieldsNamed
+where
+ F: Fold + ?Sized,
+{
+ crate::FieldsNamed {
+ brace_token: node.brace_token,
+ named: crate::punctuated::fold(node.named, f, F::fold_field),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_fields_unnamed<F>(
+ f: &mut F,
+ node: crate::FieldsUnnamed,
+) -> crate::FieldsUnnamed
+where
+ F: Fold + ?Sized,
+{
+ crate::FieldsUnnamed {
+ paren_token: node.paren_token,
+ unnamed: crate::punctuated::fold(node.unnamed, f, F::fold_field),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_file<F>(f: &mut F, node: crate::File) -> crate::File
+where
+ F: Fold + ?Sized,
+{
+ crate::File {
+ shebang: node.shebang,
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ items: fold_vec(node.items, f, F::fold_item),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_fn_arg<F>(f: &mut F, node: crate::FnArg) -> crate::FnArg
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::FnArg::Receiver(_binding_0) => {
+ crate::FnArg::Receiver(f.fold_receiver(_binding_0))
+ }
+ crate::FnArg::Typed(_binding_0) => {
+ crate::FnArg::Typed(f.fold_pat_type(_binding_0))
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_foreign_item<F>(f: &mut F, node: crate::ForeignItem) -> crate::ForeignItem
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::ForeignItem::Fn(_binding_0) => {
+ crate::ForeignItem::Fn(f.fold_foreign_item_fn(_binding_0))
+ }
+ crate::ForeignItem::Static(_binding_0) => {
+ crate::ForeignItem::Static(f.fold_foreign_item_static(_binding_0))
+ }
+ crate::ForeignItem::Type(_binding_0) => {
+ crate::ForeignItem::Type(f.fold_foreign_item_type(_binding_0))
+ }
+ crate::ForeignItem::Macro(_binding_0) => {
+ crate::ForeignItem::Macro(f.fold_foreign_item_macro(_binding_0))
+ }
+ crate::ForeignItem::Verbatim(_binding_0) => {
+ crate::ForeignItem::Verbatim(_binding_0)
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_foreign_item_fn<F>(
+ f: &mut F,
+ node: crate::ForeignItemFn,
+) -> crate::ForeignItemFn
+where
+ F: Fold + ?Sized,
+{
+ crate::ForeignItemFn {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ sig: f.fold_signature(node.sig),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_foreign_item_macro<F>(
+ f: &mut F,
+ node: crate::ForeignItemMacro,
+) -> crate::ForeignItemMacro
+where
+ F: Fold + ?Sized,
+{
+ crate::ForeignItemMacro {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ mac: f.fold_macro(node.mac),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_foreign_item_static<F>(
+ f: &mut F,
+ node: crate::ForeignItemStatic,
+) -> crate::ForeignItemStatic
+where
+ F: Fold + ?Sized,
+{
+ crate::ForeignItemStatic {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ static_token: node.static_token,
+ mutability: f.fold_static_mutability(node.mutability),
+ ident: f.fold_ident(node.ident),
+ colon_token: node.colon_token,
+ ty: Box::new(f.fold_type(*node.ty)),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_foreign_item_type<F>(
+ f: &mut F,
+ node: crate::ForeignItemType,
+) -> crate::ForeignItemType
+where
+ F: Fold + ?Sized,
+{
+ crate::ForeignItemType {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ type_token: node.type_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_generic_argument<F>(
+ f: &mut F,
+ node: crate::GenericArgument,
+) -> crate::GenericArgument
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::GenericArgument::Lifetime(_binding_0) => {
+ crate::GenericArgument::Lifetime(f.fold_lifetime(_binding_0))
+ }
+ crate::GenericArgument::Type(_binding_0) => {
+ crate::GenericArgument::Type(f.fold_type(_binding_0))
+ }
+ crate::GenericArgument::Const(_binding_0) => {
+ crate::GenericArgument::Const(f.fold_expr(_binding_0))
+ }
+ crate::GenericArgument::AssocType(_binding_0) => {
+ crate::GenericArgument::AssocType(f.fold_assoc_type(_binding_0))
+ }
+ crate::GenericArgument::AssocConst(_binding_0) => {
+ crate::GenericArgument::AssocConst(f.fold_assoc_const(_binding_0))
+ }
+ crate::GenericArgument::Constraint(_binding_0) => {
+ crate::GenericArgument::Constraint(f.fold_constraint(_binding_0))
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_generic_param<F>(f: &mut F, node: crate::GenericParam) -> crate::GenericParam
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::GenericParam::Lifetime(_binding_0) => {
+ crate::GenericParam::Lifetime(f.fold_lifetime_param(_binding_0))
+ }
+ crate::GenericParam::Type(_binding_0) => {
+ crate::GenericParam::Type(f.fold_type_param(_binding_0))
+ }
+ crate::GenericParam::Const(_binding_0) => {
+ crate::GenericParam::Const(f.fold_const_param(_binding_0))
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_generics<F>(f: &mut F, node: crate::Generics) -> crate::Generics
+where
+ F: Fold + ?Sized,
+{
+ crate::Generics {
+ lt_token: node.lt_token,
+ params: crate::punctuated::fold(node.params, f, F::fold_generic_param),
+ gt_token: node.gt_token,
+ where_clause: (node.where_clause).map(|it| f.fold_where_clause(it)),
+ }
+}
+pub fn fold_ident<F>(f: &mut F, node: proc_macro2::Ident) -> proc_macro2::Ident
+where
+ F: Fold + ?Sized,
+{
+ let mut node = node;
+ let span = f.fold_span(node.span());
+ node.set_span(span);
+ node
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_impl_item<F>(f: &mut F, node: crate::ImplItem) -> crate::ImplItem
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::ImplItem::Const(_binding_0) => {
+ crate::ImplItem::Const(f.fold_impl_item_const(_binding_0))
+ }
+ crate::ImplItem::Fn(_binding_0) => {
+ crate::ImplItem::Fn(f.fold_impl_item_fn(_binding_0))
+ }
+ crate::ImplItem::Type(_binding_0) => {
+ crate::ImplItem::Type(f.fold_impl_item_type(_binding_0))
+ }
+ crate::ImplItem::Macro(_binding_0) => {
+ crate::ImplItem::Macro(f.fold_impl_item_macro(_binding_0))
+ }
+ crate::ImplItem::Verbatim(_binding_0) => crate::ImplItem::Verbatim(_binding_0),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_impl_item_const<F>(
+ f: &mut F,
+ node: crate::ImplItemConst,
+) -> crate::ImplItemConst
+where
+ F: Fold + ?Sized,
+{
+ crate::ImplItemConst {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ defaultness: node.defaultness,
+ const_token: node.const_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ colon_token: node.colon_token,
+ ty: f.fold_type(node.ty),
+ eq_token: node.eq_token,
+ expr: f.fold_expr(node.expr),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_impl_item_fn<F>(f: &mut F, node: crate::ImplItemFn) -> crate::ImplItemFn
+where
+ F: Fold + ?Sized,
+{
+ crate::ImplItemFn {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ defaultness: node.defaultness,
+ sig: f.fold_signature(node.sig),
+ block: f.fold_block(node.block),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_impl_item_macro<F>(
+ f: &mut F,
+ node: crate::ImplItemMacro,
+) -> crate::ImplItemMacro
+where
+ F: Fold + ?Sized,
+{
+ crate::ImplItemMacro {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ mac: f.fold_macro(node.mac),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_impl_item_type<F>(
+ f: &mut F,
+ node: crate::ImplItemType,
+) -> crate::ImplItemType
+where
+ F: Fold + ?Sized,
+{
+ crate::ImplItemType {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ defaultness: node.defaultness,
+ type_token: node.type_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ eq_token: node.eq_token,
+ ty: f.fold_type(node.ty),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_impl_restriction<F>(
+ f: &mut F,
+ node: crate::ImplRestriction,
+) -> crate::ImplRestriction
+where
+ F: Fold + ?Sized,
+{
+ match node {}
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_index<F>(f: &mut F, node: crate::Index) -> crate::Index
+where
+ F: Fold + ?Sized,
+{
+ crate::Index {
+ index: node.index,
+ span: f.fold_span(node.span),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item<F>(f: &mut F, node: crate::Item) -> crate::Item
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::Item::Const(_binding_0) => {
+ crate::Item::Const(f.fold_item_const(_binding_0))
+ }
+ crate::Item::Enum(_binding_0) => crate::Item::Enum(f.fold_item_enum(_binding_0)),
+ crate::Item::ExternCrate(_binding_0) => {
+ crate::Item::ExternCrate(f.fold_item_extern_crate(_binding_0))
+ }
+ crate::Item::Fn(_binding_0) => crate::Item::Fn(f.fold_item_fn(_binding_0)),
+ crate::Item::ForeignMod(_binding_0) => {
+ crate::Item::ForeignMod(f.fold_item_foreign_mod(_binding_0))
+ }
+ crate::Item::Impl(_binding_0) => crate::Item::Impl(f.fold_item_impl(_binding_0)),
+ crate::Item::Macro(_binding_0) => {
+ crate::Item::Macro(f.fold_item_macro(_binding_0))
+ }
+ crate::Item::Mod(_binding_0) => crate::Item::Mod(f.fold_item_mod(_binding_0)),
+ crate::Item::Static(_binding_0) => {
+ crate::Item::Static(f.fold_item_static(_binding_0))
+ }
+ crate::Item::Struct(_binding_0) => {
+ crate::Item::Struct(f.fold_item_struct(_binding_0))
+ }
+ crate::Item::Trait(_binding_0) => {
+ crate::Item::Trait(f.fold_item_trait(_binding_0))
+ }
+ crate::Item::TraitAlias(_binding_0) => {
+ crate::Item::TraitAlias(f.fold_item_trait_alias(_binding_0))
+ }
+ crate::Item::Type(_binding_0) => crate::Item::Type(f.fold_item_type(_binding_0)),
+ crate::Item::Union(_binding_0) => {
+ crate::Item::Union(f.fold_item_union(_binding_0))
+ }
+ crate::Item::Use(_binding_0) => crate::Item::Use(f.fold_item_use(_binding_0)),
+ crate::Item::Verbatim(_binding_0) => crate::Item::Verbatim(_binding_0),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_const<F>(f: &mut F, node: crate::ItemConst) -> crate::ItemConst
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemConst {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ const_token: node.const_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ colon_token: node.colon_token,
+ ty: Box::new(f.fold_type(*node.ty)),
+ eq_token: node.eq_token,
+ expr: Box::new(f.fold_expr(*node.expr)),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_enum<F>(f: &mut F, node: crate::ItemEnum) -> crate::ItemEnum
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemEnum {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ enum_token: node.enum_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ brace_token: node.brace_token,
+ variants: crate::punctuated::fold(node.variants, f, F::fold_variant),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_extern_crate<F>(
+ f: &mut F,
+ node: crate::ItemExternCrate,
+) -> crate::ItemExternCrate
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemExternCrate {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ extern_token: node.extern_token,
+ crate_token: node.crate_token,
+ ident: f.fold_ident(node.ident),
+ rename: (node.rename).map(|it| ((it).0, f.fold_ident((it).1))),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_fn<F>(f: &mut F, node: crate::ItemFn) -> crate::ItemFn
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemFn {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ sig: f.fold_signature(node.sig),
+ block: Box::new(f.fold_block(*node.block)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_foreign_mod<F>(
+ f: &mut F,
+ node: crate::ItemForeignMod,
+) -> crate::ItemForeignMod
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemForeignMod {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ unsafety: node.unsafety,
+ abi: f.fold_abi(node.abi),
+ brace_token: node.brace_token,
+ items: fold_vec(node.items, f, F::fold_foreign_item),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_impl<F>(f: &mut F, node: crate::ItemImpl) -> crate::ItemImpl
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemImpl {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ defaultness: node.defaultness,
+ unsafety: node.unsafety,
+ impl_token: node.impl_token,
+ generics: f.fold_generics(node.generics),
+ trait_: (node.trait_).map(|it| ((it).0, f.fold_path((it).1), (it).2)),
+ self_ty: Box::new(f.fold_type(*node.self_ty)),
+ brace_token: node.brace_token,
+ items: fold_vec(node.items, f, F::fold_impl_item),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_macro<F>(f: &mut F, node: crate::ItemMacro) -> crate::ItemMacro
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemMacro {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ ident: (node.ident).map(|it| f.fold_ident(it)),
+ mac: f.fold_macro(node.mac),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_mod<F>(f: &mut F, node: crate::ItemMod) -> crate::ItemMod
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemMod {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ unsafety: node.unsafety,
+ mod_token: node.mod_token,
+ ident: f.fold_ident(node.ident),
+ content: (node.content).map(|it| ((it).0, fold_vec((it).1, f, F::fold_item))),
+ semi: node.semi,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_static<F>(f: &mut F, node: crate::ItemStatic) -> crate::ItemStatic
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemStatic {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ static_token: node.static_token,
+ mutability: f.fold_static_mutability(node.mutability),
+ ident: f.fold_ident(node.ident),
+ colon_token: node.colon_token,
+ ty: Box::new(f.fold_type(*node.ty)),
+ eq_token: node.eq_token,
+ expr: Box::new(f.fold_expr(*node.expr)),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_struct<F>(f: &mut F, node: crate::ItemStruct) -> crate::ItemStruct
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemStruct {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ struct_token: node.struct_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ fields: f.fold_fields(node.fields),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_trait<F>(f: &mut F, node: crate::ItemTrait) -> crate::ItemTrait
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemTrait {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ unsafety: node.unsafety,
+ auto_token: node.auto_token,
+ restriction: (node.restriction).map(|it| f.fold_impl_restriction(it)),
+ trait_token: node.trait_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ colon_token: node.colon_token,
+ supertraits: crate::punctuated::fold(
+ node.supertraits,
+ f,
+ F::fold_type_param_bound,
+ ),
+ brace_token: node.brace_token,
+ items: fold_vec(node.items, f, F::fold_trait_item),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_trait_alias<F>(
+ f: &mut F,
+ node: crate::ItemTraitAlias,
+) -> crate::ItemTraitAlias
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemTraitAlias {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ trait_token: node.trait_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ eq_token: node.eq_token,
+ bounds: crate::punctuated::fold(node.bounds, f, F::fold_type_param_bound),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_type<F>(f: &mut F, node: crate::ItemType) -> crate::ItemType
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemType {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ type_token: node.type_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ eq_token: node.eq_token,
+ ty: Box::new(f.fold_type(*node.ty)),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_union<F>(f: &mut F, node: crate::ItemUnion) -> crate::ItemUnion
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemUnion {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ union_token: node.union_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ fields: f.fold_fields_named(node.fields),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_item_use<F>(f: &mut F, node: crate::ItemUse) -> crate::ItemUse
+where
+ F: Fold + ?Sized,
+{
+ crate::ItemUse {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ vis: f.fold_visibility(node.vis),
+ use_token: node.use_token,
+ leading_colon: node.leading_colon,
+ tree: f.fold_use_tree(node.tree),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_label<F>(f: &mut F, node: crate::Label) -> crate::Label
+where
+ F: Fold + ?Sized,
+{
+ crate::Label {
+ name: f.fold_lifetime(node.name),
+ colon_token: node.colon_token,
+ }
+}
+pub fn fold_lifetime<F>(f: &mut F, node: crate::Lifetime) -> crate::Lifetime
+where
+ F: Fold + ?Sized,
+{
+ crate::Lifetime {
+ apostrophe: f.fold_span(node.apostrophe),
+ ident: f.fold_ident(node.ident),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_lifetime_param<F>(
+ f: &mut F,
+ node: crate::LifetimeParam,
+) -> crate::LifetimeParam
+where
+ F: Fold + ?Sized,
+{
+ crate::LifetimeParam {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ lifetime: f.fold_lifetime(node.lifetime),
+ colon_token: node.colon_token,
+ bounds: crate::punctuated::fold(node.bounds, f, F::fold_lifetime),
+ }
+}
+pub fn fold_lit<F>(f: &mut F, node: crate::Lit) -> crate::Lit
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::Lit::Str(_binding_0) => crate::Lit::Str(f.fold_lit_str(_binding_0)),
+ crate::Lit::ByteStr(_binding_0) => {
+ crate::Lit::ByteStr(f.fold_lit_byte_str(_binding_0))
+ }
+ crate::Lit::CStr(_binding_0) => crate::Lit::CStr(f.fold_lit_cstr(_binding_0)),
+ crate::Lit::Byte(_binding_0) => crate::Lit::Byte(f.fold_lit_byte(_binding_0)),
+ crate::Lit::Char(_binding_0) => crate::Lit::Char(f.fold_lit_char(_binding_0)),
+ crate::Lit::Int(_binding_0) => crate::Lit::Int(f.fold_lit_int(_binding_0)),
+ crate::Lit::Float(_binding_0) => crate::Lit::Float(f.fold_lit_float(_binding_0)),
+ crate::Lit::Bool(_binding_0) => crate::Lit::Bool(f.fold_lit_bool(_binding_0)),
+ crate::Lit::Verbatim(_binding_0) => crate::Lit::Verbatim(_binding_0),
+ }
+}
+pub fn fold_lit_bool<F>(f: &mut F, node: crate::LitBool) -> crate::LitBool
+where
+ F: Fold + ?Sized,
+{
+ crate::LitBool {
+ value: node.value,
+ span: f.fold_span(node.span),
+ }
+}
+pub fn fold_lit_byte<F>(f: &mut F, node: crate::LitByte) -> crate::LitByte
+where
+ F: Fold + ?Sized,
+{
+ let span = f.fold_span(node.span());
+ let mut node = node;
+ node.set_span(span);
+ node
+}
+pub fn fold_lit_byte_str<F>(f: &mut F, node: crate::LitByteStr) -> crate::LitByteStr
+where
+ F: Fold + ?Sized,
+{
+ let span = f.fold_span(node.span());
+ let mut node = node;
+ node.set_span(span);
+ node
+}
+pub fn fold_lit_cstr<F>(f: &mut F, node: crate::LitCStr) -> crate::LitCStr
+where
+ F: Fold + ?Sized,
+{
+ let span = f.fold_span(node.span());
+ let mut node = node;
+ node.set_span(span);
+ node
+}
+pub fn fold_lit_char<F>(f: &mut F, node: crate::LitChar) -> crate::LitChar
+where
+ F: Fold + ?Sized,
+{
+ let span = f.fold_span(node.span());
+ let mut node = node;
+ node.set_span(span);
+ node
+}
+pub fn fold_lit_float<F>(f: &mut F, node: crate::LitFloat) -> crate::LitFloat
+where
+ F: Fold + ?Sized,
+{
+ let span = f.fold_span(node.span());
+ let mut node = node;
+ node.set_span(span);
+ node
+}
+pub fn fold_lit_int<F>(f: &mut F, node: crate::LitInt) -> crate::LitInt
+where
+ F: Fold + ?Sized,
+{
+ let span = f.fold_span(node.span());
+ let mut node = node;
+ node.set_span(span);
+ node
+}
+pub fn fold_lit_str<F>(f: &mut F, node: crate::LitStr) -> crate::LitStr
+where
+ F: Fold + ?Sized,
+{
+ let span = f.fold_span(node.span());
+ let mut node = node;
+ node.set_span(span);
+ node
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_local<F>(f: &mut F, node: crate::Local) -> crate::Local
+where
+ F: Fold + ?Sized,
+{
+ crate::Local {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ let_token: node.let_token,
+ pat: f.fold_pat(node.pat),
+ init: (node.init).map(|it| f.fold_local_init(it)),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_local_init<F>(f: &mut F, node: crate::LocalInit) -> crate::LocalInit
+where
+ F: Fold + ?Sized,
+{
+ crate::LocalInit {
+ eq_token: node.eq_token,
+ expr: Box::new(f.fold_expr(*node.expr)),
+ diverge: (node.diverge).map(|it| ((it).0, Box::new(f.fold_expr(*(it).1)))),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_macro<F>(f: &mut F, node: crate::Macro) -> crate::Macro
+where
+ F: Fold + ?Sized,
+{
+ crate::Macro {
+ path: f.fold_path(node.path),
+ bang_token: node.bang_token,
+ delimiter: f.fold_macro_delimiter(node.delimiter),
+ tokens: node.tokens,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_macro_delimiter<F>(
+ f: &mut F,
+ node: crate::MacroDelimiter,
+) -> crate::MacroDelimiter
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::MacroDelimiter::Paren(_binding_0) => {
+ crate::MacroDelimiter::Paren(_binding_0)
+ }
+ crate::MacroDelimiter::Brace(_binding_0) => {
+ crate::MacroDelimiter::Brace(_binding_0)
+ }
+ crate::MacroDelimiter::Bracket(_binding_0) => {
+ crate::MacroDelimiter::Bracket(_binding_0)
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_member<F>(f: &mut F, node: crate::Member) -> crate::Member
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::Member::Named(_binding_0) => {
+ crate::Member::Named(f.fold_ident(_binding_0))
+ }
+ crate::Member::Unnamed(_binding_0) => {
+ crate::Member::Unnamed(f.fold_index(_binding_0))
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_meta<F>(f: &mut F, node: crate::Meta) -> crate::Meta
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::Meta::Path(_binding_0) => crate::Meta::Path(f.fold_path(_binding_0)),
+ crate::Meta::List(_binding_0) => crate::Meta::List(f.fold_meta_list(_binding_0)),
+ crate::Meta::NameValue(_binding_0) => {
+ crate::Meta::NameValue(f.fold_meta_name_value(_binding_0))
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_meta_list<F>(f: &mut F, node: crate::MetaList) -> crate::MetaList
+where
+ F: Fold + ?Sized,
+{
+ crate::MetaList {
+ path: f.fold_path(node.path),
+ delimiter: f.fold_macro_delimiter(node.delimiter),
+ tokens: node.tokens,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_meta_name_value<F>(
+ f: &mut F,
+ node: crate::MetaNameValue,
+) -> crate::MetaNameValue
+where
+ F: Fold + ?Sized,
+{
+ crate::MetaNameValue {
+ path: f.fold_path(node.path),
+ eq_token: node.eq_token,
+ value: f.fold_expr(node.value),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_parenthesized_generic_arguments<F>(
+ f: &mut F,
+ node: crate::ParenthesizedGenericArguments,
+) -> crate::ParenthesizedGenericArguments
+where
+ F: Fold + ?Sized,
+{
+ crate::ParenthesizedGenericArguments {
+ paren_token: node.paren_token,
+ inputs: crate::punctuated::fold(node.inputs, f, F::fold_type),
+ output: f.fold_return_type(node.output),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_pat<F>(f: &mut F, node: crate::Pat) -> crate::Pat
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::Pat::Const(_binding_0) => crate::Pat::Const(f.fold_expr_const(_binding_0)),
+ crate::Pat::Ident(_binding_0) => crate::Pat::Ident(f.fold_pat_ident(_binding_0)),
+ crate::Pat::Lit(_binding_0) => crate::Pat::Lit(f.fold_expr_lit(_binding_0)),
+ crate::Pat::Macro(_binding_0) => crate::Pat::Macro(f.fold_expr_macro(_binding_0)),
+ crate::Pat::Or(_binding_0) => crate::Pat::Or(f.fold_pat_or(_binding_0)),
+ crate::Pat::Paren(_binding_0) => crate::Pat::Paren(f.fold_pat_paren(_binding_0)),
+ crate::Pat::Path(_binding_0) => crate::Pat::Path(f.fold_expr_path(_binding_0)),
+ crate::Pat::Range(_binding_0) => crate::Pat::Range(f.fold_expr_range(_binding_0)),
+ crate::Pat::Reference(_binding_0) => {
+ crate::Pat::Reference(f.fold_pat_reference(_binding_0))
+ }
+ crate::Pat::Rest(_binding_0) => crate::Pat::Rest(f.fold_pat_rest(_binding_0)),
+ crate::Pat::Slice(_binding_0) => crate::Pat::Slice(f.fold_pat_slice(_binding_0)),
+ crate::Pat::Struct(_binding_0) => {
+ crate::Pat::Struct(f.fold_pat_struct(_binding_0))
+ }
+ crate::Pat::Tuple(_binding_0) => crate::Pat::Tuple(f.fold_pat_tuple(_binding_0)),
+ crate::Pat::TupleStruct(_binding_0) => {
+ crate::Pat::TupleStruct(f.fold_pat_tuple_struct(_binding_0))
+ }
+ crate::Pat::Type(_binding_0) => crate::Pat::Type(f.fold_pat_type(_binding_0)),
+ crate::Pat::Verbatim(_binding_0) => crate::Pat::Verbatim(_binding_0),
+ crate::Pat::Wild(_binding_0) => crate::Pat::Wild(f.fold_pat_wild(_binding_0)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_pat_ident<F>(f: &mut F, node: crate::PatIdent) -> crate::PatIdent
+where
+ F: Fold + ?Sized,
+{
+ crate::PatIdent {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ by_ref: node.by_ref,
+ mutability: node.mutability,
+ ident: f.fold_ident(node.ident),
+ subpat: (node.subpat).map(|it| ((it).0, Box::new(f.fold_pat(*(it).1)))),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_pat_or<F>(f: &mut F, node: crate::PatOr) -> crate::PatOr
+where
+ F: Fold + ?Sized,
+{
+ crate::PatOr {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ leading_vert: node.leading_vert,
+ cases: crate::punctuated::fold(node.cases, f, F::fold_pat),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_pat_paren<F>(f: &mut F, node: crate::PatParen) -> crate::PatParen
+where
+ F: Fold + ?Sized,
+{
+ crate::PatParen {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ paren_token: node.paren_token,
+ pat: Box::new(f.fold_pat(*node.pat)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_pat_reference<F>(f: &mut F, node: crate::PatReference) -> crate::PatReference
+where
+ F: Fold + ?Sized,
+{
+ crate::PatReference {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ and_token: node.and_token,
+ mutability: node.mutability,
+ pat: Box::new(f.fold_pat(*node.pat)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_pat_rest<F>(f: &mut F, node: crate::PatRest) -> crate::PatRest
+where
+ F: Fold + ?Sized,
+{
+ crate::PatRest {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ dot2_token: node.dot2_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_pat_slice<F>(f: &mut F, node: crate::PatSlice) -> crate::PatSlice
+where
+ F: Fold + ?Sized,
+{
+ crate::PatSlice {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ bracket_token: node.bracket_token,
+ elems: crate::punctuated::fold(node.elems, f, F::fold_pat),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_pat_struct<F>(f: &mut F, node: crate::PatStruct) -> crate::PatStruct
+where
+ F: Fold + ?Sized,
+{
+ crate::PatStruct {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ qself: (node.qself).map(|it| f.fold_qself(it)),
+ path: f.fold_path(node.path),
+ brace_token: node.brace_token,
+ fields: crate::punctuated::fold(node.fields, f, F::fold_field_pat),
+ rest: (node.rest).map(|it| f.fold_pat_rest(it)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_pat_tuple<F>(f: &mut F, node: crate::PatTuple) -> crate::PatTuple
+where
+ F: Fold + ?Sized,
+{
+ crate::PatTuple {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ paren_token: node.paren_token,
+ elems: crate::punctuated::fold(node.elems, f, F::fold_pat),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_pat_tuple_struct<F>(
+ f: &mut F,
+ node: crate::PatTupleStruct,
+) -> crate::PatTupleStruct
+where
+ F: Fold + ?Sized,
+{
+ crate::PatTupleStruct {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ qself: (node.qself).map(|it| f.fold_qself(it)),
+ path: f.fold_path(node.path),
+ paren_token: node.paren_token,
+ elems: crate::punctuated::fold(node.elems, f, F::fold_pat),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_pat_type<F>(f: &mut F, node: crate::PatType) -> crate::PatType
+where
+ F: Fold + ?Sized,
+{
+ crate::PatType {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ pat: Box::new(f.fold_pat(*node.pat)),
+ colon_token: node.colon_token,
+ ty: Box::new(f.fold_type(*node.ty)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_pat_wild<F>(f: &mut F, node: crate::PatWild) -> crate::PatWild
+where
+ F: Fold + ?Sized,
+{
+ crate::PatWild {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ underscore_token: node.underscore_token,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_path<F>(f: &mut F, node: crate::Path) -> crate::Path
+where
+ F: Fold + ?Sized,
+{
+ crate::Path {
+ leading_colon: node.leading_colon,
+ segments: crate::punctuated::fold(node.segments, f, F::fold_path_segment),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_path_arguments<F>(
+ f: &mut F,
+ node: crate::PathArguments,
+) -> crate::PathArguments
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::PathArguments::None => crate::PathArguments::None,
+ crate::PathArguments::AngleBracketed(_binding_0) => {
+ crate::PathArguments::AngleBracketed(
+ f.fold_angle_bracketed_generic_arguments(_binding_0),
+ )
+ }
+ crate::PathArguments::Parenthesized(_binding_0) => {
+ crate::PathArguments::Parenthesized(
+ f.fold_parenthesized_generic_arguments(_binding_0),
+ )
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_path_segment<F>(f: &mut F, node: crate::PathSegment) -> crate::PathSegment
+where
+ F: Fold + ?Sized,
+{
+ crate::PathSegment {
+ ident: f.fold_ident(node.ident),
+ arguments: f.fold_path_arguments(node.arguments),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_predicate_lifetime<F>(
+ f: &mut F,
+ node: crate::PredicateLifetime,
+) -> crate::PredicateLifetime
+where
+ F: Fold + ?Sized,
+{
+ crate::PredicateLifetime {
+ lifetime: f.fold_lifetime(node.lifetime),
+ colon_token: node.colon_token,
+ bounds: crate::punctuated::fold(node.bounds, f, F::fold_lifetime),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_predicate_type<F>(
+ f: &mut F,
+ node: crate::PredicateType,
+) -> crate::PredicateType
+where
+ F: Fold + ?Sized,
+{
+ crate::PredicateType {
+ lifetimes: (node.lifetimes).map(|it| f.fold_bound_lifetimes(it)),
+ bounded_ty: f.fold_type(node.bounded_ty),
+ colon_token: node.colon_token,
+ bounds: crate::punctuated::fold(node.bounds, f, F::fold_type_param_bound),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_qself<F>(f: &mut F, node: crate::QSelf) -> crate::QSelf
+where
+ F: Fold + ?Sized,
+{
+ crate::QSelf {
+ lt_token: node.lt_token,
+ ty: Box::new(f.fold_type(*node.ty)),
+ position: node.position,
+ as_token: node.as_token,
+ gt_token: node.gt_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_range_limits<F>(f: &mut F, node: crate::RangeLimits) -> crate::RangeLimits
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::RangeLimits::HalfOpen(_binding_0) => {
+ crate::RangeLimits::HalfOpen(_binding_0)
+ }
+ crate::RangeLimits::Closed(_binding_0) => crate::RangeLimits::Closed(_binding_0),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_receiver<F>(f: &mut F, node: crate::Receiver) -> crate::Receiver
+where
+ F: Fold + ?Sized,
+{
+ crate::Receiver {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ reference: (node.reference)
+ .map(|it| ((it).0, ((it).1).map(|it| f.fold_lifetime(it)))),
+ mutability: node.mutability,
+ self_token: node.self_token,
+ colon_token: node.colon_token,
+ ty: Box::new(f.fold_type(*node.ty)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_return_type<F>(f: &mut F, node: crate::ReturnType) -> crate::ReturnType
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::ReturnType::Default => crate::ReturnType::Default,
+ crate::ReturnType::Type(_binding_0, _binding_1) => {
+ crate::ReturnType::Type(_binding_0, Box::new(f.fold_type(*_binding_1)))
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_signature<F>(f: &mut F, node: crate::Signature) -> crate::Signature
+where
+ F: Fold + ?Sized,
+{
+ crate::Signature {
+ constness: node.constness,
+ asyncness: node.asyncness,
+ unsafety: node.unsafety,
+ abi: (node.abi).map(|it| f.fold_abi(it)),
+ fn_token: node.fn_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ paren_token: node.paren_token,
+ inputs: crate::punctuated::fold(node.inputs, f, F::fold_fn_arg),
+ variadic: (node.variadic).map(|it| f.fold_variadic(it)),
+ output: f.fold_return_type(node.output),
+ }
+}
+pub fn fold_span<F>(f: &mut F, node: proc_macro2::Span) -> proc_macro2::Span
+where
+ F: Fold + ?Sized,
+{
+ node
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_static_mutability<F>(
+ f: &mut F,
+ node: crate::StaticMutability,
+) -> crate::StaticMutability
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::StaticMutability::Mut(_binding_0) => {
+ crate::StaticMutability::Mut(_binding_0)
+ }
+ crate::StaticMutability::None => crate::StaticMutability::None,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_stmt<F>(f: &mut F, node: crate::Stmt) -> crate::Stmt
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::Stmt::Local(_binding_0) => crate::Stmt::Local(f.fold_local(_binding_0)),
+ crate::Stmt::Item(_binding_0) => crate::Stmt::Item(f.fold_item(_binding_0)),
+ crate::Stmt::Expr(_binding_0, _binding_1) => {
+ crate::Stmt::Expr(f.fold_expr(_binding_0), _binding_1)
+ }
+ crate::Stmt::Macro(_binding_0) => {
+ crate::Stmt::Macro(f.fold_stmt_macro(_binding_0))
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_stmt_macro<F>(f: &mut F, node: crate::StmtMacro) -> crate::StmtMacro
+where
+ F: Fold + ?Sized,
+{
+ crate::StmtMacro {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ mac: f.fold_macro(node.mac),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_trait_bound<F>(f: &mut F, node: crate::TraitBound) -> crate::TraitBound
+where
+ F: Fold + ?Sized,
+{
+ crate::TraitBound {
+ paren_token: node.paren_token,
+ modifier: f.fold_trait_bound_modifier(node.modifier),
+ lifetimes: (node.lifetimes).map(|it| f.fold_bound_lifetimes(it)),
+ path: f.fold_path(node.path),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_trait_bound_modifier<F>(
+ f: &mut F,
+ node: crate::TraitBoundModifier,
+) -> crate::TraitBoundModifier
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::TraitBoundModifier::None => crate::TraitBoundModifier::None,
+ crate::TraitBoundModifier::Maybe(_binding_0) => {
+ crate::TraitBoundModifier::Maybe(_binding_0)
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_trait_item<F>(f: &mut F, node: crate::TraitItem) -> crate::TraitItem
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::TraitItem::Const(_binding_0) => {
+ crate::TraitItem::Const(f.fold_trait_item_const(_binding_0))
+ }
+ crate::TraitItem::Fn(_binding_0) => {
+ crate::TraitItem::Fn(f.fold_trait_item_fn(_binding_0))
+ }
+ crate::TraitItem::Type(_binding_0) => {
+ crate::TraitItem::Type(f.fold_trait_item_type(_binding_0))
+ }
+ crate::TraitItem::Macro(_binding_0) => {
+ crate::TraitItem::Macro(f.fold_trait_item_macro(_binding_0))
+ }
+ crate::TraitItem::Verbatim(_binding_0) => crate::TraitItem::Verbatim(_binding_0),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_trait_item_const<F>(
+ f: &mut F,
+ node: crate::TraitItemConst,
+) -> crate::TraitItemConst
+where
+ F: Fold + ?Sized,
+{
+ crate::TraitItemConst {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ const_token: node.const_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ colon_token: node.colon_token,
+ ty: f.fold_type(node.ty),
+ default: (node.default).map(|it| ((it).0, f.fold_expr((it).1))),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_trait_item_fn<F>(f: &mut F, node: crate::TraitItemFn) -> crate::TraitItemFn
+where
+ F: Fold + ?Sized,
+{
+ crate::TraitItemFn {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ sig: f.fold_signature(node.sig),
+ default: (node.default).map(|it| f.fold_block(it)),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_trait_item_macro<F>(
+ f: &mut F,
+ node: crate::TraitItemMacro,
+) -> crate::TraitItemMacro
+where
+ F: Fold + ?Sized,
+{
+ crate::TraitItemMacro {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ mac: f.fold_macro(node.mac),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_trait_item_type<F>(
+ f: &mut F,
+ node: crate::TraitItemType,
+) -> crate::TraitItemType
+where
+ F: Fold + ?Sized,
+{
+ crate::TraitItemType {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ type_token: node.type_token,
+ ident: f.fold_ident(node.ident),
+ generics: f.fold_generics(node.generics),
+ colon_token: node.colon_token,
+ bounds: crate::punctuated::fold(node.bounds, f, F::fold_type_param_bound),
+ default: (node.default).map(|it| ((it).0, f.fold_type((it).1))),
+ semi_token: node.semi_token,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type<F>(f: &mut F, node: crate::Type) -> crate::Type
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::Type::Array(_binding_0) => {
+ crate::Type::Array(f.fold_type_array(_binding_0))
+ }
+ crate::Type::BareFn(_binding_0) => {
+ crate::Type::BareFn(f.fold_type_bare_fn(_binding_0))
+ }
+ crate::Type::Group(_binding_0) => {
+ crate::Type::Group(f.fold_type_group(_binding_0))
+ }
+ crate::Type::ImplTrait(_binding_0) => {
+ crate::Type::ImplTrait(f.fold_type_impl_trait(_binding_0))
+ }
+ crate::Type::Infer(_binding_0) => {
+ crate::Type::Infer(f.fold_type_infer(_binding_0))
+ }
+ crate::Type::Macro(_binding_0) => {
+ crate::Type::Macro(f.fold_type_macro(_binding_0))
+ }
+ crate::Type::Never(_binding_0) => {
+ crate::Type::Never(f.fold_type_never(_binding_0))
+ }
+ crate::Type::Paren(_binding_0) => {
+ crate::Type::Paren(f.fold_type_paren(_binding_0))
+ }
+ crate::Type::Path(_binding_0) => crate::Type::Path(f.fold_type_path(_binding_0)),
+ crate::Type::Ptr(_binding_0) => crate::Type::Ptr(f.fold_type_ptr(_binding_0)),
+ crate::Type::Reference(_binding_0) => {
+ crate::Type::Reference(f.fold_type_reference(_binding_0))
+ }
+ crate::Type::Slice(_binding_0) => {
+ crate::Type::Slice(f.fold_type_slice(_binding_0))
+ }
+ crate::Type::TraitObject(_binding_0) => {
+ crate::Type::TraitObject(f.fold_type_trait_object(_binding_0))
+ }
+ crate::Type::Tuple(_binding_0) => {
+ crate::Type::Tuple(f.fold_type_tuple(_binding_0))
+ }
+ crate::Type::Verbatim(_binding_0) => crate::Type::Verbatim(_binding_0),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_array<F>(f: &mut F, node: crate::TypeArray) -> crate::TypeArray
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeArray {
+ bracket_token: node.bracket_token,
+ elem: Box::new(f.fold_type(*node.elem)),
+ semi_token: node.semi_token,
+ len: f.fold_expr(node.len),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_bare_fn<F>(f: &mut F, node: crate::TypeBareFn) -> crate::TypeBareFn
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeBareFn {
+ lifetimes: (node.lifetimes).map(|it| f.fold_bound_lifetimes(it)),
+ unsafety: node.unsafety,
+ abi: (node.abi).map(|it| f.fold_abi(it)),
+ fn_token: node.fn_token,
+ paren_token: node.paren_token,
+ inputs: crate::punctuated::fold(node.inputs, f, F::fold_bare_fn_arg),
+ variadic: (node.variadic).map(|it| f.fold_bare_variadic(it)),
+ output: f.fold_return_type(node.output),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_group<F>(f: &mut F, node: crate::TypeGroup) -> crate::TypeGroup
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeGroup {
+ group_token: node.group_token,
+ elem: Box::new(f.fold_type(*node.elem)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_impl_trait<F>(
+ f: &mut F,
+ node: crate::TypeImplTrait,
+) -> crate::TypeImplTrait
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeImplTrait {
+ impl_token: node.impl_token,
+ bounds: crate::punctuated::fold(node.bounds, f, F::fold_type_param_bound),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_infer<F>(f: &mut F, node: crate::TypeInfer) -> crate::TypeInfer
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeInfer {
+ underscore_token: node.underscore_token,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_macro<F>(f: &mut F, node: crate::TypeMacro) -> crate::TypeMacro
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeMacro {
+ mac: f.fold_macro(node.mac),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_never<F>(f: &mut F, node: crate::TypeNever) -> crate::TypeNever
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeNever {
+ bang_token: node.bang_token,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_param<F>(f: &mut F, node: crate::TypeParam) -> crate::TypeParam
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeParam {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ ident: f.fold_ident(node.ident),
+ colon_token: node.colon_token,
+ bounds: crate::punctuated::fold(node.bounds, f, F::fold_type_param_bound),
+ eq_token: node.eq_token,
+ default: (node.default).map(|it| f.fold_type(it)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_param_bound<F>(
+ f: &mut F,
+ node: crate::TypeParamBound,
+) -> crate::TypeParamBound
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::TypeParamBound::Trait(_binding_0) => {
+ crate::TypeParamBound::Trait(f.fold_trait_bound(_binding_0))
+ }
+ crate::TypeParamBound::Lifetime(_binding_0) => {
+ crate::TypeParamBound::Lifetime(f.fold_lifetime(_binding_0))
+ }
+ crate::TypeParamBound::Verbatim(_binding_0) => {
+ crate::TypeParamBound::Verbatim(_binding_0)
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_paren<F>(f: &mut F, node: crate::TypeParen) -> crate::TypeParen
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeParen {
+ paren_token: node.paren_token,
+ elem: Box::new(f.fold_type(*node.elem)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_path<F>(f: &mut F, node: crate::TypePath) -> crate::TypePath
+where
+ F: Fold + ?Sized,
+{
+ crate::TypePath {
+ qself: (node.qself).map(|it| f.fold_qself(it)),
+ path: f.fold_path(node.path),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_ptr<F>(f: &mut F, node: crate::TypePtr) -> crate::TypePtr
+where
+ F: Fold + ?Sized,
+{
+ crate::TypePtr {
+ star_token: node.star_token,
+ const_token: node.const_token,
+ mutability: node.mutability,
+ elem: Box::new(f.fold_type(*node.elem)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_reference<F>(
+ f: &mut F,
+ node: crate::TypeReference,
+) -> crate::TypeReference
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeReference {
+ and_token: node.and_token,
+ lifetime: (node.lifetime).map(|it| f.fold_lifetime(it)),
+ mutability: node.mutability,
+ elem: Box::new(f.fold_type(*node.elem)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_slice<F>(f: &mut F, node: crate::TypeSlice) -> crate::TypeSlice
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeSlice {
+ bracket_token: node.bracket_token,
+ elem: Box::new(f.fold_type(*node.elem)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_trait_object<F>(
+ f: &mut F,
+ node: crate::TypeTraitObject,
+) -> crate::TypeTraitObject
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeTraitObject {
+ dyn_token: node.dyn_token,
+ bounds: crate::punctuated::fold(node.bounds, f, F::fold_type_param_bound),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_type_tuple<F>(f: &mut F, node: crate::TypeTuple) -> crate::TypeTuple
+where
+ F: Fold + ?Sized,
+{
+ crate::TypeTuple {
+ paren_token: node.paren_token,
+ elems: crate::punctuated::fold(node.elems, f, F::fold_type),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_un_op<F>(f: &mut F, node: crate::UnOp) -> crate::UnOp
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::UnOp::Deref(_binding_0) => crate::UnOp::Deref(_binding_0),
+ crate::UnOp::Not(_binding_0) => crate::UnOp::Not(_binding_0),
+ crate::UnOp::Neg(_binding_0) => crate::UnOp::Neg(_binding_0),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_use_glob<F>(f: &mut F, node: crate::UseGlob) -> crate::UseGlob
+where
+ F: Fold + ?Sized,
+{
+ crate::UseGlob {
+ star_token: node.star_token,
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_use_group<F>(f: &mut F, node: crate::UseGroup) -> crate::UseGroup
+where
+ F: Fold + ?Sized,
+{
+ crate::UseGroup {
+ brace_token: node.brace_token,
+ items: crate::punctuated::fold(node.items, f, F::fold_use_tree),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_use_name<F>(f: &mut F, node: crate::UseName) -> crate::UseName
+where
+ F: Fold + ?Sized,
+{
+ crate::UseName {
+ ident: f.fold_ident(node.ident),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_use_path<F>(f: &mut F, node: crate::UsePath) -> crate::UsePath
+where
+ F: Fold + ?Sized,
+{
+ crate::UsePath {
+ ident: f.fold_ident(node.ident),
+ colon2_token: node.colon2_token,
+ tree: Box::new(f.fold_use_tree(*node.tree)),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_use_rename<F>(f: &mut F, node: crate::UseRename) -> crate::UseRename
+where
+ F: Fold + ?Sized,
+{
+ crate::UseRename {
+ ident: f.fold_ident(node.ident),
+ as_token: node.as_token,
+ rename: f.fold_ident(node.rename),
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_use_tree<F>(f: &mut F, node: crate::UseTree) -> crate::UseTree
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::UseTree::Path(_binding_0) => {
+ crate::UseTree::Path(f.fold_use_path(_binding_0))
+ }
+ crate::UseTree::Name(_binding_0) => {
+ crate::UseTree::Name(f.fold_use_name(_binding_0))
+ }
+ crate::UseTree::Rename(_binding_0) => {
+ crate::UseTree::Rename(f.fold_use_rename(_binding_0))
+ }
+ crate::UseTree::Glob(_binding_0) => {
+ crate::UseTree::Glob(f.fold_use_glob(_binding_0))
+ }
+ crate::UseTree::Group(_binding_0) => {
+ crate::UseTree::Group(f.fold_use_group(_binding_0))
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn fold_variadic<F>(f: &mut F, node: crate::Variadic) -> crate::Variadic
+where
+ F: Fold + ?Sized,
+{
+ crate::Variadic {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ pat: (node.pat).map(|it| (Box::new(f.fold_pat(*(it).0)), (it).1)),
+ dots: node.dots,
+ comma: node.comma,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_variant<F>(f: &mut F, node: crate::Variant) -> crate::Variant
+where
+ F: Fold + ?Sized,
+{
+ crate::Variant {
+ attrs: fold_vec(node.attrs, f, F::fold_attribute),
+ ident: f.fold_ident(node.ident),
+ fields: f.fold_fields(node.fields),
+ discriminant: (node.discriminant).map(|it| ((it).0, f.fold_expr((it).1))),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_vis_restricted<F>(
+ f: &mut F,
+ node: crate::VisRestricted,
+) -> crate::VisRestricted
+where
+ F: Fold + ?Sized,
+{
+ crate::VisRestricted {
+ pub_token: node.pub_token,
+ paren_token: node.paren_token,
+ in_token: node.in_token,
+ path: Box::new(f.fold_path(*node.path)),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_visibility<F>(f: &mut F, node: crate::Visibility) -> crate::Visibility
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::Visibility::Public(_binding_0) => crate::Visibility::Public(_binding_0),
+ crate::Visibility::Restricted(_binding_0) => {
+ crate::Visibility::Restricted(f.fold_vis_restricted(_binding_0))
+ }
+ crate::Visibility::Inherited => crate::Visibility::Inherited,
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_where_clause<F>(f: &mut F, node: crate::WhereClause) -> crate::WhereClause
+where
+ F: Fold + ?Sized,
+{
+ crate::WhereClause {
+ where_token: node.where_token,
+ predicates: crate::punctuated::fold(node.predicates, f, F::fold_where_predicate),
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn fold_where_predicate<F>(
+ f: &mut F,
+ node: crate::WherePredicate,
+) -> crate::WherePredicate
+where
+ F: Fold + ?Sized,
+{
+ match node {
+ crate::WherePredicate::Lifetime(_binding_0) => {
+ crate::WherePredicate::Lifetime(f.fold_predicate_lifetime(_binding_0))
+ }
+ crate::WherePredicate::Type(_binding_0) => {
+ crate::WherePredicate::Type(f.fold_predicate_type(_binding_0))
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+fn fold_vec<T, V, F>(vec: Vec<T>, fold: &mut V, mut f: F) -> Vec<T>
+where
+ V: ?Sized,
+ F: FnMut(&mut V, T) -> T,
+{
+ vec.into_iter().map(|it| f(fold, it)).collect()
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/gen/hash.rs b/rust/hw/char/pl011/vendor/syn/src/gen/hash.rs
new file mode 100644
index 0000000000..02097b9d6e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/gen/hash.rs
@@ -0,0 +1,2807 @@
+// This file is @generated by syn-internal-codegen.
+// It is not intended for manual editing.
+
+#[cfg(any(feature = "derive", feature = "full"))]
+use crate::tt::TokenStreamHelper;
+use std::hash::{Hash, Hasher};
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Abi {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.name.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::AngleBracketedGenericArguments {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.colon2_token.hash(state);
+ self.args.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Arm {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.pat.hash(state);
+ self.guard.hash(state);
+ self.body.hash(state);
+ self.comma.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::AssocConst {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.value.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::AssocType {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.ty.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::AttrStyle {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::AttrStyle::Outer => {
+ state.write_u8(0u8);
+ }
+ crate::AttrStyle::Inner(_) => {
+ state.write_u8(1u8);
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Attribute {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.style.hash(state);
+ self.meta.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::BareFnArg {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.name.hash(state);
+ self.ty.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::BareVariadic {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.name.hash(state);
+ self.comma.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::BinOp {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::BinOp::Add(_) => {
+ state.write_u8(0u8);
+ }
+ crate::BinOp::Sub(_) => {
+ state.write_u8(1u8);
+ }
+ crate::BinOp::Mul(_) => {
+ state.write_u8(2u8);
+ }
+ crate::BinOp::Div(_) => {
+ state.write_u8(3u8);
+ }
+ crate::BinOp::Rem(_) => {
+ state.write_u8(4u8);
+ }
+ crate::BinOp::And(_) => {
+ state.write_u8(5u8);
+ }
+ crate::BinOp::Or(_) => {
+ state.write_u8(6u8);
+ }
+ crate::BinOp::BitXor(_) => {
+ state.write_u8(7u8);
+ }
+ crate::BinOp::BitAnd(_) => {
+ state.write_u8(8u8);
+ }
+ crate::BinOp::BitOr(_) => {
+ state.write_u8(9u8);
+ }
+ crate::BinOp::Shl(_) => {
+ state.write_u8(10u8);
+ }
+ crate::BinOp::Shr(_) => {
+ state.write_u8(11u8);
+ }
+ crate::BinOp::Eq(_) => {
+ state.write_u8(12u8);
+ }
+ crate::BinOp::Lt(_) => {
+ state.write_u8(13u8);
+ }
+ crate::BinOp::Le(_) => {
+ state.write_u8(14u8);
+ }
+ crate::BinOp::Ne(_) => {
+ state.write_u8(15u8);
+ }
+ crate::BinOp::Ge(_) => {
+ state.write_u8(16u8);
+ }
+ crate::BinOp::Gt(_) => {
+ state.write_u8(17u8);
+ }
+ crate::BinOp::AddAssign(_) => {
+ state.write_u8(18u8);
+ }
+ crate::BinOp::SubAssign(_) => {
+ state.write_u8(19u8);
+ }
+ crate::BinOp::MulAssign(_) => {
+ state.write_u8(20u8);
+ }
+ crate::BinOp::DivAssign(_) => {
+ state.write_u8(21u8);
+ }
+ crate::BinOp::RemAssign(_) => {
+ state.write_u8(22u8);
+ }
+ crate::BinOp::BitXorAssign(_) => {
+ state.write_u8(23u8);
+ }
+ crate::BinOp::BitAndAssign(_) => {
+ state.write_u8(24u8);
+ }
+ crate::BinOp::BitOrAssign(_) => {
+ state.write_u8(25u8);
+ }
+ crate::BinOp::ShlAssign(_) => {
+ state.write_u8(26u8);
+ }
+ crate::BinOp::ShrAssign(_) => {
+ state.write_u8(27u8);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Block {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.stmts.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::BoundLifetimes {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.lifetimes.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ConstParam {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.ident.hash(state);
+ self.ty.hash(state);
+ self.eq_token.hash(state);
+ self.default.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Constraint {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.bounds.hash(state);
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Data {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::Data::Struct(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::Data::Enum(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::Data::Union(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ }
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::DataEnum {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.variants.hash(state);
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::DataStruct {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.fields.hash(state);
+ self.semi_token.hash(state);
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::DataUnion {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.fields.hash(state);
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::DeriveInput {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.data.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Expr {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ #[cfg(feature = "full")]
+ crate::Expr::Array(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Assign(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Async(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Await(v0) => {
+ state.write_u8(3u8);
+ v0.hash(state);
+ }
+ crate::Expr::Binary(v0) => {
+ state.write_u8(4u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Block(v0) => {
+ state.write_u8(5u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Break(v0) => {
+ state.write_u8(6u8);
+ v0.hash(state);
+ }
+ crate::Expr::Call(v0) => {
+ state.write_u8(7u8);
+ v0.hash(state);
+ }
+ crate::Expr::Cast(v0) => {
+ state.write_u8(8u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Closure(v0) => {
+ state.write_u8(9u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Const(v0) => {
+ state.write_u8(10u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Continue(v0) => {
+ state.write_u8(11u8);
+ v0.hash(state);
+ }
+ crate::Expr::Field(v0) => {
+ state.write_u8(12u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::ForLoop(v0) => {
+ state.write_u8(13u8);
+ v0.hash(state);
+ }
+ crate::Expr::Group(v0) => {
+ state.write_u8(14u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::If(v0) => {
+ state.write_u8(15u8);
+ v0.hash(state);
+ }
+ crate::Expr::Index(v0) => {
+ state.write_u8(16u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Infer(v0) => {
+ state.write_u8(17u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Let(v0) => {
+ state.write_u8(18u8);
+ v0.hash(state);
+ }
+ crate::Expr::Lit(v0) => {
+ state.write_u8(19u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Loop(v0) => {
+ state.write_u8(20u8);
+ v0.hash(state);
+ }
+ crate::Expr::Macro(v0) => {
+ state.write_u8(21u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Match(v0) => {
+ state.write_u8(22u8);
+ v0.hash(state);
+ }
+ crate::Expr::MethodCall(v0) => {
+ state.write_u8(23u8);
+ v0.hash(state);
+ }
+ crate::Expr::Paren(v0) => {
+ state.write_u8(24u8);
+ v0.hash(state);
+ }
+ crate::Expr::Path(v0) => {
+ state.write_u8(25u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Range(v0) => {
+ state.write_u8(26u8);
+ v0.hash(state);
+ }
+ crate::Expr::Reference(v0) => {
+ state.write_u8(27u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Repeat(v0) => {
+ state.write_u8(28u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Return(v0) => {
+ state.write_u8(29u8);
+ v0.hash(state);
+ }
+ crate::Expr::Struct(v0) => {
+ state.write_u8(30u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Try(v0) => {
+ state.write_u8(31u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::TryBlock(v0) => {
+ state.write_u8(32u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Tuple(v0) => {
+ state.write_u8(33u8);
+ v0.hash(state);
+ }
+ crate::Expr::Unary(v0) => {
+ state.write_u8(34u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Unsafe(v0) => {
+ state.write_u8(35u8);
+ v0.hash(state);
+ }
+ crate::Expr::Verbatim(v0) => {
+ state.write_u8(36u8);
+ TokenStreamHelper(v0).hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::While(v0) => {
+ state.write_u8(37u8);
+ v0.hash(state);
+ }
+ #[cfg(feature = "full")]
+ crate::Expr::Yield(v0) => {
+ state.write_u8(38u8);
+ v0.hash(state);
+ }
+ #[cfg(not(feature = "full"))]
+ _ => unreachable!(),
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprArray {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.elems.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprAssign {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.left.hash(state);
+ self.right.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprAsync {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.capture.hash(state);
+ self.block.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprAwait {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.base.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprBinary {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.left.hash(state);
+ self.op.hash(state);
+ self.right.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprBlock {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.label.hash(state);
+ self.block.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprBreak {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.label.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprCall {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.func.hash(state);
+ self.args.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprCast {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.expr.hash(state);
+ self.ty.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprClosure {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.lifetimes.hash(state);
+ self.constness.hash(state);
+ self.movability.hash(state);
+ self.asyncness.hash(state);
+ self.capture.hash(state);
+ self.inputs.hash(state);
+ self.output.hash(state);
+ self.body.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprConst {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.block.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprContinue {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.label.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprField {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.base.hash(state);
+ self.member.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprForLoop {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.label.hash(state);
+ self.pat.hash(state);
+ self.expr.hash(state);
+ self.body.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprGroup {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprIf {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.cond.hash(state);
+ self.then_branch.hash(state);
+ self.else_branch.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprIndex {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.expr.hash(state);
+ self.index.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprInfer {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprLet {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.pat.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprLit {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.lit.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprLoop {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.label.hash(state);
+ self.body.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprMacro {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.mac.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprMatch {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.expr.hash(state);
+ self.arms.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprMethodCall {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.receiver.hash(state);
+ self.method.hash(state);
+ self.turbofish.hash(state);
+ self.args.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprParen {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprPath {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.qself.hash(state);
+ self.path.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprRange {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.start.hash(state);
+ self.limits.hash(state);
+ self.end.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprReference {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.mutability.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprRepeat {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.expr.hash(state);
+ self.len.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprReturn {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprStruct {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.qself.hash(state);
+ self.path.hash(state);
+ self.fields.hash(state);
+ self.dot2_token.hash(state);
+ self.rest.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprTry {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprTryBlock {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.block.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprTuple {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.elems.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprUnary {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.op.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprUnsafe {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.block.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprWhile {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.label.hash(state);
+ self.cond.hash(state);
+ self.body.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ExprYield {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Field {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.mutability.hash(state);
+ self.ident.hash(state);
+ self.colon_token.hash(state);
+ self.ty.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::FieldMutability {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::FieldMutability::None => {
+ state.write_u8(0u8);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::FieldPat {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.member.hash(state);
+ self.colon_token.hash(state);
+ self.pat.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::FieldValue {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.member.hash(state);
+ self.colon_token.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Fields {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::Fields::Named(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::Fields::Unnamed(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::Fields::Unit => {
+ state.write_u8(2u8);
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::FieldsNamed {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.named.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::FieldsUnnamed {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.unnamed.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::File {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.shebang.hash(state);
+ self.attrs.hash(state);
+ self.items.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::FnArg {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::FnArg::Receiver(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::FnArg::Typed(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ForeignItem {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::ForeignItem::Fn(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::ForeignItem::Static(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::ForeignItem::Type(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ crate::ForeignItem::Macro(v0) => {
+ state.write_u8(3u8);
+ v0.hash(state);
+ }
+ crate::ForeignItem::Verbatim(v0) => {
+ state.write_u8(4u8);
+ TokenStreamHelper(v0).hash(state);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ForeignItemFn {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.sig.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ForeignItemMacro {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.mac.hash(state);
+ self.semi_token.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ForeignItemStatic {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.mutability.hash(state);
+ self.ident.hash(state);
+ self.ty.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ForeignItemType {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::GenericArgument {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::GenericArgument::Lifetime(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::GenericArgument::Type(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::GenericArgument::Const(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ crate::GenericArgument::AssocType(v0) => {
+ state.write_u8(3u8);
+ v0.hash(state);
+ }
+ crate::GenericArgument::AssocConst(v0) => {
+ state.write_u8(4u8);
+ v0.hash(state);
+ }
+ crate::GenericArgument::Constraint(v0) => {
+ state.write_u8(5u8);
+ v0.hash(state);
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::GenericParam {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::GenericParam::Lifetime(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::GenericParam::Type(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::GenericParam::Const(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Generics {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.lt_token.hash(state);
+ self.params.hash(state);
+ self.gt_token.hash(state);
+ self.where_clause.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ImplItem {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::ImplItem::Const(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::ImplItem::Fn(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::ImplItem::Type(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ crate::ImplItem::Macro(v0) => {
+ state.write_u8(3u8);
+ v0.hash(state);
+ }
+ crate::ImplItem::Verbatim(v0) => {
+ state.write_u8(4u8);
+ TokenStreamHelper(v0).hash(state);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ImplItemConst {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.defaultness.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.ty.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ImplItemFn {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.defaultness.hash(state);
+ self.sig.hash(state);
+ self.block.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ImplItemMacro {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.mac.hash(state);
+ self.semi_token.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ImplItemType {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.defaultness.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.ty.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ImplRestriction {
+ fn hash<H>(&self, _state: &mut H)
+ where
+ H: Hasher,
+ {
+ match *self {}
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Item {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::Item::Const(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::Item::Enum(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::Item::ExternCrate(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ crate::Item::Fn(v0) => {
+ state.write_u8(3u8);
+ v0.hash(state);
+ }
+ crate::Item::ForeignMod(v0) => {
+ state.write_u8(4u8);
+ v0.hash(state);
+ }
+ crate::Item::Impl(v0) => {
+ state.write_u8(5u8);
+ v0.hash(state);
+ }
+ crate::Item::Macro(v0) => {
+ state.write_u8(6u8);
+ v0.hash(state);
+ }
+ crate::Item::Mod(v0) => {
+ state.write_u8(7u8);
+ v0.hash(state);
+ }
+ crate::Item::Static(v0) => {
+ state.write_u8(8u8);
+ v0.hash(state);
+ }
+ crate::Item::Struct(v0) => {
+ state.write_u8(9u8);
+ v0.hash(state);
+ }
+ crate::Item::Trait(v0) => {
+ state.write_u8(10u8);
+ v0.hash(state);
+ }
+ crate::Item::TraitAlias(v0) => {
+ state.write_u8(11u8);
+ v0.hash(state);
+ }
+ crate::Item::Type(v0) => {
+ state.write_u8(12u8);
+ v0.hash(state);
+ }
+ crate::Item::Union(v0) => {
+ state.write_u8(13u8);
+ v0.hash(state);
+ }
+ crate::Item::Use(v0) => {
+ state.write_u8(14u8);
+ v0.hash(state);
+ }
+ crate::Item::Verbatim(v0) => {
+ state.write_u8(15u8);
+ TokenStreamHelper(v0).hash(state);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemConst {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.ty.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemEnum {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.variants.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemExternCrate {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.ident.hash(state);
+ self.rename.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemFn {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.sig.hash(state);
+ self.block.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemForeignMod {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.unsafety.hash(state);
+ self.abi.hash(state);
+ self.items.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemImpl {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.defaultness.hash(state);
+ self.unsafety.hash(state);
+ self.generics.hash(state);
+ self.trait_.hash(state);
+ self.self_ty.hash(state);
+ self.items.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemMacro {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.ident.hash(state);
+ self.mac.hash(state);
+ self.semi_token.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemMod {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.unsafety.hash(state);
+ self.ident.hash(state);
+ self.content.hash(state);
+ self.semi.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemStatic {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.mutability.hash(state);
+ self.ident.hash(state);
+ self.ty.hash(state);
+ self.expr.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemStruct {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.fields.hash(state);
+ self.semi_token.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemTrait {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.unsafety.hash(state);
+ self.auto_token.hash(state);
+ self.restriction.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.colon_token.hash(state);
+ self.supertraits.hash(state);
+ self.items.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemTraitAlias {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.bounds.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemType {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.ty.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemUnion {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.fields.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ItemUse {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.vis.hash(state);
+ self.leading_colon.hash(state);
+ self.tree.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Label {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.name.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::LifetimeParam {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.lifetime.hash(state);
+ self.colon_token.hash(state);
+ self.bounds.hash(state);
+ }
+}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Lit {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::Lit::Str(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::Lit::ByteStr(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::Lit::CStr(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ crate::Lit::Byte(v0) => {
+ state.write_u8(3u8);
+ v0.hash(state);
+ }
+ crate::Lit::Char(v0) => {
+ state.write_u8(4u8);
+ v0.hash(state);
+ }
+ crate::Lit::Int(v0) => {
+ state.write_u8(5u8);
+ v0.hash(state);
+ }
+ crate::Lit::Float(v0) => {
+ state.write_u8(6u8);
+ v0.hash(state);
+ }
+ crate::Lit::Bool(v0) => {
+ state.write_u8(7u8);
+ v0.hash(state);
+ }
+ crate::Lit::Verbatim(v0) => {
+ state.write_u8(8u8);
+ v0.to_string().hash(state);
+ }
+ }
+ }
+}
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::LitBool {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.value.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Local {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.pat.hash(state);
+ self.init.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::LocalInit {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.expr.hash(state);
+ self.diverge.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Macro {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.path.hash(state);
+ self.delimiter.hash(state);
+ TokenStreamHelper(&self.tokens).hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::MacroDelimiter {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::MacroDelimiter::Paren(_) => {
+ state.write_u8(0u8);
+ }
+ crate::MacroDelimiter::Brace(_) => {
+ state.write_u8(1u8);
+ }
+ crate::MacroDelimiter::Bracket(_) => {
+ state.write_u8(2u8);
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Meta {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::Meta::Path(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::Meta::List(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::Meta::NameValue(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::MetaList {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.path.hash(state);
+ self.delimiter.hash(state);
+ TokenStreamHelper(&self.tokens).hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::MetaNameValue {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.path.hash(state);
+ self.value.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ParenthesizedGenericArguments {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.inputs.hash(state);
+ self.output.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Pat {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::Pat::Const(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::Pat::Ident(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::Pat::Lit(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ crate::Pat::Macro(v0) => {
+ state.write_u8(3u8);
+ v0.hash(state);
+ }
+ crate::Pat::Or(v0) => {
+ state.write_u8(4u8);
+ v0.hash(state);
+ }
+ crate::Pat::Paren(v0) => {
+ state.write_u8(5u8);
+ v0.hash(state);
+ }
+ crate::Pat::Path(v0) => {
+ state.write_u8(6u8);
+ v0.hash(state);
+ }
+ crate::Pat::Range(v0) => {
+ state.write_u8(7u8);
+ v0.hash(state);
+ }
+ crate::Pat::Reference(v0) => {
+ state.write_u8(8u8);
+ v0.hash(state);
+ }
+ crate::Pat::Rest(v0) => {
+ state.write_u8(9u8);
+ v0.hash(state);
+ }
+ crate::Pat::Slice(v0) => {
+ state.write_u8(10u8);
+ v0.hash(state);
+ }
+ crate::Pat::Struct(v0) => {
+ state.write_u8(11u8);
+ v0.hash(state);
+ }
+ crate::Pat::Tuple(v0) => {
+ state.write_u8(12u8);
+ v0.hash(state);
+ }
+ crate::Pat::TupleStruct(v0) => {
+ state.write_u8(13u8);
+ v0.hash(state);
+ }
+ crate::Pat::Type(v0) => {
+ state.write_u8(14u8);
+ v0.hash(state);
+ }
+ crate::Pat::Verbatim(v0) => {
+ state.write_u8(15u8);
+ TokenStreamHelper(v0).hash(state);
+ }
+ crate::Pat::Wild(v0) => {
+ state.write_u8(16u8);
+ v0.hash(state);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PatIdent {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.by_ref.hash(state);
+ self.mutability.hash(state);
+ self.ident.hash(state);
+ self.subpat.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PatOr {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.leading_vert.hash(state);
+ self.cases.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PatParen {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.pat.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PatReference {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.mutability.hash(state);
+ self.pat.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PatRest {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PatSlice {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.elems.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PatStruct {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.qself.hash(state);
+ self.path.hash(state);
+ self.fields.hash(state);
+ self.rest.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PatTuple {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.elems.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PatTupleStruct {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.qself.hash(state);
+ self.path.hash(state);
+ self.elems.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PatType {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.pat.hash(state);
+ self.ty.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PatWild {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Path {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.leading_colon.hash(state);
+ self.segments.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PathArguments {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::PathArguments::None => {
+ state.write_u8(0u8);
+ }
+ crate::PathArguments::AngleBracketed(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::PathArguments::Parenthesized(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PathSegment {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.ident.hash(state);
+ self.arguments.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PredicateLifetime {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.lifetime.hash(state);
+ self.bounds.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::PredicateType {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.lifetimes.hash(state);
+ self.bounded_ty.hash(state);
+ self.bounds.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::QSelf {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.ty.hash(state);
+ self.position.hash(state);
+ self.as_token.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::RangeLimits {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::RangeLimits::HalfOpen(_) => {
+ state.write_u8(0u8);
+ }
+ crate::RangeLimits::Closed(_) => {
+ state.write_u8(1u8);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Receiver {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.reference.hash(state);
+ self.mutability.hash(state);
+ self.colon_token.hash(state);
+ self.ty.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::ReturnType {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::ReturnType::Default => {
+ state.write_u8(0u8);
+ }
+ crate::ReturnType::Type(_, v1) => {
+ state.write_u8(1u8);
+ v1.hash(state);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Signature {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.constness.hash(state);
+ self.asyncness.hash(state);
+ self.unsafety.hash(state);
+ self.abi.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.inputs.hash(state);
+ self.variadic.hash(state);
+ self.output.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::StaticMutability {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::StaticMutability::Mut(_) => {
+ state.write_u8(0u8);
+ }
+ crate::StaticMutability::None => {
+ state.write_u8(1u8);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Stmt {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::Stmt::Local(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::Stmt::Item(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::Stmt::Expr(v0, v1) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ v1.hash(state);
+ }
+ crate::Stmt::Macro(v0) => {
+ state.write_u8(3u8);
+ v0.hash(state);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::StmtMacro {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.mac.hash(state);
+ self.semi_token.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TraitBound {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.paren_token.hash(state);
+ self.modifier.hash(state);
+ self.lifetimes.hash(state);
+ self.path.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TraitBoundModifier {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::TraitBoundModifier::None => {
+ state.write_u8(0u8);
+ }
+ crate::TraitBoundModifier::Maybe(_) => {
+ state.write_u8(1u8);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TraitItem {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::TraitItem::Const(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::TraitItem::Fn(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::TraitItem::Type(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ crate::TraitItem::Macro(v0) => {
+ state.write_u8(3u8);
+ v0.hash(state);
+ }
+ crate::TraitItem::Verbatim(v0) => {
+ state.write_u8(4u8);
+ TokenStreamHelper(v0).hash(state);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TraitItemConst {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.ty.hash(state);
+ self.default.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TraitItemFn {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.sig.hash(state);
+ self.default.hash(state);
+ self.semi_token.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TraitItemMacro {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.mac.hash(state);
+ self.semi_token.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TraitItemType {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.ident.hash(state);
+ self.generics.hash(state);
+ self.colon_token.hash(state);
+ self.bounds.hash(state);
+ self.default.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Type {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::Type::Array(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::Type::BareFn(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::Type::Group(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ crate::Type::ImplTrait(v0) => {
+ state.write_u8(3u8);
+ v0.hash(state);
+ }
+ crate::Type::Infer(v0) => {
+ state.write_u8(4u8);
+ v0.hash(state);
+ }
+ crate::Type::Macro(v0) => {
+ state.write_u8(5u8);
+ v0.hash(state);
+ }
+ crate::Type::Never(v0) => {
+ state.write_u8(6u8);
+ v0.hash(state);
+ }
+ crate::Type::Paren(v0) => {
+ state.write_u8(7u8);
+ v0.hash(state);
+ }
+ crate::Type::Path(v0) => {
+ state.write_u8(8u8);
+ v0.hash(state);
+ }
+ crate::Type::Ptr(v0) => {
+ state.write_u8(9u8);
+ v0.hash(state);
+ }
+ crate::Type::Reference(v0) => {
+ state.write_u8(10u8);
+ v0.hash(state);
+ }
+ crate::Type::Slice(v0) => {
+ state.write_u8(11u8);
+ v0.hash(state);
+ }
+ crate::Type::TraitObject(v0) => {
+ state.write_u8(12u8);
+ v0.hash(state);
+ }
+ crate::Type::Tuple(v0) => {
+ state.write_u8(13u8);
+ v0.hash(state);
+ }
+ crate::Type::Verbatim(v0) => {
+ state.write_u8(14u8);
+ TokenStreamHelper(v0).hash(state);
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeArray {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.elem.hash(state);
+ self.len.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeBareFn {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.lifetimes.hash(state);
+ self.unsafety.hash(state);
+ self.abi.hash(state);
+ self.inputs.hash(state);
+ self.variadic.hash(state);
+ self.output.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeGroup {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.elem.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeImplTrait {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.bounds.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeInfer {
+ fn hash<H>(&self, _state: &mut H)
+ where
+ H: Hasher,
+ {}
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeMacro {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.mac.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeNever {
+ fn hash<H>(&self, _state: &mut H)
+ where
+ H: Hasher,
+ {}
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeParam {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.ident.hash(state);
+ self.colon_token.hash(state);
+ self.bounds.hash(state);
+ self.eq_token.hash(state);
+ self.default.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeParamBound {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::TypeParamBound::Trait(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::TypeParamBound::Lifetime(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::TypeParamBound::Verbatim(v0) => {
+ state.write_u8(2u8);
+ TokenStreamHelper(v0).hash(state);
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeParen {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.elem.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypePath {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.qself.hash(state);
+ self.path.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypePtr {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.const_token.hash(state);
+ self.mutability.hash(state);
+ self.elem.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeReference {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.lifetime.hash(state);
+ self.mutability.hash(state);
+ self.elem.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeSlice {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.elem.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeTraitObject {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.dyn_token.hash(state);
+ self.bounds.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::TypeTuple {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.elems.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::UnOp {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::UnOp::Deref(_) => {
+ state.write_u8(0u8);
+ }
+ crate::UnOp::Not(_) => {
+ state.write_u8(1u8);
+ }
+ crate::UnOp::Neg(_) => {
+ state.write_u8(2u8);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::UseGlob {
+ fn hash<H>(&self, _state: &mut H)
+ where
+ H: Hasher,
+ {}
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::UseGroup {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.items.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::UseName {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.ident.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::UsePath {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.ident.hash(state);
+ self.tree.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::UseRename {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.ident.hash(state);
+ self.rename.hash(state);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::UseTree {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::UseTree::Path(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::UseTree::Name(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::UseTree::Rename(v0) => {
+ state.write_u8(2u8);
+ v0.hash(state);
+ }
+ crate::UseTree::Glob(v0) => {
+ state.write_u8(3u8);
+ v0.hash(state);
+ }
+ crate::UseTree::Group(v0) => {
+ state.write_u8(4u8);
+ v0.hash(state);
+ }
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Variadic {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.pat.hash(state);
+ self.comma.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Variant {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.attrs.hash(state);
+ self.ident.hash(state);
+ self.fields.hash(state);
+ self.discriminant.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::VisRestricted {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.in_token.hash(state);
+ self.path.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::Visibility {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::Visibility::Public(_) => {
+ state.write_u8(0u8);
+ }
+ crate::Visibility::Restricted(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ crate::Visibility::Inherited => {
+ state.write_u8(2u8);
+ }
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::WhereClause {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.predicates.hash(state);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for crate::WherePredicate {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ match self {
+ crate::WherePredicate::Lifetime(v0) => {
+ state.write_u8(0u8);
+ v0.hash(state);
+ }
+ crate::WherePredicate::Type(v0) => {
+ state.write_u8(1u8);
+ v0.hash(state);
+ }
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/gen/visit.rs b/rust/hw/char/pl011/vendor/syn/src/gen/visit.rs
new file mode 100644
index 0000000000..b61997f177
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/gen/visit.rs
@@ -0,0 +1,3858 @@
+// This file is @generated by syn-internal-codegen.
+// It is not intended for manual editing.
+
+#![allow(unused_variables)]
+#![allow(clippy::needless_pass_by_ref_mut)]
+#[cfg(any(feature = "full", feature = "derive"))]
+use crate::punctuated::Punctuated;
+#[cfg(feature = "full")]
+macro_rules! full {
+ ($e:expr) => {
+ $e
+ };
+}
+#[cfg(all(feature = "derive", not(feature = "full")))]
+macro_rules! full {
+ ($e:expr) => {
+ unreachable!()
+ };
+}
+macro_rules! skip {
+ ($($tt:tt)*) => {};
+}
+/// Syntax tree traversal to walk a shared borrow of a syntax tree.
+///
+/// See the [module documentation] for details.
+///
+/// [module documentation]: self
+pub trait Visit<'ast> {
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_abi(&mut self, i: &'ast crate::Abi) {
+ visit_abi(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_angle_bracketed_generic_arguments(
+ &mut self,
+ i: &'ast crate::AngleBracketedGenericArguments,
+ ) {
+ visit_angle_bracketed_generic_arguments(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_arm(&mut self, i: &'ast crate::Arm) {
+ visit_arm(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_assoc_const(&mut self, i: &'ast crate::AssocConst) {
+ visit_assoc_const(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_assoc_type(&mut self, i: &'ast crate::AssocType) {
+ visit_assoc_type(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_attr_style(&mut self, i: &'ast crate::AttrStyle) {
+ visit_attr_style(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_attribute(&mut self, i: &'ast crate::Attribute) {
+ visit_attribute(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_bare_fn_arg(&mut self, i: &'ast crate::BareFnArg) {
+ visit_bare_fn_arg(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_bare_variadic(&mut self, i: &'ast crate::BareVariadic) {
+ visit_bare_variadic(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_bin_op(&mut self, i: &'ast crate::BinOp) {
+ visit_bin_op(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_block(&mut self, i: &'ast crate::Block) {
+ visit_block(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_bound_lifetimes(&mut self, i: &'ast crate::BoundLifetimes) {
+ visit_bound_lifetimes(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_const_param(&mut self, i: &'ast crate::ConstParam) {
+ visit_const_param(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_constraint(&mut self, i: &'ast crate::Constraint) {
+ visit_constraint(self, i);
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn visit_data(&mut self, i: &'ast crate::Data) {
+ visit_data(self, i);
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn visit_data_enum(&mut self, i: &'ast crate::DataEnum) {
+ visit_data_enum(self, i);
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn visit_data_struct(&mut self, i: &'ast crate::DataStruct) {
+ visit_data_struct(self, i);
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn visit_data_union(&mut self, i: &'ast crate::DataUnion) {
+ visit_data_union(self, i);
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn visit_derive_input(&mut self, i: &'ast crate::DeriveInput) {
+ visit_derive_input(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr(&mut self, i: &'ast crate::Expr) {
+ visit_expr(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_array(&mut self, i: &'ast crate::ExprArray) {
+ visit_expr_array(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_assign(&mut self, i: &'ast crate::ExprAssign) {
+ visit_expr_assign(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_async(&mut self, i: &'ast crate::ExprAsync) {
+ visit_expr_async(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_await(&mut self, i: &'ast crate::ExprAwait) {
+ visit_expr_await(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_binary(&mut self, i: &'ast crate::ExprBinary) {
+ visit_expr_binary(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_block(&mut self, i: &'ast crate::ExprBlock) {
+ visit_expr_block(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_break(&mut self, i: &'ast crate::ExprBreak) {
+ visit_expr_break(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_call(&mut self, i: &'ast crate::ExprCall) {
+ visit_expr_call(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_cast(&mut self, i: &'ast crate::ExprCast) {
+ visit_expr_cast(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_closure(&mut self, i: &'ast crate::ExprClosure) {
+ visit_expr_closure(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_const(&mut self, i: &'ast crate::ExprConst) {
+ visit_expr_const(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_continue(&mut self, i: &'ast crate::ExprContinue) {
+ visit_expr_continue(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_field(&mut self, i: &'ast crate::ExprField) {
+ visit_expr_field(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_for_loop(&mut self, i: &'ast crate::ExprForLoop) {
+ visit_expr_for_loop(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_group(&mut self, i: &'ast crate::ExprGroup) {
+ visit_expr_group(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_if(&mut self, i: &'ast crate::ExprIf) {
+ visit_expr_if(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_index(&mut self, i: &'ast crate::ExprIndex) {
+ visit_expr_index(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_infer(&mut self, i: &'ast crate::ExprInfer) {
+ visit_expr_infer(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_let(&mut self, i: &'ast crate::ExprLet) {
+ visit_expr_let(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_lit(&mut self, i: &'ast crate::ExprLit) {
+ visit_expr_lit(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_loop(&mut self, i: &'ast crate::ExprLoop) {
+ visit_expr_loop(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_macro(&mut self, i: &'ast crate::ExprMacro) {
+ visit_expr_macro(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_match(&mut self, i: &'ast crate::ExprMatch) {
+ visit_expr_match(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_method_call(&mut self, i: &'ast crate::ExprMethodCall) {
+ visit_expr_method_call(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_paren(&mut self, i: &'ast crate::ExprParen) {
+ visit_expr_paren(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_path(&mut self, i: &'ast crate::ExprPath) {
+ visit_expr_path(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_range(&mut self, i: &'ast crate::ExprRange) {
+ visit_expr_range(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_reference(&mut self, i: &'ast crate::ExprReference) {
+ visit_expr_reference(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_repeat(&mut self, i: &'ast crate::ExprRepeat) {
+ visit_expr_repeat(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_return(&mut self, i: &'ast crate::ExprReturn) {
+ visit_expr_return(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_struct(&mut self, i: &'ast crate::ExprStruct) {
+ visit_expr_struct(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_try(&mut self, i: &'ast crate::ExprTry) {
+ visit_expr_try(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_try_block(&mut self, i: &'ast crate::ExprTryBlock) {
+ visit_expr_try_block(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_tuple(&mut self, i: &'ast crate::ExprTuple) {
+ visit_expr_tuple(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_unary(&mut self, i: &'ast crate::ExprUnary) {
+ visit_expr_unary(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_unsafe(&mut self, i: &'ast crate::ExprUnsafe) {
+ visit_expr_unsafe(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_while(&mut self, i: &'ast crate::ExprWhile) {
+ visit_expr_while(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_yield(&mut self, i: &'ast crate::ExprYield) {
+ visit_expr_yield(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_field(&mut self, i: &'ast crate::Field) {
+ visit_field(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_field_mutability(&mut self, i: &'ast crate::FieldMutability) {
+ visit_field_mutability(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_field_pat(&mut self, i: &'ast crate::FieldPat) {
+ visit_field_pat(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_field_value(&mut self, i: &'ast crate::FieldValue) {
+ visit_field_value(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_fields(&mut self, i: &'ast crate::Fields) {
+ visit_fields(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_fields_named(&mut self, i: &'ast crate::FieldsNamed) {
+ visit_fields_named(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_fields_unnamed(&mut self, i: &'ast crate::FieldsUnnamed) {
+ visit_fields_unnamed(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_file(&mut self, i: &'ast crate::File) {
+ visit_file(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_fn_arg(&mut self, i: &'ast crate::FnArg) {
+ visit_fn_arg(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_foreign_item(&mut self, i: &'ast crate::ForeignItem) {
+ visit_foreign_item(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_foreign_item_fn(&mut self, i: &'ast crate::ForeignItemFn) {
+ visit_foreign_item_fn(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_foreign_item_macro(&mut self, i: &'ast crate::ForeignItemMacro) {
+ visit_foreign_item_macro(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_foreign_item_static(&mut self, i: &'ast crate::ForeignItemStatic) {
+ visit_foreign_item_static(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_foreign_item_type(&mut self, i: &'ast crate::ForeignItemType) {
+ visit_foreign_item_type(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_generic_argument(&mut self, i: &'ast crate::GenericArgument) {
+ visit_generic_argument(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_generic_param(&mut self, i: &'ast crate::GenericParam) {
+ visit_generic_param(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_generics(&mut self, i: &'ast crate::Generics) {
+ visit_generics(self, i);
+ }
+ fn visit_ident(&mut self, i: &'ast proc_macro2::Ident) {
+ visit_ident(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_impl_item(&mut self, i: &'ast crate::ImplItem) {
+ visit_impl_item(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_impl_item_const(&mut self, i: &'ast crate::ImplItemConst) {
+ visit_impl_item_const(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_impl_item_fn(&mut self, i: &'ast crate::ImplItemFn) {
+ visit_impl_item_fn(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_impl_item_macro(&mut self, i: &'ast crate::ImplItemMacro) {
+ visit_impl_item_macro(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_impl_item_type(&mut self, i: &'ast crate::ImplItemType) {
+ visit_impl_item_type(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_impl_restriction(&mut self, i: &'ast crate::ImplRestriction) {
+ visit_impl_restriction(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_index(&mut self, i: &'ast crate::Index) {
+ visit_index(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item(&mut self, i: &'ast crate::Item) {
+ visit_item(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_const(&mut self, i: &'ast crate::ItemConst) {
+ visit_item_const(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_enum(&mut self, i: &'ast crate::ItemEnum) {
+ visit_item_enum(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_extern_crate(&mut self, i: &'ast crate::ItemExternCrate) {
+ visit_item_extern_crate(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_fn(&mut self, i: &'ast crate::ItemFn) {
+ visit_item_fn(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_foreign_mod(&mut self, i: &'ast crate::ItemForeignMod) {
+ visit_item_foreign_mod(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_impl(&mut self, i: &'ast crate::ItemImpl) {
+ visit_item_impl(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_macro(&mut self, i: &'ast crate::ItemMacro) {
+ visit_item_macro(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_mod(&mut self, i: &'ast crate::ItemMod) {
+ visit_item_mod(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_static(&mut self, i: &'ast crate::ItemStatic) {
+ visit_item_static(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_struct(&mut self, i: &'ast crate::ItemStruct) {
+ visit_item_struct(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_trait(&mut self, i: &'ast crate::ItemTrait) {
+ visit_item_trait(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_trait_alias(&mut self, i: &'ast crate::ItemTraitAlias) {
+ visit_item_trait_alias(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_type(&mut self, i: &'ast crate::ItemType) {
+ visit_item_type(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_union(&mut self, i: &'ast crate::ItemUnion) {
+ visit_item_union(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_use(&mut self, i: &'ast crate::ItemUse) {
+ visit_item_use(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_label(&mut self, i: &'ast crate::Label) {
+ visit_label(self, i);
+ }
+ fn visit_lifetime(&mut self, i: &'ast crate::Lifetime) {
+ visit_lifetime(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_lifetime_param(&mut self, i: &'ast crate::LifetimeParam) {
+ visit_lifetime_param(self, i);
+ }
+ fn visit_lit(&mut self, i: &'ast crate::Lit) {
+ visit_lit(self, i);
+ }
+ fn visit_lit_bool(&mut self, i: &'ast crate::LitBool) {
+ visit_lit_bool(self, i);
+ }
+ fn visit_lit_byte(&mut self, i: &'ast crate::LitByte) {
+ visit_lit_byte(self, i);
+ }
+ fn visit_lit_byte_str(&mut self, i: &'ast crate::LitByteStr) {
+ visit_lit_byte_str(self, i);
+ }
+ fn visit_lit_cstr(&mut self, i: &'ast crate::LitCStr) {
+ visit_lit_cstr(self, i);
+ }
+ fn visit_lit_char(&mut self, i: &'ast crate::LitChar) {
+ visit_lit_char(self, i);
+ }
+ fn visit_lit_float(&mut self, i: &'ast crate::LitFloat) {
+ visit_lit_float(self, i);
+ }
+ fn visit_lit_int(&mut self, i: &'ast crate::LitInt) {
+ visit_lit_int(self, i);
+ }
+ fn visit_lit_str(&mut self, i: &'ast crate::LitStr) {
+ visit_lit_str(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_local(&mut self, i: &'ast crate::Local) {
+ visit_local(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_local_init(&mut self, i: &'ast crate::LocalInit) {
+ visit_local_init(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_macro(&mut self, i: &'ast crate::Macro) {
+ visit_macro(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_macro_delimiter(&mut self, i: &'ast crate::MacroDelimiter) {
+ visit_macro_delimiter(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_member(&mut self, i: &'ast crate::Member) {
+ visit_member(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_meta(&mut self, i: &'ast crate::Meta) {
+ visit_meta(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_meta_list(&mut self, i: &'ast crate::MetaList) {
+ visit_meta_list(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_meta_name_value(&mut self, i: &'ast crate::MetaNameValue) {
+ visit_meta_name_value(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_parenthesized_generic_arguments(
+ &mut self,
+ i: &'ast crate::ParenthesizedGenericArguments,
+ ) {
+ visit_parenthesized_generic_arguments(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat(&mut self, i: &'ast crate::Pat) {
+ visit_pat(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_ident(&mut self, i: &'ast crate::PatIdent) {
+ visit_pat_ident(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_or(&mut self, i: &'ast crate::PatOr) {
+ visit_pat_or(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_paren(&mut self, i: &'ast crate::PatParen) {
+ visit_pat_paren(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_reference(&mut self, i: &'ast crate::PatReference) {
+ visit_pat_reference(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_rest(&mut self, i: &'ast crate::PatRest) {
+ visit_pat_rest(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_slice(&mut self, i: &'ast crate::PatSlice) {
+ visit_pat_slice(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_struct(&mut self, i: &'ast crate::PatStruct) {
+ visit_pat_struct(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_tuple(&mut self, i: &'ast crate::PatTuple) {
+ visit_pat_tuple(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_tuple_struct(&mut self, i: &'ast crate::PatTupleStruct) {
+ visit_pat_tuple_struct(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_type(&mut self, i: &'ast crate::PatType) {
+ visit_pat_type(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_wild(&mut self, i: &'ast crate::PatWild) {
+ visit_pat_wild(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_path(&mut self, i: &'ast crate::Path) {
+ visit_path(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_path_arguments(&mut self, i: &'ast crate::PathArguments) {
+ visit_path_arguments(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_path_segment(&mut self, i: &'ast crate::PathSegment) {
+ visit_path_segment(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_predicate_lifetime(&mut self, i: &'ast crate::PredicateLifetime) {
+ visit_predicate_lifetime(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_predicate_type(&mut self, i: &'ast crate::PredicateType) {
+ visit_predicate_type(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_qself(&mut self, i: &'ast crate::QSelf) {
+ visit_qself(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_range_limits(&mut self, i: &'ast crate::RangeLimits) {
+ visit_range_limits(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_receiver(&mut self, i: &'ast crate::Receiver) {
+ visit_receiver(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_return_type(&mut self, i: &'ast crate::ReturnType) {
+ visit_return_type(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_signature(&mut self, i: &'ast crate::Signature) {
+ visit_signature(self, i);
+ }
+ fn visit_span(&mut self, i: &proc_macro2::Span) {
+ visit_span(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_static_mutability(&mut self, i: &'ast crate::StaticMutability) {
+ visit_static_mutability(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_stmt(&mut self, i: &'ast crate::Stmt) {
+ visit_stmt(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_stmt_macro(&mut self, i: &'ast crate::StmtMacro) {
+ visit_stmt_macro(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_trait_bound(&mut self, i: &'ast crate::TraitBound) {
+ visit_trait_bound(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_trait_bound_modifier(&mut self, i: &'ast crate::TraitBoundModifier) {
+ visit_trait_bound_modifier(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_trait_item(&mut self, i: &'ast crate::TraitItem) {
+ visit_trait_item(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_trait_item_const(&mut self, i: &'ast crate::TraitItemConst) {
+ visit_trait_item_const(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_trait_item_fn(&mut self, i: &'ast crate::TraitItemFn) {
+ visit_trait_item_fn(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_trait_item_macro(&mut self, i: &'ast crate::TraitItemMacro) {
+ visit_trait_item_macro(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_trait_item_type(&mut self, i: &'ast crate::TraitItemType) {
+ visit_trait_item_type(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type(&mut self, i: &'ast crate::Type) {
+ visit_type(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_array(&mut self, i: &'ast crate::TypeArray) {
+ visit_type_array(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_bare_fn(&mut self, i: &'ast crate::TypeBareFn) {
+ visit_type_bare_fn(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_group(&mut self, i: &'ast crate::TypeGroup) {
+ visit_type_group(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_impl_trait(&mut self, i: &'ast crate::TypeImplTrait) {
+ visit_type_impl_trait(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_infer(&mut self, i: &'ast crate::TypeInfer) {
+ visit_type_infer(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_macro(&mut self, i: &'ast crate::TypeMacro) {
+ visit_type_macro(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_never(&mut self, i: &'ast crate::TypeNever) {
+ visit_type_never(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_param(&mut self, i: &'ast crate::TypeParam) {
+ visit_type_param(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_param_bound(&mut self, i: &'ast crate::TypeParamBound) {
+ visit_type_param_bound(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_paren(&mut self, i: &'ast crate::TypeParen) {
+ visit_type_paren(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_path(&mut self, i: &'ast crate::TypePath) {
+ visit_type_path(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_ptr(&mut self, i: &'ast crate::TypePtr) {
+ visit_type_ptr(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_reference(&mut self, i: &'ast crate::TypeReference) {
+ visit_type_reference(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_slice(&mut self, i: &'ast crate::TypeSlice) {
+ visit_type_slice(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_trait_object(&mut self, i: &'ast crate::TypeTraitObject) {
+ visit_type_trait_object(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_tuple(&mut self, i: &'ast crate::TypeTuple) {
+ visit_type_tuple(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_un_op(&mut self, i: &'ast crate::UnOp) {
+ visit_un_op(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_use_glob(&mut self, i: &'ast crate::UseGlob) {
+ visit_use_glob(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_use_group(&mut self, i: &'ast crate::UseGroup) {
+ visit_use_group(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_use_name(&mut self, i: &'ast crate::UseName) {
+ visit_use_name(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_use_path(&mut self, i: &'ast crate::UsePath) {
+ visit_use_path(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_use_rename(&mut self, i: &'ast crate::UseRename) {
+ visit_use_rename(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_use_tree(&mut self, i: &'ast crate::UseTree) {
+ visit_use_tree(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_variadic(&mut self, i: &'ast crate::Variadic) {
+ visit_variadic(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_variant(&mut self, i: &'ast crate::Variant) {
+ visit_variant(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_vis_restricted(&mut self, i: &'ast crate::VisRestricted) {
+ visit_vis_restricted(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_visibility(&mut self, i: &'ast crate::Visibility) {
+ visit_visibility(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_where_clause(&mut self, i: &'ast crate::WhereClause) {
+ visit_where_clause(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_where_predicate(&mut self, i: &'ast crate::WherePredicate) {
+ visit_where_predicate(self, i);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_abi<'ast, V>(v: &mut V, node: &'ast crate::Abi)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.extern_token);
+ if let Some(it) = &node.name {
+ v.visit_lit_str(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_angle_bracketed_generic_arguments<'ast, V>(
+ v: &mut V,
+ node: &'ast crate::AngleBracketedGenericArguments,
+)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.colon2_token);
+ skip!(node.lt_token);
+ for el in Punctuated::pairs(&node.args) {
+ let it = el.value();
+ v.visit_generic_argument(it);
+ }
+ skip!(node.gt_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_arm<'ast, V>(v: &mut V, node: &'ast crate::Arm)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_pat(&node.pat);
+ if let Some(it) = &node.guard {
+ skip!((it).0);
+ v.visit_expr(&*(it).1);
+ }
+ skip!(node.fat_arrow_token);
+ v.visit_expr(&*node.body);
+ skip!(node.comma);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_assoc_const<'ast, V>(v: &mut V, node: &'ast crate::AssocConst)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_ident(&node.ident);
+ if let Some(it) = &node.generics {
+ v.visit_angle_bracketed_generic_arguments(it);
+ }
+ skip!(node.eq_token);
+ v.visit_expr(&node.value);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_assoc_type<'ast, V>(v: &mut V, node: &'ast crate::AssocType)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_ident(&node.ident);
+ if let Some(it) = &node.generics {
+ v.visit_angle_bracketed_generic_arguments(it);
+ }
+ skip!(node.eq_token);
+ v.visit_type(&node.ty);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_attr_style<'ast, V>(v: &mut V, node: &'ast crate::AttrStyle)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::AttrStyle::Outer => {}
+ crate::AttrStyle::Inner(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_attribute<'ast, V>(v: &mut V, node: &'ast crate::Attribute)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.pound_token);
+ v.visit_attr_style(&node.style);
+ skip!(node.bracket_token);
+ v.visit_meta(&node.meta);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_bare_fn_arg<'ast, V>(v: &mut V, node: &'ast crate::BareFnArg)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.name {
+ v.visit_ident(&(it).0);
+ skip!((it).1);
+ }
+ v.visit_type(&node.ty);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_bare_variadic<'ast, V>(v: &mut V, node: &'ast crate::BareVariadic)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.name {
+ v.visit_ident(&(it).0);
+ skip!((it).1);
+ }
+ skip!(node.dots);
+ skip!(node.comma);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_bin_op<'ast, V>(v: &mut V, node: &'ast crate::BinOp)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::BinOp::Add(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Sub(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Mul(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Div(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Rem(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::And(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Or(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::BitXor(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::BitAnd(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::BitOr(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Shl(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Shr(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Eq(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Lt(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Le(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Ne(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Ge(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Gt(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::AddAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::SubAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::MulAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::DivAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::RemAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::BitXorAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::BitAndAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::BitOrAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::ShlAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::ShrAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_block<'ast, V>(v: &mut V, node: &'ast crate::Block)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.brace_token);
+ for it in &node.stmts {
+ v.visit_stmt(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_bound_lifetimes<'ast, V>(v: &mut V, node: &'ast crate::BoundLifetimes)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.for_token);
+ skip!(node.lt_token);
+ for el in Punctuated::pairs(&node.lifetimes) {
+ let it = el.value();
+ v.visit_generic_param(it);
+ }
+ skip!(node.gt_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_const_param<'ast, V>(v: &mut V, node: &'ast crate::ConstParam)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.const_token);
+ v.visit_ident(&node.ident);
+ skip!(node.colon_token);
+ v.visit_type(&node.ty);
+ skip!(node.eq_token);
+ if let Some(it) = &node.default {
+ v.visit_expr(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_constraint<'ast, V>(v: &mut V, node: &'ast crate::Constraint)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_ident(&node.ident);
+ if let Some(it) = &node.generics {
+ v.visit_angle_bracketed_generic_arguments(it);
+ }
+ skip!(node.colon_token);
+ for el in Punctuated::pairs(&node.bounds) {
+ let it = el.value();
+ v.visit_type_param_bound(it);
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn visit_data<'ast, V>(v: &mut V, node: &'ast crate::Data)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::Data::Struct(_binding_0) => {
+ v.visit_data_struct(_binding_0);
+ }
+ crate::Data::Enum(_binding_0) => {
+ v.visit_data_enum(_binding_0);
+ }
+ crate::Data::Union(_binding_0) => {
+ v.visit_data_union(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn visit_data_enum<'ast, V>(v: &mut V, node: &'ast crate::DataEnum)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.enum_token);
+ skip!(node.brace_token);
+ for el in Punctuated::pairs(&node.variants) {
+ let it = el.value();
+ v.visit_variant(it);
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn visit_data_struct<'ast, V>(v: &mut V, node: &'ast crate::DataStruct)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.struct_token);
+ v.visit_fields(&node.fields);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn visit_data_union<'ast, V>(v: &mut V, node: &'ast crate::DataUnion)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.union_token);
+ v.visit_fields_named(&node.fields);
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn visit_derive_input<'ast, V>(v: &mut V, node: &'ast crate::DeriveInput)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ v.visit_data(&node.data);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr<'ast, V>(v: &mut V, node: &'ast crate::Expr)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::Expr::Array(_binding_0) => {
+ full!(v.visit_expr_array(_binding_0));
+ }
+ crate::Expr::Assign(_binding_0) => {
+ full!(v.visit_expr_assign(_binding_0));
+ }
+ crate::Expr::Async(_binding_0) => {
+ full!(v.visit_expr_async(_binding_0));
+ }
+ crate::Expr::Await(_binding_0) => {
+ full!(v.visit_expr_await(_binding_0));
+ }
+ crate::Expr::Binary(_binding_0) => {
+ v.visit_expr_binary(_binding_0);
+ }
+ crate::Expr::Block(_binding_0) => {
+ full!(v.visit_expr_block(_binding_0));
+ }
+ crate::Expr::Break(_binding_0) => {
+ full!(v.visit_expr_break(_binding_0));
+ }
+ crate::Expr::Call(_binding_0) => {
+ v.visit_expr_call(_binding_0);
+ }
+ crate::Expr::Cast(_binding_0) => {
+ v.visit_expr_cast(_binding_0);
+ }
+ crate::Expr::Closure(_binding_0) => {
+ full!(v.visit_expr_closure(_binding_0));
+ }
+ crate::Expr::Const(_binding_0) => {
+ full!(v.visit_expr_const(_binding_0));
+ }
+ crate::Expr::Continue(_binding_0) => {
+ full!(v.visit_expr_continue(_binding_0));
+ }
+ crate::Expr::Field(_binding_0) => {
+ v.visit_expr_field(_binding_0);
+ }
+ crate::Expr::ForLoop(_binding_0) => {
+ full!(v.visit_expr_for_loop(_binding_0));
+ }
+ crate::Expr::Group(_binding_0) => {
+ v.visit_expr_group(_binding_0);
+ }
+ crate::Expr::If(_binding_0) => {
+ full!(v.visit_expr_if(_binding_0));
+ }
+ crate::Expr::Index(_binding_0) => {
+ v.visit_expr_index(_binding_0);
+ }
+ crate::Expr::Infer(_binding_0) => {
+ full!(v.visit_expr_infer(_binding_0));
+ }
+ crate::Expr::Let(_binding_0) => {
+ full!(v.visit_expr_let(_binding_0));
+ }
+ crate::Expr::Lit(_binding_0) => {
+ v.visit_expr_lit(_binding_0);
+ }
+ crate::Expr::Loop(_binding_0) => {
+ full!(v.visit_expr_loop(_binding_0));
+ }
+ crate::Expr::Macro(_binding_0) => {
+ v.visit_expr_macro(_binding_0);
+ }
+ crate::Expr::Match(_binding_0) => {
+ full!(v.visit_expr_match(_binding_0));
+ }
+ crate::Expr::MethodCall(_binding_0) => {
+ v.visit_expr_method_call(_binding_0);
+ }
+ crate::Expr::Paren(_binding_0) => {
+ v.visit_expr_paren(_binding_0);
+ }
+ crate::Expr::Path(_binding_0) => {
+ v.visit_expr_path(_binding_0);
+ }
+ crate::Expr::Range(_binding_0) => {
+ full!(v.visit_expr_range(_binding_0));
+ }
+ crate::Expr::Reference(_binding_0) => {
+ v.visit_expr_reference(_binding_0);
+ }
+ crate::Expr::Repeat(_binding_0) => {
+ full!(v.visit_expr_repeat(_binding_0));
+ }
+ crate::Expr::Return(_binding_0) => {
+ full!(v.visit_expr_return(_binding_0));
+ }
+ crate::Expr::Struct(_binding_0) => {
+ v.visit_expr_struct(_binding_0);
+ }
+ crate::Expr::Try(_binding_0) => {
+ full!(v.visit_expr_try(_binding_0));
+ }
+ crate::Expr::TryBlock(_binding_0) => {
+ full!(v.visit_expr_try_block(_binding_0));
+ }
+ crate::Expr::Tuple(_binding_0) => {
+ full!(v.visit_expr_tuple(_binding_0));
+ }
+ crate::Expr::Unary(_binding_0) => {
+ v.visit_expr_unary(_binding_0);
+ }
+ crate::Expr::Unsafe(_binding_0) => {
+ full!(v.visit_expr_unsafe(_binding_0));
+ }
+ crate::Expr::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::Expr::While(_binding_0) => {
+ full!(v.visit_expr_while(_binding_0));
+ }
+ crate::Expr::Yield(_binding_0) => {
+ full!(v.visit_expr_yield(_binding_0));
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_array<'ast, V>(v: &mut V, node: &'ast crate::ExprArray)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.bracket_token);
+ for el in Punctuated::pairs(&node.elems) {
+ let it = el.value();
+ v.visit_expr(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_assign<'ast, V>(v: &mut V, node: &'ast crate::ExprAssign)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_expr(&*node.left);
+ skip!(node.eq_token);
+ v.visit_expr(&*node.right);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_async<'ast, V>(v: &mut V, node: &'ast crate::ExprAsync)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.async_token);
+ skip!(node.capture);
+ v.visit_block(&node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_await<'ast, V>(v: &mut V, node: &'ast crate::ExprAwait)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_expr(&*node.base);
+ skip!(node.dot_token);
+ skip!(node.await_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_binary<'ast, V>(v: &mut V, node: &'ast crate::ExprBinary)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_expr(&*node.left);
+ v.visit_bin_op(&node.op);
+ v.visit_expr(&*node.right);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_block<'ast, V>(v: &mut V, node: &'ast crate::ExprBlock)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.label {
+ v.visit_label(it);
+ }
+ v.visit_block(&node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_break<'ast, V>(v: &mut V, node: &'ast crate::ExprBreak)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.break_token);
+ if let Some(it) = &node.label {
+ v.visit_lifetime(it);
+ }
+ if let Some(it) = &node.expr {
+ v.visit_expr(&**it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_call<'ast, V>(v: &mut V, node: &'ast crate::ExprCall)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_expr(&*node.func);
+ skip!(node.paren_token);
+ for el in Punctuated::pairs(&node.args) {
+ let it = el.value();
+ v.visit_expr(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_cast<'ast, V>(v: &mut V, node: &'ast crate::ExprCast)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_expr(&*node.expr);
+ skip!(node.as_token);
+ v.visit_type(&*node.ty);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_closure<'ast, V>(v: &mut V, node: &'ast crate::ExprClosure)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.lifetimes {
+ v.visit_bound_lifetimes(it);
+ }
+ skip!(node.constness);
+ skip!(node.movability);
+ skip!(node.asyncness);
+ skip!(node.capture);
+ skip!(node.or1_token);
+ for el in Punctuated::pairs(&node.inputs) {
+ let it = el.value();
+ v.visit_pat(it);
+ }
+ skip!(node.or2_token);
+ v.visit_return_type(&node.output);
+ v.visit_expr(&*node.body);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_const<'ast, V>(v: &mut V, node: &'ast crate::ExprConst)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.const_token);
+ v.visit_block(&node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_continue<'ast, V>(v: &mut V, node: &'ast crate::ExprContinue)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.continue_token);
+ if let Some(it) = &node.label {
+ v.visit_lifetime(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_field<'ast, V>(v: &mut V, node: &'ast crate::ExprField)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_expr(&*node.base);
+ skip!(node.dot_token);
+ v.visit_member(&node.member);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_for_loop<'ast, V>(v: &mut V, node: &'ast crate::ExprForLoop)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.label {
+ v.visit_label(it);
+ }
+ skip!(node.for_token);
+ v.visit_pat(&*node.pat);
+ skip!(node.in_token);
+ v.visit_expr(&*node.expr);
+ v.visit_block(&node.body);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_group<'ast, V>(v: &mut V, node: &'ast crate::ExprGroup)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.group_token);
+ v.visit_expr(&*node.expr);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_if<'ast, V>(v: &mut V, node: &'ast crate::ExprIf)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.if_token);
+ v.visit_expr(&*node.cond);
+ v.visit_block(&node.then_branch);
+ if let Some(it) = &node.else_branch {
+ skip!((it).0);
+ v.visit_expr(&*(it).1);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_index<'ast, V>(v: &mut V, node: &'ast crate::ExprIndex)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_expr(&*node.expr);
+ skip!(node.bracket_token);
+ v.visit_expr(&*node.index);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_infer<'ast, V>(v: &mut V, node: &'ast crate::ExprInfer)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.underscore_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_let<'ast, V>(v: &mut V, node: &'ast crate::ExprLet)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.let_token);
+ v.visit_pat(&*node.pat);
+ skip!(node.eq_token);
+ v.visit_expr(&*node.expr);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_lit<'ast, V>(v: &mut V, node: &'ast crate::ExprLit)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_lit(&node.lit);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_loop<'ast, V>(v: &mut V, node: &'ast crate::ExprLoop)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.label {
+ v.visit_label(it);
+ }
+ skip!(node.loop_token);
+ v.visit_block(&node.body);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_macro<'ast, V>(v: &mut V, node: &'ast crate::ExprMacro)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_macro(&node.mac);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_match<'ast, V>(v: &mut V, node: &'ast crate::ExprMatch)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.match_token);
+ v.visit_expr(&*node.expr);
+ skip!(node.brace_token);
+ for it in &node.arms {
+ v.visit_arm(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_method_call<'ast, V>(v: &mut V, node: &'ast crate::ExprMethodCall)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_expr(&*node.receiver);
+ skip!(node.dot_token);
+ v.visit_ident(&node.method);
+ if let Some(it) = &node.turbofish {
+ v.visit_angle_bracketed_generic_arguments(it);
+ }
+ skip!(node.paren_token);
+ for el in Punctuated::pairs(&node.args) {
+ let it = el.value();
+ v.visit_expr(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_paren<'ast, V>(v: &mut V, node: &'ast crate::ExprParen)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.paren_token);
+ v.visit_expr(&*node.expr);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_path<'ast, V>(v: &mut V, node: &'ast crate::ExprPath)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.qself {
+ v.visit_qself(it);
+ }
+ v.visit_path(&node.path);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_range<'ast, V>(v: &mut V, node: &'ast crate::ExprRange)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.start {
+ v.visit_expr(&**it);
+ }
+ v.visit_range_limits(&node.limits);
+ if let Some(it) = &node.end {
+ v.visit_expr(&**it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_reference<'ast, V>(v: &mut V, node: &'ast crate::ExprReference)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.and_token);
+ skip!(node.mutability);
+ v.visit_expr(&*node.expr);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_repeat<'ast, V>(v: &mut V, node: &'ast crate::ExprRepeat)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.bracket_token);
+ v.visit_expr(&*node.expr);
+ skip!(node.semi_token);
+ v.visit_expr(&*node.len);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_return<'ast, V>(v: &mut V, node: &'ast crate::ExprReturn)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.return_token);
+ if let Some(it) = &node.expr {
+ v.visit_expr(&**it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_struct<'ast, V>(v: &mut V, node: &'ast crate::ExprStruct)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.qself {
+ v.visit_qself(it);
+ }
+ v.visit_path(&node.path);
+ skip!(node.brace_token);
+ for el in Punctuated::pairs(&node.fields) {
+ let it = el.value();
+ v.visit_field_value(it);
+ }
+ skip!(node.dot2_token);
+ if let Some(it) = &node.rest {
+ v.visit_expr(&**it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_try<'ast, V>(v: &mut V, node: &'ast crate::ExprTry)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_expr(&*node.expr);
+ skip!(node.question_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_try_block<'ast, V>(v: &mut V, node: &'ast crate::ExprTryBlock)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.try_token);
+ v.visit_block(&node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_tuple<'ast, V>(v: &mut V, node: &'ast crate::ExprTuple)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.paren_token);
+ for el in Punctuated::pairs(&node.elems) {
+ let it = el.value();
+ v.visit_expr(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_unary<'ast, V>(v: &mut V, node: &'ast crate::ExprUnary)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_un_op(&node.op);
+ v.visit_expr(&*node.expr);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_unsafe<'ast, V>(v: &mut V, node: &'ast crate::ExprUnsafe)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.unsafe_token);
+ v.visit_block(&node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_while<'ast, V>(v: &mut V, node: &'ast crate::ExprWhile)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.label {
+ v.visit_label(it);
+ }
+ skip!(node.while_token);
+ v.visit_expr(&*node.cond);
+ v.visit_block(&node.body);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_yield<'ast, V>(v: &mut V, node: &'ast crate::ExprYield)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.yield_token);
+ if let Some(it) = &node.expr {
+ v.visit_expr(&**it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_field<'ast, V>(v: &mut V, node: &'ast crate::Field)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ v.visit_field_mutability(&node.mutability);
+ if let Some(it) = &node.ident {
+ v.visit_ident(it);
+ }
+ skip!(node.colon_token);
+ v.visit_type(&node.ty);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_field_mutability<'ast, V>(v: &mut V, node: &'ast crate::FieldMutability)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::FieldMutability::None => {}
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_field_pat<'ast, V>(v: &mut V, node: &'ast crate::FieldPat)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_member(&node.member);
+ skip!(node.colon_token);
+ v.visit_pat(&*node.pat);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_field_value<'ast, V>(v: &mut V, node: &'ast crate::FieldValue)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_member(&node.member);
+ skip!(node.colon_token);
+ v.visit_expr(&node.expr);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_fields<'ast, V>(v: &mut V, node: &'ast crate::Fields)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::Fields::Named(_binding_0) => {
+ v.visit_fields_named(_binding_0);
+ }
+ crate::Fields::Unnamed(_binding_0) => {
+ v.visit_fields_unnamed(_binding_0);
+ }
+ crate::Fields::Unit => {}
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_fields_named<'ast, V>(v: &mut V, node: &'ast crate::FieldsNamed)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.brace_token);
+ for el in Punctuated::pairs(&node.named) {
+ let it = el.value();
+ v.visit_field(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_fields_unnamed<'ast, V>(v: &mut V, node: &'ast crate::FieldsUnnamed)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.paren_token);
+ for el in Punctuated::pairs(&node.unnamed) {
+ let it = el.value();
+ v.visit_field(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_file<'ast, V>(v: &mut V, node: &'ast crate::File)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.shebang);
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ for it in &node.items {
+ v.visit_item(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_fn_arg<'ast, V>(v: &mut V, node: &'ast crate::FnArg)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::FnArg::Receiver(_binding_0) => {
+ v.visit_receiver(_binding_0);
+ }
+ crate::FnArg::Typed(_binding_0) => {
+ v.visit_pat_type(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_foreign_item<'ast, V>(v: &mut V, node: &'ast crate::ForeignItem)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::ForeignItem::Fn(_binding_0) => {
+ v.visit_foreign_item_fn(_binding_0);
+ }
+ crate::ForeignItem::Static(_binding_0) => {
+ v.visit_foreign_item_static(_binding_0);
+ }
+ crate::ForeignItem::Type(_binding_0) => {
+ v.visit_foreign_item_type(_binding_0);
+ }
+ crate::ForeignItem::Macro(_binding_0) => {
+ v.visit_foreign_item_macro(_binding_0);
+ }
+ crate::ForeignItem::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_foreign_item_fn<'ast, V>(v: &mut V, node: &'ast crate::ForeignItemFn)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ v.visit_signature(&node.sig);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_foreign_item_macro<'ast, V>(v: &mut V, node: &'ast crate::ForeignItemMacro)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_macro(&node.mac);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_foreign_item_static<'ast, V>(
+ v: &mut V,
+ node: &'ast crate::ForeignItemStatic,
+)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.static_token);
+ v.visit_static_mutability(&node.mutability);
+ v.visit_ident(&node.ident);
+ skip!(node.colon_token);
+ v.visit_type(&*node.ty);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_foreign_item_type<'ast, V>(v: &mut V, node: &'ast crate::ForeignItemType)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.type_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ skip!(node.semi_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_generic_argument<'ast, V>(v: &mut V, node: &'ast crate::GenericArgument)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::GenericArgument::Lifetime(_binding_0) => {
+ v.visit_lifetime(_binding_0);
+ }
+ crate::GenericArgument::Type(_binding_0) => {
+ v.visit_type(_binding_0);
+ }
+ crate::GenericArgument::Const(_binding_0) => {
+ v.visit_expr(_binding_0);
+ }
+ crate::GenericArgument::AssocType(_binding_0) => {
+ v.visit_assoc_type(_binding_0);
+ }
+ crate::GenericArgument::AssocConst(_binding_0) => {
+ v.visit_assoc_const(_binding_0);
+ }
+ crate::GenericArgument::Constraint(_binding_0) => {
+ v.visit_constraint(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_generic_param<'ast, V>(v: &mut V, node: &'ast crate::GenericParam)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::GenericParam::Lifetime(_binding_0) => {
+ v.visit_lifetime_param(_binding_0);
+ }
+ crate::GenericParam::Type(_binding_0) => {
+ v.visit_type_param(_binding_0);
+ }
+ crate::GenericParam::Const(_binding_0) => {
+ v.visit_const_param(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_generics<'ast, V>(v: &mut V, node: &'ast crate::Generics)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.lt_token);
+ for el in Punctuated::pairs(&node.params) {
+ let it = el.value();
+ v.visit_generic_param(it);
+ }
+ skip!(node.gt_token);
+ if let Some(it) = &node.where_clause {
+ v.visit_where_clause(it);
+ }
+}
+pub fn visit_ident<'ast, V>(v: &mut V, node: &'ast proc_macro2::Ident)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_span(&node.span());
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_impl_item<'ast, V>(v: &mut V, node: &'ast crate::ImplItem)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::ImplItem::Const(_binding_0) => {
+ v.visit_impl_item_const(_binding_0);
+ }
+ crate::ImplItem::Fn(_binding_0) => {
+ v.visit_impl_item_fn(_binding_0);
+ }
+ crate::ImplItem::Type(_binding_0) => {
+ v.visit_impl_item_type(_binding_0);
+ }
+ crate::ImplItem::Macro(_binding_0) => {
+ v.visit_impl_item_macro(_binding_0);
+ }
+ crate::ImplItem::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_impl_item_const<'ast, V>(v: &mut V, node: &'ast crate::ImplItemConst)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.defaultness);
+ skip!(node.const_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ skip!(node.colon_token);
+ v.visit_type(&node.ty);
+ skip!(node.eq_token);
+ v.visit_expr(&node.expr);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_impl_item_fn<'ast, V>(v: &mut V, node: &'ast crate::ImplItemFn)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.defaultness);
+ v.visit_signature(&node.sig);
+ v.visit_block(&node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_impl_item_macro<'ast, V>(v: &mut V, node: &'ast crate::ImplItemMacro)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_macro(&node.mac);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_impl_item_type<'ast, V>(v: &mut V, node: &'ast crate::ImplItemType)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.defaultness);
+ skip!(node.type_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ skip!(node.eq_token);
+ v.visit_type(&node.ty);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_impl_restriction<'ast, V>(v: &mut V, node: &'ast crate::ImplRestriction)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match *node {}
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_index<'ast, V>(v: &mut V, node: &'ast crate::Index)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.index);
+ v.visit_span(&node.span);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item<'ast, V>(v: &mut V, node: &'ast crate::Item)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::Item::Const(_binding_0) => {
+ v.visit_item_const(_binding_0);
+ }
+ crate::Item::Enum(_binding_0) => {
+ v.visit_item_enum(_binding_0);
+ }
+ crate::Item::ExternCrate(_binding_0) => {
+ v.visit_item_extern_crate(_binding_0);
+ }
+ crate::Item::Fn(_binding_0) => {
+ v.visit_item_fn(_binding_0);
+ }
+ crate::Item::ForeignMod(_binding_0) => {
+ v.visit_item_foreign_mod(_binding_0);
+ }
+ crate::Item::Impl(_binding_0) => {
+ v.visit_item_impl(_binding_0);
+ }
+ crate::Item::Macro(_binding_0) => {
+ v.visit_item_macro(_binding_0);
+ }
+ crate::Item::Mod(_binding_0) => {
+ v.visit_item_mod(_binding_0);
+ }
+ crate::Item::Static(_binding_0) => {
+ v.visit_item_static(_binding_0);
+ }
+ crate::Item::Struct(_binding_0) => {
+ v.visit_item_struct(_binding_0);
+ }
+ crate::Item::Trait(_binding_0) => {
+ v.visit_item_trait(_binding_0);
+ }
+ crate::Item::TraitAlias(_binding_0) => {
+ v.visit_item_trait_alias(_binding_0);
+ }
+ crate::Item::Type(_binding_0) => {
+ v.visit_item_type(_binding_0);
+ }
+ crate::Item::Union(_binding_0) => {
+ v.visit_item_union(_binding_0);
+ }
+ crate::Item::Use(_binding_0) => {
+ v.visit_item_use(_binding_0);
+ }
+ crate::Item::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_const<'ast, V>(v: &mut V, node: &'ast crate::ItemConst)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.const_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ skip!(node.colon_token);
+ v.visit_type(&*node.ty);
+ skip!(node.eq_token);
+ v.visit_expr(&*node.expr);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_enum<'ast, V>(v: &mut V, node: &'ast crate::ItemEnum)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.enum_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ skip!(node.brace_token);
+ for el in Punctuated::pairs(&node.variants) {
+ let it = el.value();
+ v.visit_variant(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_extern_crate<'ast, V>(v: &mut V, node: &'ast crate::ItemExternCrate)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.extern_token);
+ skip!(node.crate_token);
+ v.visit_ident(&node.ident);
+ if let Some(it) = &node.rename {
+ skip!((it).0);
+ v.visit_ident(&(it).1);
+ }
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_fn<'ast, V>(v: &mut V, node: &'ast crate::ItemFn)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ v.visit_signature(&node.sig);
+ v.visit_block(&*node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_foreign_mod<'ast, V>(v: &mut V, node: &'ast crate::ItemForeignMod)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.unsafety);
+ v.visit_abi(&node.abi);
+ skip!(node.brace_token);
+ for it in &node.items {
+ v.visit_foreign_item(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_impl<'ast, V>(v: &mut V, node: &'ast crate::ItemImpl)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.defaultness);
+ skip!(node.unsafety);
+ skip!(node.impl_token);
+ v.visit_generics(&node.generics);
+ if let Some(it) = &node.trait_ {
+ skip!((it).0);
+ v.visit_path(&(it).1);
+ skip!((it).2);
+ }
+ v.visit_type(&*node.self_ty);
+ skip!(node.brace_token);
+ for it in &node.items {
+ v.visit_impl_item(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_macro<'ast, V>(v: &mut V, node: &'ast crate::ItemMacro)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.ident {
+ v.visit_ident(it);
+ }
+ v.visit_macro(&node.mac);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_mod<'ast, V>(v: &mut V, node: &'ast crate::ItemMod)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.unsafety);
+ skip!(node.mod_token);
+ v.visit_ident(&node.ident);
+ if let Some(it) = &node.content {
+ skip!((it).0);
+ for it in &(it).1 {
+ v.visit_item(it);
+ }
+ }
+ skip!(node.semi);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_static<'ast, V>(v: &mut V, node: &'ast crate::ItemStatic)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.static_token);
+ v.visit_static_mutability(&node.mutability);
+ v.visit_ident(&node.ident);
+ skip!(node.colon_token);
+ v.visit_type(&*node.ty);
+ skip!(node.eq_token);
+ v.visit_expr(&*node.expr);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_struct<'ast, V>(v: &mut V, node: &'ast crate::ItemStruct)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.struct_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ v.visit_fields(&node.fields);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_trait<'ast, V>(v: &mut V, node: &'ast crate::ItemTrait)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.unsafety);
+ skip!(node.auto_token);
+ if let Some(it) = &node.restriction {
+ v.visit_impl_restriction(it);
+ }
+ skip!(node.trait_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ skip!(node.colon_token);
+ for el in Punctuated::pairs(&node.supertraits) {
+ let it = el.value();
+ v.visit_type_param_bound(it);
+ }
+ skip!(node.brace_token);
+ for it in &node.items {
+ v.visit_trait_item(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_trait_alias<'ast, V>(v: &mut V, node: &'ast crate::ItemTraitAlias)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.trait_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ skip!(node.eq_token);
+ for el in Punctuated::pairs(&node.bounds) {
+ let it = el.value();
+ v.visit_type_param_bound(it);
+ }
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_type<'ast, V>(v: &mut V, node: &'ast crate::ItemType)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.type_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ skip!(node.eq_token);
+ v.visit_type(&*node.ty);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_union<'ast, V>(v: &mut V, node: &'ast crate::ItemUnion)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.union_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ v.visit_fields_named(&node.fields);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_use<'ast, V>(v: &mut V, node: &'ast crate::ItemUse)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_visibility(&node.vis);
+ skip!(node.use_token);
+ skip!(node.leading_colon);
+ v.visit_use_tree(&node.tree);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_label<'ast, V>(v: &mut V, node: &'ast crate::Label)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_lifetime(&node.name);
+ skip!(node.colon_token);
+}
+pub fn visit_lifetime<'ast, V>(v: &mut V, node: &'ast crate::Lifetime)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_span(&node.apostrophe);
+ v.visit_ident(&node.ident);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_lifetime_param<'ast, V>(v: &mut V, node: &'ast crate::LifetimeParam)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_lifetime(&node.lifetime);
+ skip!(node.colon_token);
+ for el in Punctuated::pairs(&node.bounds) {
+ let it = el.value();
+ v.visit_lifetime(it);
+ }
+}
+pub fn visit_lit<'ast, V>(v: &mut V, node: &'ast crate::Lit)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::Lit::Str(_binding_0) => {
+ v.visit_lit_str(_binding_0);
+ }
+ crate::Lit::ByteStr(_binding_0) => {
+ v.visit_lit_byte_str(_binding_0);
+ }
+ crate::Lit::CStr(_binding_0) => {
+ v.visit_lit_cstr(_binding_0);
+ }
+ crate::Lit::Byte(_binding_0) => {
+ v.visit_lit_byte(_binding_0);
+ }
+ crate::Lit::Char(_binding_0) => {
+ v.visit_lit_char(_binding_0);
+ }
+ crate::Lit::Int(_binding_0) => {
+ v.visit_lit_int(_binding_0);
+ }
+ crate::Lit::Float(_binding_0) => {
+ v.visit_lit_float(_binding_0);
+ }
+ crate::Lit::Bool(_binding_0) => {
+ v.visit_lit_bool(_binding_0);
+ }
+ crate::Lit::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+pub fn visit_lit_bool<'ast, V>(v: &mut V, node: &'ast crate::LitBool)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.value);
+ v.visit_span(&node.span);
+}
+pub fn visit_lit_byte<'ast, V>(v: &mut V, node: &'ast crate::LitByte)
+where
+ V: Visit<'ast> + ?Sized,
+{}
+pub fn visit_lit_byte_str<'ast, V>(v: &mut V, node: &'ast crate::LitByteStr)
+where
+ V: Visit<'ast> + ?Sized,
+{}
+pub fn visit_lit_cstr<'ast, V>(v: &mut V, node: &'ast crate::LitCStr)
+where
+ V: Visit<'ast> + ?Sized,
+{}
+pub fn visit_lit_char<'ast, V>(v: &mut V, node: &'ast crate::LitChar)
+where
+ V: Visit<'ast> + ?Sized,
+{}
+pub fn visit_lit_float<'ast, V>(v: &mut V, node: &'ast crate::LitFloat)
+where
+ V: Visit<'ast> + ?Sized,
+{}
+pub fn visit_lit_int<'ast, V>(v: &mut V, node: &'ast crate::LitInt)
+where
+ V: Visit<'ast> + ?Sized,
+{}
+pub fn visit_lit_str<'ast, V>(v: &mut V, node: &'ast crate::LitStr)
+where
+ V: Visit<'ast> + ?Sized,
+{}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_local<'ast, V>(v: &mut V, node: &'ast crate::Local)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.let_token);
+ v.visit_pat(&node.pat);
+ if let Some(it) = &node.init {
+ v.visit_local_init(it);
+ }
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_local_init<'ast, V>(v: &mut V, node: &'ast crate::LocalInit)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.eq_token);
+ v.visit_expr(&*node.expr);
+ if let Some(it) = &node.diverge {
+ skip!((it).0);
+ v.visit_expr(&*(it).1);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_macro<'ast, V>(v: &mut V, node: &'ast crate::Macro)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_path(&node.path);
+ skip!(node.bang_token);
+ v.visit_macro_delimiter(&node.delimiter);
+ skip!(node.tokens);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_macro_delimiter<'ast, V>(v: &mut V, node: &'ast crate::MacroDelimiter)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::MacroDelimiter::Paren(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::MacroDelimiter::Brace(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::MacroDelimiter::Bracket(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_member<'ast, V>(v: &mut V, node: &'ast crate::Member)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::Member::Named(_binding_0) => {
+ v.visit_ident(_binding_0);
+ }
+ crate::Member::Unnamed(_binding_0) => {
+ v.visit_index(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_meta<'ast, V>(v: &mut V, node: &'ast crate::Meta)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::Meta::Path(_binding_0) => {
+ v.visit_path(_binding_0);
+ }
+ crate::Meta::List(_binding_0) => {
+ v.visit_meta_list(_binding_0);
+ }
+ crate::Meta::NameValue(_binding_0) => {
+ v.visit_meta_name_value(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_meta_list<'ast, V>(v: &mut V, node: &'ast crate::MetaList)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_path(&node.path);
+ v.visit_macro_delimiter(&node.delimiter);
+ skip!(node.tokens);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_meta_name_value<'ast, V>(v: &mut V, node: &'ast crate::MetaNameValue)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_path(&node.path);
+ skip!(node.eq_token);
+ v.visit_expr(&node.value);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_parenthesized_generic_arguments<'ast, V>(
+ v: &mut V,
+ node: &'ast crate::ParenthesizedGenericArguments,
+)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.paren_token);
+ for el in Punctuated::pairs(&node.inputs) {
+ let it = el.value();
+ v.visit_type(it);
+ }
+ v.visit_return_type(&node.output);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat<'ast, V>(v: &mut V, node: &'ast crate::Pat)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::Pat::Const(_binding_0) => {
+ v.visit_expr_const(_binding_0);
+ }
+ crate::Pat::Ident(_binding_0) => {
+ v.visit_pat_ident(_binding_0);
+ }
+ crate::Pat::Lit(_binding_0) => {
+ v.visit_expr_lit(_binding_0);
+ }
+ crate::Pat::Macro(_binding_0) => {
+ v.visit_expr_macro(_binding_0);
+ }
+ crate::Pat::Or(_binding_0) => {
+ v.visit_pat_or(_binding_0);
+ }
+ crate::Pat::Paren(_binding_0) => {
+ v.visit_pat_paren(_binding_0);
+ }
+ crate::Pat::Path(_binding_0) => {
+ v.visit_expr_path(_binding_0);
+ }
+ crate::Pat::Range(_binding_0) => {
+ v.visit_expr_range(_binding_0);
+ }
+ crate::Pat::Reference(_binding_0) => {
+ v.visit_pat_reference(_binding_0);
+ }
+ crate::Pat::Rest(_binding_0) => {
+ v.visit_pat_rest(_binding_0);
+ }
+ crate::Pat::Slice(_binding_0) => {
+ v.visit_pat_slice(_binding_0);
+ }
+ crate::Pat::Struct(_binding_0) => {
+ v.visit_pat_struct(_binding_0);
+ }
+ crate::Pat::Tuple(_binding_0) => {
+ v.visit_pat_tuple(_binding_0);
+ }
+ crate::Pat::TupleStruct(_binding_0) => {
+ v.visit_pat_tuple_struct(_binding_0);
+ }
+ crate::Pat::Type(_binding_0) => {
+ v.visit_pat_type(_binding_0);
+ }
+ crate::Pat::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::Pat::Wild(_binding_0) => {
+ v.visit_pat_wild(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_ident<'ast, V>(v: &mut V, node: &'ast crate::PatIdent)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.by_ref);
+ skip!(node.mutability);
+ v.visit_ident(&node.ident);
+ if let Some(it) = &node.subpat {
+ skip!((it).0);
+ v.visit_pat(&*(it).1);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_or<'ast, V>(v: &mut V, node: &'ast crate::PatOr)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.leading_vert);
+ for el in Punctuated::pairs(&node.cases) {
+ let it = el.value();
+ v.visit_pat(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_paren<'ast, V>(v: &mut V, node: &'ast crate::PatParen)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.paren_token);
+ v.visit_pat(&*node.pat);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_reference<'ast, V>(v: &mut V, node: &'ast crate::PatReference)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.and_token);
+ skip!(node.mutability);
+ v.visit_pat(&*node.pat);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_rest<'ast, V>(v: &mut V, node: &'ast crate::PatRest)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.dot2_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_slice<'ast, V>(v: &mut V, node: &'ast crate::PatSlice)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.bracket_token);
+ for el in Punctuated::pairs(&node.elems) {
+ let it = el.value();
+ v.visit_pat(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_struct<'ast, V>(v: &mut V, node: &'ast crate::PatStruct)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.qself {
+ v.visit_qself(it);
+ }
+ v.visit_path(&node.path);
+ skip!(node.brace_token);
+ for el in Punctuated::pairs(&node.fields) {
+ let it = el.value();
+ v.visit_field_pat(it);
+ }
+ if let Some(it) = &node.rest {
+ v.visit_pat_rest(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_tuple<'ast, V>(v: &mut V, node: &'ast crate::PatTuple)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.paren_token);
+ for el in Punctuated::pairs(&node.elems) {
+ let it = el.value();
+ v.visit_pat(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_tuple_struct<'ast, V>(v: &mut V, node: &'ast crate::PatTupleStruct)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.qself {
+ v.visit_qself(it);
+ }
+ v.visit_path(&node.path);
+ skip!(node.paren_token);
+ for el in Punctuated::pairs(&node.elems) {
+ let it = el.value();
+ v.visit_pat(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_type<'ast, V>(v: &mut V, node: &'ast crate::PatType)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_pat(&*node.pat);
+ skip!(node.colon_token);
+ v.visit_type(&*node.ty);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_wild<'ast, V>(v: &mut V, node: &'ast crate::PatWild)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.underscore_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_path<'ast, V>(v: &mut V, node: &'ast crate::Path)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.leading_colon);
+ for el in Punctuated::pairs(&node.segments) {
+ let it = el.value();
+ v.visit_path_segment(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_path_arguments<'ast, V>(v: &mut V, node: &'ast crate::PathArguments)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::PathArguments::None => {}
+ crate::PathArguments::AngleBracketed(_binding_0) => {
+ v.visit_angle_bracketed_generic_arguments(_binding_0);
+ }
+ crate::PathArguments::Parenthesized(_binding_0) => {
+ v.visit_parenthesized_generic_arguments(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_path_segment<'ast, V>(v: &mut V, node: &'ast crate::PathSegment)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_ident(&node.ident);
+ v.visit_path_arguments(&node.arguments);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_predicate_lifetime<'ast, V>(v: &mut V, node: &'ast crate::PredicateLifetime)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_lifetime(&node.lifetime);
+ skip!(node.colon_token);
+ for el in Punctuated::pairs(&node.bounds) {
+ let it = el.value();
+ v.visit_lifetime(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_predicate_type<'ast, V>(v: &mut V, node: &'ast crate::PredicateType)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ if let Some(it) = &node.lifetimes {
+ v.visit_bound_lifetimes(it);
+ }
+ v.visit_type(&node.bounded_ty);
+ skip!(node.colon_token);
+ for el in Punctuated::pairs(&node.bounds) {
+ let it = el.value();
+ v.visit_type_param_bound(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_qself<'ast, V>(v: &mut V, node: &'ast crate::QSelf)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.lt_token);
+ v.visit_type(&*node.ty);
+ skip!(node.position);
+ skip!(node.as_token);
+ skip!(node.gt_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_range_limits<'ast, V>(v: &mut V, node: &'ast crate::RangeLimits)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::RangeLimits::HalfOpen(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::RangeLimits::Closed(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_receiver<'ast, V>(v: &mut V, node: &'ast crate::Receiver)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.reference {
+ skip!((it).0);
+ if let Some(it) = &(it).1 {
+ v.visit_lifetime(it);
+ }
+ }
+ skip!(node.mutability);
+ skip!(node.self_token);
+ skip!(node.colon_token);
+ v.visit_type(&*node.ty);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_return_type<'ast, V>(v: &mut V, node: &'ast crate::ReturnType)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::ReturnType::Default => {}
+ crate::ReturnType::Type(_binding_0, _binding_1) => {
+ skip!(_binding_0);
+ v.visit_type(&**_binding_1);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_signature<'ast, V>(v: &mut V, node: &'ast crate::Signature)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.constness);
+ skip!(node.asyncness);
+ skip!(node.unsafety);
+ if let Some(it) = &node.abi {
+ v.visit_abi(it);
+ }
+ skip!(node.fn_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ skip!(node.paren_token);
+ for el in Punctuated::pairs(&node.inputs) {
+ let it = el.value();
+ v.visit_fn_arg(it);
+ }
+ if let Some(it) = &node.variadic {
+ v.visit_variadic(it);
+ }
+ v.visit_return_type(&node.output);
+}
+pub fn visit_span<'ast, V>(v: &mut V, node: &proc_macro2::Span)
+where
+ V: Visit<'ast> + ?Sized,
+{}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_static_mutability<'ast, V>(v: &mut V, node: &'ast crate::StaticMutability)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::StaticMutability::Mut(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::StaticMutability::None => {}
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_stmt<'ast, V>(v: &mut V, node: &'ast crate::Stmt)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::Stmt::Local(_binding_0) => {
+ v.visit_local(_binding_0);
+ }
+ crate::Stmt::Item(_binding_0) => {
+ v.visit_item(_binding_0);
+ }
+ crate::Stmt::Expr(_binding_0, _binding_1) => {
+ v.visit_expr(_binding_0);
+ skip!(_binding_1);
+ }
+ crate::Stmt::Macro(_binding_0) => {
+ v.visit_stmt_macro(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_stmt_macro<'ast, V>(v: &mut V, node: &'ast crate::StmtMacro)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_macro(&node.mac);
+ skip!(node.semi_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_trait_bound<'ast, V>(v: &mut V, node: &'ast crate::TraitBound)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.paren_token);
+ v.visit_trait_bound_modifier(&node.modifier);
+ if let Some(it) = &node.lifetimes {
+ v.visit_bound_lifetimes(it);
+ }
+ v.visit_path(&node.path);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_trait_bound_modifier<'ast, V>(
+ v: &mut V,
+ node: &'ast crate::TraitBoundModifier,
+)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::TraitBoundModifier::None => {}
+ crate::TraitBoundModifier::Maybe(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_trait_item<'ast, V>(v: &mut V, node: &'ast crate::TraitItem)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::TraitItem::Const(_binding_0) => {
+ v.visit_trait_item_const(_binding_0);
+ }
+ crate::TraitItem::Fn(_binding_0) => {
+ v.visit_trait_item_fn(_binding_0);
+ }
+ crate::TraitItem::Type(_binding_0) => {
+ v.visit_trait_item_type(_binding_0);
+ }
+ crate::TraitItem::Macro(_binding_0) => {
+ v.visit_trait_item_macro(_binding_0);
+ }
+ crate::TraitItem::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_trait_item_const<'ast, V>(v: &mut V, node: &'ast crate::TraitItemConst)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.const_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ skip!(node.colon_token);
+ v.visit_type(&node.ty);
+ if let Some(it) = &node.default {
+ skip!((it).0);
+ v.visit_expr(&(it).1);
+ }
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_trait_item_fn<'ast, V>(v: &mut V, node: &'ast crate::TraitItemFn)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_signature(&node.sig);
+ if let Some(it) = &node.default {
+ v.visit_block(it);
+ }
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_trait_item_macro<'ast, V>(v: &mut V, node: &'ast crate::TraitItemMacro)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_macro(&node.mac);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_trait_item_type<'ast, V>(v: &mut V, node: &'ast crate::TraitItemType)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ skip!(node.type_token);
+ v.visit_ident(&node.ident);
+ v.visit_generics(&node.generics);
+ skip!(node.colon_token);
+ for el in Punctuated::pairs(&node.bounds) {
+ let it = el.value();
+ v.visit_type_param_bound(it);
+ }
+ if let Some(it) = &node.default {
+ skip!((it).0);
+ v.visit_type(&(it).1);
+ }
+ skip!(node.semi_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type<'ast, V>(v: &mut V, node: &'ast crate::Type)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::Type::Array(_binding_0) => {
+ v.visit_type_array(_binding_0);
+ }
+ crate::Type::BareFn(_binding_0) => {
+ v.visit_type_bare_fn(_binding_0);
+ }
+ crate::Type::Group(_binding_0) => {
+ v.visit_type_group(_binding_0);
+ }
+ crate::Type::ImplTrait(_binding_0) => {
+ v.visit_type_impl_trait(_binding_0);
+ }
+ crate::Type::Infer(_binding_0) => {
+ v.visit_type_infer(_binding_0);
+ }
+ crate::Type::Macro(_binding_0) => {
+ v.visit_type_macro(_binding_0);
+ }
+ crate::Type::Never(_binding_0) => {
+ v.visit_type_never(_binding_0);
+ }
+ crate::Type::Paren(_binding_0) => {
+ v.visit_type_paren(_binding_0);
+ }
+ crate::Type::Path(_binding_0) => {
+ v.visit_type_path(_binding_0);
+ }
+ crate::Type::Ptr(_binding_0) => {
+ v.visit_type_ptr(_binding_0);
+ }
+ crate::Type::Reference(_binding_0) => {
+ v.visit_type_reference(_binding_0);
+ }
+ crate::Type::Slice(_binding_0) => {
+ v.visit_type_slice(_binding_0);
+ }
+ crate::Type::TraitObject(_binding_0) => {
+ v.visit_type_trait_object(_binding_0);
+ }
+ crate::Type::Tuple(_binding_0) => {
+ v.visit_type_tuple(_binding_0);
+ }
+ crate::Type::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_array<'ast, V>(v: &mut V, node: &'ast crate::TypeArray)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.bracket_token);
+ v.visit_type(&*node.elem);
+ skip!(node.semi_token);
+ v.visit_expr(&node.len);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_bare_fn<'ast, V>(v: &mut V, node: &'ast crate::TypeBareFn)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ if let Some(it) = &node.lifetimes {
+ v.visit_bound_lifetimes(it);
+ }
+ skip!(node.unsafety);
+ if let Some(it) = &node.abi {
+ v.visit_abi(it);
+ }
+ skip!(node.fn_token);
+ skip!(node.paren_token);
+ for el in Punctuated::pairs(&node.inputs) {
+ let it = el.value();
+ v.visit_bare_fn_arg(it);
+ }
+ if let Some(it) = &node.variadic {
+ v.visit_bare_variadic(it);
+ }
+ v.visit_return_type(&node.output);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_group<'ast, V>(v: &mut V, node: &'ast crate::TypeGroup)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.group_token);
+ v.visit_type(&*node.elem);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_impl_trait<'ast, V>(v: &mut V, node: &'ast crate::TypeImplTrait)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.impl_token);
+ for el in Punctuated::pairs(&node.bounds) {
+ let it = el.value();
+ v.visit_type_param_bound(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_infer<'ast, V>(v: &mut V, node: &'ast crate::TypeInfer)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.underscore_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_macro<'ast, V>(v: &mut V, node: &'ast crate::TypeMacro)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_macro(&node.mac);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_never<'ast, V>(v: &mut V, node: &'ast crate::TypeNever)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.bang_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_param<'ast, V>(v: &mut V, node: &'ast crate::TypeParam)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_ident(&node.ident);
+ skip!(node.colon_token);
+ for el in Punctuated::pairs(&node.bounds) {
+ let it = el.value();
+ v.visit_type_param_bound(it);
+ }
+ skip!(node.eq_token);
+ if let Some(it) = &node.default {
+ v.visit_type(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_param_bound<'ast, V>(v: &mut V, node: &'ast crate::TypeParamBound)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::TypeParamBound::Trait(_binding_0) => {
+ v.visit_trait_bound(_binding_0);
+ }
+ crate::TypeParamBound::Lifetime(_binding_0) => {
+ v.visit_lifetime(_binding_0);
+ }
+ crate::TypeParamBound::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_paren<'ast, V>(v: &mut V, node: &'ast crate::TypeParen)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.paren_token);
+ v.visit_type(&*node.elem);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_path<'ast, V>(v: &mut V, node: &'ast crate::TypePath)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ if let Some(it) = &node.qself {
+ v.visit_qself(it);
+ }
+ v.visit_path(&node.path);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_ptr<'ast, V>(v: &mut V, node: &'ast crate::TypePtr)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.star_token);
+ skip!(node.const_token);
+ skip!(node.mutability);
+ v.visit_type(&*node.elem);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_reference<'ast, V>(v: &mut V, node: &'ast crate::TypeReference)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.and_token);
+ if let Some(it) = &node.lifetime {
+ v.visit_lifetime(it);
+ }
+ skip!(node.mutability);
+ v.visit_type(&*node.elem);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_slice<'ast, V>(v: &mut V, node: &'ast crate::TypeSlice)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.bracket_token);
+ v.visit_type(&*node.elem);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_trait_object<'ast, V>(v: &mut V, node: &'ast crate::TypeTraitObject)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.dyn_token);
+ for el in Punctuated::pairs(&node.bounds) {
+ let it = el.value();
+ v.visit_type_param_bound(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_tuple<'ast, V>(v: &mut V, node: &'ast crate::TypeTuple)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.paren_token);
+ for el in Punctuated::pairs(&node.elems) {
+ let it = el.value();
+ v.visit_type(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_un_op<'ast, V>(v: &mut V, node: &'ast crate::UnOp)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::UnOp::Deref(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::UnOp::Not(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::UnOp::Neg(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_use_glob<'ast, V>(v: &mut V, node: &'ast crate::UseGlob)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.star_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_use_group<'ast, V>(v: &mut V, node: &'ast crate::UseGroup)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.brace_token);
+ for el in Punctuated::pairs(&node.items) {
+ let it = el.value();
+ v.visit_use_tree(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_use_name<'ast, V>(v: &mut V, node: &'ast crate::UseName)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_ident(&node.ident);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_use_path<'ast, V>(v: &mut V, node: &'ast crate::UsePath)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_ident(&node.ident);
+ skip!(node.colon2_token);
+ v.visit_use_tree(&*node.tree);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_use_rename<'ast, V>(v: &mut V, node: &'ast crate::UseRename)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ v.visit_ident(&node.ident);
+ skip!(node.as_token);
+ v.visit_ident(&node.rename);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_use_tree<'ast, V>(v: &mut V, node: &'ast crate::UseTree)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::UseTree::Path(_binding_0) => {
+ v.visit_use_path(_binding_0);
+ }
+ crate::UseTree::Name(_binding_0) => {
+ v.visit_use_name(_binding_0);
+ }
+ crate::UseTree::Rename(_binding_0) => {
+ v.visit_use_rename(_binding_0);
+ }
+ crate::UseTree::Glob(_binding_0) => {
+ v.visit_use_glob(_binding_0);
+ }
+ crate::UseTree::Group(_binding_0) => {
+ v.visit_use_group(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_variadic<'ast, V>(v: &mut V, node: &'ast crate::Variadic)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ if let Some(it) = &node.pat {
+ v.visit_pat(&*(it).0);
+ skip!((it).1);
+ }
+ skip!(node.dots);
+ skip!(node.comma);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_variant<'ast, V>(v: &mut V, node: &'ast crate::Variant)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ for it in &node.attrs {
+ v.visit_attribute(it);
+ }
+ v.visit_ident(&node.ident);
+ v.visit_fields(&node.fields);
+ if let Some(it) = &node.discriminant {
+ skip!((it).0);
+ v.visit_expr(&(it).1);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_vis_restricted<'ast, V>(v: &mut V, node: &'ast crate::VisRestricted)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.pub_token);
+ skip!(node.paren_token);
+ skip!(node.in_token);
+ v.visit_path(&*node.path);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_visibility<'ast, V>(v: &mut V, node: &'ast crate::Visibility)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::Visibility::Public(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::Visibility::Restricted(_binding_0) => {
+ v.visit_vis_restricted(_binding_0);
+ }
+ crate::Visibility::Inherited => {}
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_where_clause<'ast, V>(v: &mut V, node: &'ast crate::WhereClause)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ skip!(node.where_token);
+ for el in Punctuated::pairs(&node.predicates) {
+ let it = el.value();
+ v.visit_where_predicate(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_where_predicate<'ast, V>(v: &mut V, node: &'ast crate::WherePredicate)
+where
+ V: Visit<'ast> + ?Sized,
+{
+ match node {
+ crate::WherePredicate::Lifetime(_binding_0) => {
+ v.visit_predicate_lifetime(_binding_0);
+ }
+ crate::WherePredicate::Type(_binding_0) => {
+ v.visit_predicate_type(_binding_0);
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/gen/visit_mut.rs b/rust/hw/char/pl011/vendor/syn/src/gen/visit_mut.rs
new file mode 100644
index 0000000000..9d457f1640
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/gen/visit_mut.rs
@@ -0,0 +1,3855 @@
+// This file is @generated by syn-internal-codegen.
+// It is not intended for manual editing.
+
+#![allow(unused_variables)]
+#![allow(clippy::needless_pass_by_ref_mut)]
+#[cfg(any(feature = "full", feature = "derive"))]
+use crate::punctuated::Punctuated;
+#[cfg(feature = "full")]
+macro_rules! full {
+ ($e:expr) => {
+ $e
+ };
+}
+#[cfg(all(feature = "derive", not(feature = "full")))]
+macro_rules! full {
+ ($e:expr) => {
+ unreachable!()
+ };
+}
+macro_rules! skip {
+ ($($tt:tt)*) => {};
+}
+/// Syntax tree traversal to mutate an exclusive borrow of a syntax tree in
+/// place.
+///
+/// See the [module documentation] for details.
+///
+/// [module documentation]: self
+pub trait VisitMut {
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_abi_mut(&mut self, i: &mut crate::Abi) {
+ visit_abi_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_angle_bracketed_generic_arguments_mut(
+ &mut self,
+ i: &mut crate::AngleBracketedGenericArguments,
+ ) {
+ visit_angle_bracketed_generic_arguments_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_arm_mut(&mut self, i: &mut crate::Arm) {
+ visit_arm_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_assoc_const_mut(&mut self, i: &mut crate::AssocConst) {
+ visit_assoc_const_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_assoc_type_mut(&mut self, i: &mut crate::AssocType) {
+ visit_assoc_type_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_attr_style_mut(&mut self, i: &mut crate::AttrStyle) {
+ visit_attr_style_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_attribute_mut(&mut self, i: &mut crate::Attribute) {
+ visit_attribute_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_bare_fn_arg_mut(&mut self, i: &mut crate::BareFnArg) {
+ visit_bare_fn_arg_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_bare_variadic_mut(&mut self, i: &mut crate::BareVariadic) {
+ visit_bare_variadic_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_bin_op_mut(&mut self, i: &mut crate::BinOp) {
+ visit_bin_op_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_block_mut(&mut self, i: &mut crate::Block) {
+ visit_block_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_bound_lifetimes_mut(&mut self, i: &mut crate::BoundLifetimes) {
+ visit_bound_lifetimes_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_const_param_mut(&mut self, i: &mut crate::ConstParam) {
+ visit_const_param_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_constraint_mut(&mut self, i: &mut crate::Constraint) {
+ visit_constraint_mut(self, i);
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn visit_data_mut(&mut self, i: &mut crate::Data) {
+ visit_data_mut(self, i);
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn visit_data_enum_mut(&mut self, i: &mut crate::DataEnum) {
+ visit_data_enum_mut(self, i);
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn visit_data_struct_mut(&mut self, i: &mut crate::DataStruct) {
+ visit_data_struct_mut(self, i);
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn visit_data_union_mut(&mut self, i: &mut crate::DataUnion) {
+ visit_data_union_mut(self, i);
+ }
+ #[cfg(feature = "derive")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+ fn visit_derive_input_mut(&mut self, i: &mut crate::DeriveInput) {
+ visit_derive_input_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_mut(&mut self, i: &mut crate::Expr) {
+ visit_expr_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_array_mut(&mut self, i: &mut crate::ExprArray) {
+ visit_expr_array_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_assign_mut(&mut self, i: &mut crate::ExprAssign) {
+ visit_expr_assign_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_async_mut(&mut self, i: &mut crate::ExprAsync) {
+ visit_expr_async_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_await_mut(&mut self, i: &mut crate::ExprAwait) {
+ visit_expr_await_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_binary_mut(&mut self, i: &mut crate::ExprBinary) {
+ visit_expr_binary_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_block_mut(&mut self, i: &mut crate::ExprBlock) {
+ visit_expr_block_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_break_mut(&mut self, i: &mut crate::ExprBreak) {
+ visit_expr_break_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_call_mut(&mut self, i: &mut crate::ExprCall) {
+ visit_expr_call_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_cast_mut(&mut self, i: &mut crate::ExprCast) {
+ visit_expr_cast_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_closure_mut(&mut self, i: &mut crate::ExprClosure) {
+ visit_expr_closure_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_const_mut(&mut self, i: &mut crate::ExprConst) {
+ visit_expr_const_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_continue_mut(&mut self, i: &mut crate::ExprContinue) {
+ visit_expr_continue_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_field_mut(&mut self, i: &mut crate::ExprField) {
+ visit_expr_field_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_for_loop_mut(&mut self, i: &mut crate::ExprForLoop) {
+ visit_expr_for_loop_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_group_mut(&mut self, i: &mut crate::ExprGroup) {
+ visit_expr_group_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_if_mut(&mut self, i: &mut crate::ExprIf) {
+ visit_expr_if_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_index_mut(&mut self, i: &mut crate::ExprIndex) {
+ visit_expr_index_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_infer_mut(&mut self, i: &mut crate::ExprInfer) {
+ visit_expr_infer_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_let_mut(&mut self, i: &mut crate::ExprLet) {
+ visit_expr_let_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_lit_mut(&mut self, i: &mut crate::ExprLit) {
+ visit_expr_lit_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_loop_mut(&mut self, i: &mut crate::ExprLoop) {
+ visit_expr_loop_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_macro_mut(&mut self, i: &mut crate::ExprMacro) {
+ visit_expr_macro_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_match_mut(&mut self, i: &mut crate::ExprMatch) {
+ visit_expr_match_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_method_call_mut(&mut self, i: &mut crate::ExprMethodCall) {
+ visit_expr_method_call_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_paren_mut(&mut self, i: &mut crate::ExprParen) {
+ visit_expr_paren_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_path_mut(&mut self, i: &mut crate::ExprPath) {
+ visit_expr_path_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_range_mut(&mut self, i: &mut crate::ExprRange) {
+ visit_expr_range_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_reference_mut(&mut self, i: &mut crate::ExprReference) {
+ visit_expr_reference_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_repeat_mut(&mut self, i: &mut crate::ExprRepeat) {
+ visit_expr_repeat_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_return_mut(&mut self, i: &mut crate::ExprReturn) {
+ visit_expr_return_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_struct_mut(&mut self, i: &mut crate::ExprStruct) {
+ visit_expr_struct_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_try_mut(&mut self, i: &mut crate::ExprTry) {
+ visit_expr_try_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_try_block_mut(&mut self, i: &mut crate::ExprTryBlock) {
+ visit_expr_try_block_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_tuple_mut(&mut self, i: &mut crate::ExprTuple) {
+ visit_expr_tuple_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_expr_unary_mut(&mut self, i: &mut crate::ExprUnary) {
+ visit_expr_unary_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_unsafe_mut(&mut self, i: &mut crate::ExprUnsafe) {
+ visit_expr_unsafe_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_while_mut(&mut self, i: &mut crate::ExprWhile) {
+ visit_expr_while_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_expr_yield_mut(&mut self, i: &mut crate::ExprYield) {
+ visit_expr_yield_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_field_mut(&mut self, i: &mut crate::Field) {
+ visit_field_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_field_mutability_mut(&mut self, i: &mut crate::FieldMutability) {
+ visit_field_mutability_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_field_pat_mut(&mut self, i: &mut crate::FieldPat) {
+ visit_field_pat_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_field_value_mut(&mut self, i: &mut crate::FieldValue) {
+ visit_field_value_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_fields_mut(&mut self, i: &mut crate::Fields) {
+ visit_fields_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_fields_named_mut(&mut self, i: &mut crate::FieldsNamed) {
+ visit_fields_named_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_fields_unnamed_mut(&mut self, i: &mut crate::FieldsUnnamed) {
+ visit_fields_unnamed_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_file_mut(&mut self, i: &mut crate::File) {
+ visit_file_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_fn_arg_mut(&mut self, i: &mut crate::FnArg) {
+ visit_fn_arg_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_foreign_item_mut(&mut self, i: &mut crate::ForeignItem) {
+ visit_foreign_item_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_foreign_item_fn_mut(&mut self, i: &mut crate::ForeignItemFn) {
+ visit_foreign_item_fn_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_foreign_item_macro_mut(&mut self, i: &mut crate::ForeignItemMacro) {
+ visit_foreign_item_macro_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_foreign_item_static_mut(&mut self, i: &mut crate::ForeignItemStatic) {
+ visit_foreign_item_static_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_foreign_item_type_mut(&mut self, i: &mut crate::ForeignItemType) {
+ visit_foreign_item_type_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_generic_argument_mut(&mut self, i: &mut crate::GenericArgument) {
+ visit_generic_argument_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_generic_param_mut(&mut self, i: &mut crate::GenericParam) {
+ visit_generic_param_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_generics_mut(&mut self, i: &mut crate::Generics) {
+ visit_generics_mut(self, i);
+ }
+ fn visit_ident_mut(&mut self, i: &mut proc_macro2::Ident) {
+ visit_ident_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_impl_item_mut(&mut self, i: &mut crate::ImplItem) {
+ visit_impl_item_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_impl_item_const_mut(&mut self, i: &mut crate::ImplItemConst) {
+ visit_impl_item_const_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_impl_item_fn_mut(&mut self, i: &mut crate::ImplItemFn) {
+ visit_impl_item_fn_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_impl_item_macro_mut(&mut self, i: &mut crate::ImplItemMacro) {
+ visit_impl_item_macro_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_impl_item_type_mut(&mut self, i: &mut crate::ImplItemType) {
+ visit_impl_item_type_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_impl_restriction_mut(&mut self, i: &mut crate::ImplRestriction) {
+ visit_impl_restriction_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_index_mut(&mut self, i: &mut crate::Index) {
+ visit_index_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_mut(&mut self, i: &mut crate::Item) {
+ visit_item_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_const_mut(&mut self, i: &mut crate::ItemConst) {
+ visit_item_const_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_enum_mut(&mut self, i: &mut crate::ItemEnum) {
+ visit_item_enum_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_extern_crate_mut(&mut self, i: &mut crate::ItemExternCrate) {
+ visit_item_extern_crate_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_fn_mut(&mut self, i: &mut crate::ItemFn) {
+ visit_item_fn_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_foreign_mod_mut(&mut self, i: &mut crate::ItemForeignMod) {
+ visit_item_foreign_mod_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_impl_mut(&mut self, i: &mut crate::ItemImpl) {
+ visit_item_impl_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_macro_mut(&mut self, i: &mut crate::ItemMacro) {
+ visit_item_macro_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_mod_mut(&mut self, i: &mut crate::ItemMod) {
+ visit_item_mod_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_static_mut(&mut self, i: &mut crate::ItemStatic) {
+ visit_item_static_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_struct_mut(&mut self, i: &mut crate::ItemStruct) {
+ visit_item_struct_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_trait_mut(&mut self, i: &mut crate::ItemTrait) {
+ visit_item_trait_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_trait_alias_mut(&mut self, i: &mut crate::ItemTraitAlias) {
+ visit_item_trait_alias_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_type_mut(&mut self, i: &mut crate::ItemType) {
+ visit_item_type_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_union_mut(&mut self, i: &mut crate::ItemUnion) {
+ visit_item_union_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_item_use_mut(&mut self, i: &mut crate::ItemUse) {
+ visit_item_use_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_label_mut(&mut self, i: &mut crate::Label) {
+ visit_label_mut(self, i);
+ }
+ fn visit_lifetime_mut(&mut self, i: &mut crate::Lifetime) {
+ visit_lifetime_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_lifetime_param_mut(&mut self, i: &mut crate::LifetimeParam) {
+ visit_lifetime_param_mut(self, i);
+ }
+ fn visit_lit_mut(&mut self, i: &mut crate::Lit) {
+ visit_lit_mut(self, i);
+ }
+ fn visit_lit_bool_mut(&mut self, i: &mut crate::LitBool) {
+ visit_lit_bool_mut(self, i);
+ }
+ fn visit_lit_byte_mut(&mut self, i: &mut crate::LitByte) {
+ visit_lit_byte_mut(self, i);
+ }
+ fn visit_lit_byte_str_mut(&mut self, i: &mut crate::LitByteStr) {
+ visit_lit_byte_str_mut(self, i);
+ }
+ fn visit_lit_cstr_mut(&mut self, i: &mut crate::LitCStr) {
+ visit_lit_cstr_mut(self, i);
+ }
+ fn visit_lit_char_mut(&mut self, i: &mut crate::LitChar) {
+ visit_lit_char_mut(self, i);
+ }
+ fn visit_lit_float_mut(&mut self, i: &mut crate::LitFloat) {
+ visit_lit_float_mut(self, i);
+ }
+ fn visit_lit_int_mut(&mut self, i: &mut crate::LitInt) {
+ visit_lit_int_mut(self, i);
+ }
+ fn visit_lit_str_mut(&mut self, i: &mut crate::LitStr) {
+ visit_lit_str_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_local_mut(&mut self, i: &mut crate::Local) {
+ visit_local_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_local_init_mut(&mut self, i: &mut crate::LocalInit) {
+ visit_local_init_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_macro_mut(&mut self, i: &mut crate::Macro) {
+ visit_macro_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_macro_delimiter_mut(&mut self, i: &mut crate::MacroDelimiter) {
+ visit_macro_delimiter_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_member_mut(&mut self, i: &mut crate::Member) {
+ visit_member_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_meta_mut(&mut self, i: &mut crate::Meta) {
+ visit_meta_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_meta_list_mut(&mut self, i: &mut crate::MetaList) {
+ visit_meta_list_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_meta_name_value_mut(&mut self, i: &mut crate::MetaNameValue) {
+ visit_meta_name_value_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_parenthesized_generic_arguments_mut(
+ &mut self,
+ i: &mut crate::ParenthesizedGenericArguments,
+ ) {
+ visit_parenthesized_generic_arguments_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_mut(&mut self, i: &mut crate::Pat) {
+ visit_pat_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_ident_mut(&mut self, i: &mut crate::PatIdent) {
+ visit_pat_ident_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_or_mut(&mut self, i: &mut crate::PatOr) {
+ visit_pat_or_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_paren_mut(&mut self, i: &mut crate::PatParen) {
+ visit_pat_paren_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_reference_mut(&mut self, i: &mut crate::PatReference) {
+ visit_pat_reference_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_rest_mut(&mut self, i: &mut crate::PatRest) {
+ visit_pat_rest_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_slice_mut(&mut self, i: &mut crate::PatSlice) {
+ visit_pat_slice_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_struct_mut(&mut self, i: &mut crate::PatStruct) {
+ visit_pat_struct_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_tuple_mut(&mut self, i: &mut crate::PatTuple) {
+ visit_pat_tuple_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_tuple_struct_mut(&mut self, i: &mut crate::PatTupleStruct) {
+ visit_pat_tuple_struct_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_type_mut(&mut self, i: &mut crate::PatType) {
+ visit_pat_type_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_pat_wild_mut(&mut self, i: &mut crate::PatWild) {
+ visit_pat_wild_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_path_mut(&mut self, i: &mut crate::Path) {
+ visit_path_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_path_arguments_mut(&mut self, i: &mut crate::PathArguments) {
+ visit_path_arguments_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_path_segment_mut(&mut self, i: &mut crate::PathSegment) {
+ visit_path_segment_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_predicate_lifetime_mut(&mut self, i: &mut crate::PredicateLifetime) {
+ visit_predicate_lifetime_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_predicate_type_mut(&mut self, i: &mut crate::PredicateType) {
+ visit_predicate_type_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_qself_mut(&mut self, i: &mut crate::QSelf) {
+ visit_qself_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_range_limits_mut(&mut self, i: &mut crate::RangeLimits) {
+ visit_range_limits_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_receiver_mut(&mut self, i: &mut crate::Receiver) {
+ visit_receiver_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_return_type_mut(&mut self, i: &mut crate::ReturnType) {
+ visit_return_type_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_signature_mut(&mut self, i: &mut crate::Signature) {
+ visit_signature_mut(self, i);
+ }
+ fn visit_span_mut(&mut self, i: &mut proc_macro2::Span) {
+ visit_span_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_static_mutability_mut(&mut self, i: &mut crate::StaticMutability) {
+ visit_static_mutability_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_stmt_mut(&mut self, i: &mut crate::Stmt) {
+ visit_stmt_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_stmt_macro_mut(&mut self, i: &mut crate::StmtMacro) {
+ visit_stmt_macro_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_trait_bound_mut(&mut self, i: &mut crate::TraitBound) {
+ visit_trait_bound_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_trait_bound_modifier_mut(&mut self, i: &mut crate::TraitBoundModifier) {
+ visit_trait_bound_modifier_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_trait_item_mut(&mut self, i: &mut crate::TraitItem) {
+ visit_trait_item_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_trait_item_const_mut(&mut self, i: &mut crate::TraitItemConst) {
+ visit_trait_item_const_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_trait_item_fn_mut(&mut self, i: &mut crate::TraitItemFn) {
+ visit_trait_item_fn_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_trait_item_macro_mut(&mut self, i: &mut crate::TraitItemMacro) {
+ visit_trait_item_macro_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_trait_item_type_mut(&mut self, i: &mut crate::TraitItemType) {
+ visit_trait_item_type_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_mut(&mut self, i: &mut crate::Type) {
+ visit_type_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_array_mut(&mut self, i: &mut crate::TypeArray) {
+ visit_type_array_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_bare_fn_mut(&mut self, i: &mut crate::TypeBareFn) {
+ visit_type_bare_fn_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_group_mut(&mut self, i: &mut crate::TypeGroup) {
+ visit_type_group_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_impl_trait_mut(&mut self, i: &mut crate::TypeImplTrait) {
+ visit_type_impl_trait_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_infer_mut(&mut self, i: &mut crate::TypeInfer) {
+ visit_type_infer_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_macro_mut(&mut self, i: &mut crate::TypeMacro) {
+ visit_type_macro_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_never_mut(&mut self, i: &mut crate::TypeNever) {
+ visit_type_never_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_param_mut(&mut self, i: &mut crate::TypeParam) {
+ visit_type_param_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_param_bound_mut(&mut self, i: &mut crate::TypeParamBound) {
+ visit_type_param_bound_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_paren_mut(&mut self, i: &mut crate::TypeParen) {
+ visit_type_paren_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_path_mut(&mut self, i: &mut crate::TypePath) {
+ visit_type_path_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_ptr_mut(&mut self, i: &mut crate::TypePtr) {
+ visit_type_ptr_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_reference_mut(&mut self, i: &mut crate::TypeReference) {
+ visit_type_reference_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_slice_mut(&mut self, i: &mut crate::TypeSlice) {
+ visit_type_slice_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_trait_object_mut(&mut self, i: &mut crate::TypeTraitObject) {
+ visit_type_trait_object_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_type_tuple_mut(&mut self, i: &mut crate::TypeTuple) {
+ visit_type_tuple_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_un_op_mut(&mut self, i: &mut crate::UnOp) {
+ visit_un_op_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_use_glob_mut(&mut self, i: &mut crate::UseGlob) {
+ visit_use_glob_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_use_group_mut(&mut self, i: &mut crate::UseGroup) {
+ visit_use_group_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_use_name_mut(&mut self, i: &mut crate::UseName) {
+ visit_use_name_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_use_path_mut(&mut self, i: &mut crate::UsePath) {
+ visit_use_path_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_use_rename_mut(&mut self, i: &mut crate::UseRename) {
+ visit_use_rename_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_use_tree_mut(&mut self, i: &mut crate::UseTree) {
+ visit_use_tree_mut(self, i);
+ }
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ fn visit_variadic_mut(&mut self, i: &mut crate::Variadic) {
+ visit_variadic_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_variant_mut(&mut self, i: &mut crate::Variant) {
+ visit_variant_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_vis_restricted_mut(&mut self, i: &mut crate::VisRestricted) {
+ visit_vis_restricted_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_visibility_mut(&mut self, i: &mut crate::Visibility) {
+ visit_visibility_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_where_clause_mut(&mut self, i: &mut crate::WhereClause) {
+ visit_where_clause_mut(self, i);
+ }
+ #[cfg(any(feature = "derive", feature = "full"))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+ fn visit_where_predicate_mut(&mut self, i: &mut crate::WherePredicate) {
+ visit_where_predicate_mut(self, i);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_abi_mut<V>(v: &mut V, node: &mut crate::Abi)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.extern_token);
+ if let Some(it) = &mut node.name {
+ v.visit_lit_str_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_angle_bracketed_generic_arguments_mut<V>(
+ v: &mut V,
+ node: &mut crate::AngleBracketedGenericArguments,
+)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.colon2_token);
+ skip!(node.lt_token);
+ for mut el in Punctuated::pairs_mut(&mut node.args) {
+ let it = el.value_mut();
+ v.visit_generic_argument_mut(it);
+ }
+ skip!(node.gt_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_arm_mut<V>(v: &mut V, node: &mut crate::Arm)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_pat_mut(&mut node.pat);
+ if let Some(it) = &mut node.guard {
+ skip!((it).0);
+ v.visit_expr_mut(&mut *(it).1);
+ }
+ skip!(node.fat_arrow_token);
+ v.visit_expr_mut(&mut *node.body);
+ skip!(node.comma);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_assoc_const_mut<V>(v: &mut V, node: &mut crate::AssocConst)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_ident_mut(&mut node.ident);
+ if let Some(it) = &mut node.generics {
+ v.visit_angle_bracketed_generic_arguments_mut(it);
+ }
+ skip!(node.eq_token);
+ v.visit_expr_mut(&mut node.value);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_assoc_type_mut<V>(v: &mut V, node: &mut crate::AssocType)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_ident_mut(&mut node.ident);
+ if let Some(it) = &mut node.generics {
+ v.visit_angle_bracketed_generic_arguments_mut(it);
+ }
+ skip!(node.eq_token);
+ v.visit_type_mut(&mut node.ty);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_attr_style_mut<V>(v: &mut V, node: &mut crate::AttrStyle)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::AttrStyle::Outer => {}
+ crate::AttrStyle::Inner(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_attribute_mut<V>(v: &mut V, node: &mut crate::Attribute)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.pound_token);
+ v.visit_attr_style_mut(&mut node.style);
+ skip!(node.bracket_token);
+ v.visit_meta_mut(&mut node.meta);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_bare_fn_arg_mut<V>(v: &mut V, node: &mut crate::BareFnArg)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.name {
+ v.visit_ident_mut(&mut (it).0);
+ skip!((it).1);
+ }
+ v.visit_type_mut(&mut node.ty);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_bare_variadic_mut<V>(v: &mut V, node: &mut crate::BareVariadic)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.name {
+ v.visit_ident_mut(&mut (it).0);
+ skip!((it).1);
+ }
+ skip!(node.dots);
+ skip!(node.comma);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_bin_op_mut<V>(v: &mut V, node: &mut crate::BinOp)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::BinOp::Add(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Sub(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Mul(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Div(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Rem(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::And(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Or(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::BitXor(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::BitAnd(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::BitOr(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Shl(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Shr(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Eq(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Lt(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Le(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Ne(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Ge(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::Gt(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::AddAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::SubAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::MulAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::DivAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::RemAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::BitXorAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::BitAndAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::BitOrAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::ShlAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::BinOp::ShrAssign(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_block_mut<V>(v: &mut V, node: &mut crate::Block)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.brace_token);
+ for it in &mut node.stmts {
+ v.visit_stmt_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_bound_lifetimes_mut<V>(v: &mut V, node: &mut crate::BoundLifetimes)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.for_token);
+ skip!(node.lt_token);
+ for mut el in Punctuated::pairs_mut(&mut node.lifetimes) {
+ let it = el.value_mut();
+ v.visit_generic_param_mut(it);
+ }
+ skip!(node.gt_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_const_param_mut<V>(v: &mut V, node: &mut crate::ConstParam)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.const_token);
+ v.visit_ident_mut(&mut node.ident);
+ skip!(node.colon_token);
+ v.visit_type_mut(&mut node.ty);
+ skip!(node.eq_token);
+ if let Some(it) = &mut node.default {
+ v.visit_expr_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_constraint_mut<V>(v: &mut V, node: &mut crate::Constraint)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_ident_mut(&mut node.ident);
+ if let Some(it) = &mut node.generics {
+ v.visit_angle_bracketed_generic_arguments_mut(it);
+ }
+ skip!(node.colon_token);
+ for mut el in Punctuated::pairs_mut(&mut node.bounds) {
+ let it = el.value_mut();
+ v.visit_type_param_bound_mut(it);
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn visit_data_mut<V>(v: &mut V, node: &mut crate::Data)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::Data::Struct(_binding_0) => {
+ v.visit_data_struct_mut(_binding_0);
+ }
+ crate::Data::Enum(_binding_0) => {
+ v.visit_data_enum_mut(_binding_0);
+ }
+ crate::Data::Union(_binding_0) => {
+ v.visit_data_union_mut(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn visit_data_enum_mut<V>(v: &mut V, node: &mut crate::DataEnum)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.enum_token);
+ skip!(node.brace_token);
+ for mut el in Punctuated::pairs_mut(&mut node.variants) {
+ let it = el.value_mut();
+ v.visit_variant_mut(it);
+ }
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn visit_data_struct_mut<V>(v: &mut V, node: &mut crate::DataStruct)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.struct_token);
+ v.visit_fields_mut(&mut node.fields);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn visit_data_union_mut<V>(v: &mut V, node: &mut crate::DataUnion)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.union_token);
+ v.visit_fields_named_mut(&mut node.fields);
+}
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub fn visit_derive_input_mut<V>(v: &mut V, node: &mut crate::DeriveInput)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ v.visit_data_mut(&mut node.data);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_mut<V>(v: &mut V, node: &mut crate::Expr)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::Expr::Array(_binding_0) => {
+ full!(v.visit_expr_array_mut(_binding_0));
+ }
+ crate::Expr::Assign(_binding_0) => {
+ full!(v.visit_expr_assign_mut(_binding_0));
+ }
+ crate::Expr::Async(_binding_0) => {
+ full!(v.visit_expr_async_mut(_binding_0));
+ }
+ crate::Expr::Await(_binding_0) => {
+ full!(v.visit_expr_await_mut(_binding_0));
+ }
+ crate::Expr::Binary(_binding_0) => {
+ v.visit_expr_binary_mut(_binding_0);
+ }
+ crate::Expr::Block(_binding_0) => {
+ full!(v.visit_expr_block_mut(_binding_0));
+ }
+ crate::Expr::Break(_binding_0) => {
+ full!(v.visit_expr_break_mut(_binding_0));
+ }
+ crate::Expr::Call(_binding_0) => {
+ v.visit_expr_call_mut(_binding_0);
+ }
+ crate::Expr::Cast(_binding_0) => {
+ v.visit_expr_cast_mut(_binding_0);
+ }
+ crate::Expr::Closure(_binding_0) => {
+ full!(v.visit_expr_closure_mut(_binding_0));
+ }
+ crate::Expr::Const(_binding_0) => {
+ full!(v.visit_expr_const_mut(_binding_0));
+ }
+ crate::Expr::Continue(_binding_0) => {
+ full!(v.visit_expr_continue_mut(_binding_0));
+ }
+ crate::Expr::Field(_binding_0) => {
+ v.visit_expr_field_mut(_binding_0);
+ }
+ crate::Expr::ForLoop(_binding_0) => {
+ full!(v.visit_expr_for_loop_mut(_binding_0));
+ }
+ crate::Expr::Group(_binding_0) => {
+ v.visit_expr_group_mut(_binding_0);
+ }
+ crate::Expr::If(_binding_0) => {
+ full!(v.visit_expr_if_mut(_binding_0));
+ }
+ crate::Expr::Index(_binding_0) => {
+ v.visit_expr_index_mut(_binding_0);
+ }
+ crate::Expr::Infer(_binding_0) => {
+ full!(v.visit_expr_infer_mut(_binding_0));
+ }
+ crate::Expr::Let(_binding_0) => {
+ full!(v.visit_expr_let_mut(_binding_0));
+ }
+ crate::Expr::Lit(_binding_0) => {
+ v.visit_expr_lit_mut(_binding_0);
+ }
+ crate::Expr::Loop(_binding_0) => {
+ full!(v.visit_expr_loop_mut(_binding_0));
+ }
+ crate::Expr::Macro(_binding_0) => {
+ v.visit_expr_macro_mut(_binding_0);
+ }
+ crate::Expr::Match(_binding_0) => {
+ full!(v.visit_expr_match_mut(_binding_0));
+ }
+ crate::Expr::MethodCall(_binding_0) => {
+ v.visit_expr_method_call_mut(_binding_0);
+ }
+ crate::Expr::Paren(_binding_0) => {
+ v.visit_expr_paren_mut(_binding_0);
+ }
+ crate::Expr::Path(_binding_0) => {
+ v.visit_expr_path_mut(_binding_0);
+ }
+ crate::Expr::Range(_binding_0) => {
+ full!(v.visit_expr_range_mut(_binding_0));
+ }
+ crate::Expr::Reference(_binding_0) => {
+ v.visit_expr_reference_mut(_binding_0);
+ }
+ crate::Expr::Repeat(_binding_0) => {
+ full!(v.visit_expr_repeat_mut(_binding_0));
+ }
+ crate::Expr::Return(_binding_0) => {
+ full!(v.visit_expr_return_mut(_binding_0));
+ }
+ crate::Expr::Struct(_binding_0) => {
+ v.visit_expr_struct_mut(_binding_0);
+ }
+ crate::Expr::Try(_binding_0) => {
+ full!(v.visit_expr_try_mut(_binding_0));
+ }
+ crate::Expr::TryBlock(_binding_0) => {
+ full!(v.visit_expr_try_block_mut(_binding_0));
+ }
+ crate::Expr::Tuple(_binding_0) => {
+ full!(v.visit_expr_tuple_mut(_binding_0));
+ }
+ crate::Expr::Unary(_binding_0) => {
+ v.visit_expr_unary_mut(_binding_0);
+ }
+ crate::Expr::Unsafe(_binding_0) => {
+ full!(v.visit_expr_unsafe_mut(_binding_0));
+ }
+ crate::Expr::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::Expr::While(_binding_0) => {
+ full!(v.visit_expr_while_mut(_binding_0));
+ }
+ crate::Expr::Yield(_binding_0) => {
+ full!(v.visit_expr_yield_mut(_binding_0));
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_array_mut<V>(v: &mut V, node: &mut crate::ExprArray)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.bracket_token);
+ for mut el in Punctuated::pairs_mut(&mut node.elems) {
+ let it = el.value_mut();
+ v.visit_expr_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_assign_mut<V>(v: &mut V, node: &mut crate::ExprAssign)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_expr_mut(&mut *node.left);
+ skip!(node.eq_token);
+ v.visit_expr_mut(&mut *node.right);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_async_mut<V>(v: &mut V, node: &mut crate::ExprAsync)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.async_token);
+ skip!(node.capture);
+ v.visit_block_mut(&mut node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_await_mut<V>(v: &mut V, node: &mut crate::ExprAwait)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_expr_mut(&mut *node.base);
+ skip!(node.dot_token);
+ skip!(node.await_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_binary_mut<V>(v: &mut V, node: &mut crate::ExprBinary)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_expr_mut(&mut *node.left);
+ v.visit_bin_op_mut(&mut node.op);
+ v.visit_expr_mut(&mut *node.right);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_block_mut<V>(v: &mut V, node: &mut crate::ExprBlock)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.label {
+ v.visit_label_mut(it);
+ }
+ v.visit_block_mut(&mut node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_break_mut<V>(v: &mut V, node: &mut crate::ExprBreak)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.break_token);
+ if let Some(it) = &mut node.label {
+ v.visit_lifetime_mut(it);
+ }
+ if let Some(it) = &mut node.expr {
+ v.visit_expr_mut(&mut **it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_call_mut<V>(v: &mut V, node: &mut crate::ExprCall)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_expr_mut(&mut *node.func);
+ skip!(node.paren_token);
+ for mut el in Punctuated::pairs_mut(&mut node.args) {
+ let it = el.value_mut();
+ v.visit_expr_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_cast_mut<V>(v: &mut V, node: &mut crate::ExprCast)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_expr_mut(&mut *node.expr);
+ skip!(node.as_token);
+ v.visit_type_mut(&mut *node.ty);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_closure_mut<V>(v: &mut V, node: &mut crate::ExprClosure)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.lifetimes {
+ v.visit_bound_lifetimes_mut(it);
+ }
+ skip!(node.constness);
+ skip!(node.movability);
+ skip!(node.asyncness);
+ skip!(node.capture);
+ skip!(node.or1_token);
+ for mut el in Punctuated::pairs_mut(&mut node.inputs) {
+ let it = el.value_mut();
+ v.visit_pat_mut(it);
+ }
+ skip!(node.or2_token);
+ v.visit_return_type_mut(&mut node.output);
+ v.visit_expr_mut(&mut *node.body);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_const_mut<V>(v: &mut V, node: &mut crate::ExprConst)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.const_token);
+ v.visit_block_mut(&mut node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_continue_mut<V>(v: &mut V, node: &mut crate::ExprContinue)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.continue_token);
+ if let Some(it) = &mut node.label {
+ v.visit_lifetime_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_field_mut<V>(v: &mut V, node: &mut crate::ExprField)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_expr_mut(&mut *node.base);
+ skip!(node.dot_token);
+ v.visit_member_mut(&mut node.member);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_for_loop_mut<V>(v: &mut V, node: &mut crate::ExprForLoop)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.label {
+ v.visit_label_mut(it);
+ }
+ skip!(node.for_token);
+ v.visit_pat_mut(&mut *node.pat);
+ skip!(node.in_token);
+ v.visit_expr_mut(&mut *node.expr);
+ v.visit_block_mut(&mut node.body);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_group_mut<V>(v: &mut V, node: &mut crate::ExprGroup)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.group_token);
+ v.visit_expr_mut(&mut *node.expr);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_if_mut<V>(v: &mut V, node: &mut crate::ExprIf)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.if_token);
+ v.visit_expr_mut(&mut *node.cond);
+ v.visit_block_mut(&mut node.then_branch);
+ if let Some(it) = &mut node.else_branch {
+ skip!((it).0);
+ v.visit_expr_mut(&mut *(it).1);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_index_mut<V>(v: &mut V, node: &mut crate::ExprIndex)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_expr_mut(&mut *node.expr);
+ skip!(node.bracket_token);
+ v.visit_expr_mut(&mut *node.index);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_infer_mut<V>(v: &mut V, node: &mut crate::ExprInfer)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.underscore_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_let_mut<V>(v: &mut V, node: &mut crate::ExprLet)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.let_token);
+ v.visit_pat_mut(&mut *node.pat);
+ skip!(node.eq_token);
+ v.visit_expr_mut(&mut *node.expr);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_lit_mut<V>(v: &mut V, node: &mut crate::ExprLit)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_lit_mut(&mut node.lit);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_loop_mut<V>(v: &mut V, node: &mut crate::ExprLoop)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.label {
+ v.visit_label_mut(it);
+ }
+ skip!(node.loop_token);
+ v.visit_block_mut(&mut node.body);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_macro_mut<V>(v: &mut V, node: &mut crate::ExprMacro)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_macro_mut(&mut node.mac);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_match_mut<V>(v: &mut V, node: &mut crate::ExprMatch)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.match_token);
+ v.visit_expr_mut(&mut *node.expr);
+ skip!(node.brace_token);
+ for it in &mut node.arms {
+ v.visit_arm_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_method_call_mut<V>(v: &mut V, node: &mut crate::ExprMethodCall)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_expr_mut(&mut *node.receiver);
+ skip!(node.dot_token);
+ v.visit_ident_mut(&mut node.method);
+ if let Some(it) = &mut node.turbofish {
+ v.visit_angle_bracketed_generic_arguments_mut(it);
+ }
+ skip!(node.paren_token);
+ for mut el in Punctuated::pairs_mut(&mut node.args) {
+ let it = el.value_mut();
+ v.visit_expr_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_paren_mut<V>(v: &mut V, node: &mut crate::ExprParen)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.paren_token);
+ v.visit_expr_mut(&mut *node.expr);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_path_mut<V>(v: &mut V, node: &mut crate::ExprPath)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.qself {
+ v.visit_qself_mut(it);
+ }
+ v.visit_path_mut(&mut node.path);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_range_mut<V>(v: &mut V, node: &mut crate::ExprRange)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.start {
+ v.visit_expr_mut(&mut **it);
+ }
+ v.visit_range_limits_mut(&mut node.limits);
+ if let Some(it) = &mut node.end {
+ v.visit_expr_mut(&mut **it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_reference_mut<V>(v: &mut V, node: &mut crate::ExprReference)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.and_token);
+ skip!(node.mutability);
+ v.visit_expr_mut(&mut *node.expr);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_repeat_mut<V>(v: &mut V, node: &mut crate::ExprRepeat)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.bracket_token);
+ v.visit_expr_mut(&mut *node.expr);
+ skip!(node.semi_token);
+ v.visit_expr_mut(&mut *node.len);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_return_mut<V>(v: &mut V, node: &mut crate::ExprReturn)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.return_token);
+ if let Some(it) = &mut node.expr {
+ v.visit_expr_mut(&mut **it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_struct_mut<V>(v: &mut V, node: &mut crate::ExprStruct)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.qself {
+ v.visit_qself_mut(it);
+ }
+ v.visit_path_mut(&mut node.path);
+ skip!(node.brace_token);
+ for mut el in Punctuated::pairs_mut(&mut node.fields) {
+ let it = el.value_mut();
+ v.visit_field_value_mut(it);
+ }
+ skip!(node.dot2_token);
+ if let Some(it) = &mut node.rest {
+ v.visit_expr_mut(&mut **it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_try_mut<V>(v: &mut V, node: &mut crate::ExprTry)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_expr_mut(&mut *node.expr);
+ skip!(node.question_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_try_block_mut<V>(v: &mut V, node: &mut crate::ExprTryBlock)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.try_token);
+ v.visit_block_mut(&mut node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_tuple_mut<V>(v: &mut V, node: &mut crate::ExprTuple)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.paren_token);
+ for mut el in Punctuated::pairs_mut(&mut node.elems) {
+ let it = el.value_mut();
+ v.visit_expr_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_expr_unary_mut<V>(v: &mut V, node: &mut crate::ExprUnary)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_un_op_mut(&mut node.op);
+ v.visit_expr_mut(&mut *node.expr);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_unsafe_mut<V>(v: &mut V, node: &mut crate::ExprUnsafe)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.unsafe_token);
+ v.visit_block_mut(&mut node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_while_mut<V>(v: &mut V, node: &mut crate::ExprWhile)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.label {
+ v.visit_label_mut(it);
+ }
+ skip!(node.while_token);
+ v.visit_expr_mut(&mut *node.cond);
+ v.visit_block_mut(&mut node.body);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_expr_yield_mut<V>(v: &mut V, node: &mut crate::ExprYield)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.yield_token);
+ if let Some(it) = &mut node.expr {
+ v.visit_expr_mut(&mut **it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_field_mut<V>(v: &mut V, node: &mut crate::Field)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ v.visit_field_mutability_mut(&mut node.mutability);
+ if let Some(it) = &mut node.ident {
+ v.visit_ident_mut(it);
+ }
+ skip!(node.colon_token);
+ v.visit_type_mut(&mut node.ty);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_field_mutability_mut<V>(v: &mut V, node: &mut crate::FieldMutability)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::FieldMutability::None => {}
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_field_pat_mut<V>(v: &mut V, node: &mut crate::FieldPat)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_member_mut(&mut node.member);
+ skip!(node.colon_token);
+ v.visit_pat_mut(&mut *node.pat);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_field_value_mut<V>(v: &mut V, node: &mut crate::FieldValue)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_member_mut(&mut node.member);
+ skip!(node.colon_token);
+ v.visit_expr_mut(&mut node.expr);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_fields_mut<V>(v: &mut V, node: &mut crate::Fields)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::Fields::Named(_binding_0) => {
+ v.visit_fields_named_mut(_binding_0);
+ }
+ crate::Fields::Unnamed(_binding_0) => {
+ v.visit_fields_unnamed_mut(_binding_0);
+ }
+ crate::Fields::Unit => {}
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_fields_named_mut<V>(v: &mut V, node: &mut crate::FieldsNamed)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.brace_token);
+ for mut el in Punctuated::pairs_mut(&mut node.named) {
+ let it = el.value_mut();
+ v.visit_field_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_fields_unnamed_mut<V>(v: &mut V, node: &mut crate::FieldsUnnamed)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.paren_token);
+ for mut el in Punctuated::pairs_mut(&mut node.unnamed) {
+ let it = el.value_mut();
+ v.visit_field_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_file_mut<V>(v: &mut V, node: &mut crate::File)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.shebang);
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ for it in &mut node.items {
+ v.visit_item_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_fn_arg_mut<V>(v: &mut V, node: &mut crate::FnArg)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::FnArg::Receiver(_binding_0) => {
+ v.visit_receiver_mut(_binding_0);
+ }
+ crate::FnArg::Typed(_binding_0) => {
+ v.visit_pat_type_mut(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_foreign_item_mut<V>(v: &mut V, node: &mut crate::ForeignItem)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::ForeignItem::Fn(_binding_0) => {
+ v.visit_foreign_item_fn_mut(_binding_0);
+ }
+ crate::ForeignItem::Static(_binding_0) => {
+ v.visit_foreign_item_static_mut(_binding_0);
+ }
+ crate::ForeignItem::Type(_binding_0) => {
+ v.visit_foreign_item_type_mut(_binding_0);
+ }
+ crate::ForeignItem::Macro(_binding_0) => {
+ v.visit_foreign_item_macro_mut(_binding_0);
+ }
+ crate::ForeignItem::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_foreign_item_fn_mut<V>(v: &mut V, node: &mut crate::ForeignItemFn)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ v.visit_signature_mut(&mut node.sig);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_foreign_item_macro_mut<V>(v: &mut V, node: &mut crate::ForeignItemMacro)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_macro_mut(&mut node.mac);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_foreign_item_static_mut<V>(v: &mut V, node: &mut crate::ForeignItemStatic)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.static_token);
+ v.visit_static_mutability_mut(&mut node.mutability);
+ v.visit_ident_mut(&mut node.ident);
+ skip!(node.colon_token);
+ v.visit_type_mut(&mut *node.ty);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_foreign_item_type_mut<V>(v: &mut V, node: &mut crate::ForeignItemType)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.type_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ skip!(node.semi_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_generic_argument_mut<V>(v: &mut V, node: &mut crate::GenericArgument)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::GenericArgument::Lifetime(_binding_0) => {
+ v.visit_lifetime_mut(_binding_0);
+ }
+ crate::GenericArgument::Type(_binding_0) => {
+ v.visit_type_mut(_binding_0);
+ }
+ crate::GenericArgument::Const(_binding_0) => {
+ v.visit_expr_mut(_binding_0);
+ }
+ crate::GenericArgument::AssocType(_binding_0) => {
+ v.visit_assoc_type_mut(_binding_0);
+ }
+ crate::GenericArgument::AssocConst(_binding_0) => {
+ v.visit_assoc_const_mut(_binding_0);
+ }
+ crate::GenericArgument::Constraint(_binding_0) => {
+ v.visit_constraint_mut(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_generic_param_mut<V>(v: &mut V, node: &mut crate::GenericParam)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::GenericParam::Lifetime(_binding_0) => {
+ v.visit_lifetime_param_mut(_binding_0);
+ }
+ crate::GenericParam::Type(_binding_0) => {
+ v.visit_type_param_mut(_binding_0);
+ }
+ crate::GenericParam::Const(_binding_0) => {
+ v.visit_const_param_mut(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_generics_mut<V>(v: &mut V, node: &mut crate::Generics)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.lt_token);
+ for mut el in Punctuated::pairs_mut(&mut node.params) {
+ let it = el.value_mut();
+ v.visit_generic_param_mut(it);
+ }
+ skip!(node.gt_token);
+ if let Some(it) = &mut node.where_clause {
+ v.visit_where_clause_mut(it);
+ }
+}
+pub fn visit_ident_mut<V>(v: &mut V, node: &mut proc_macro2::Ident)
+where
+ V: VisitMut + ?Sized,
+{
+ let mut span = node.span();
+ v.visit_span_mut(&mut span);
+ node.set_span(span);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_impl_item_mut<V>(v: &mut V, node: &mut crate::ImplItem)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::ImplItem::Const(_binding_0) => {
+ v.visit_impl_item_const_mut(_binding_0);
+ }
+ crate::ImplItem::Fn(_binding_0) => {
+ v.visit_impl_item_fn_mut(_binding_0);
+ }
+ crate::ImplItem::Type(_binding_0) => {
+ v.visit_impl_item_type_mut(_binding_0);
+ }
+ crate::ImplItem::Macro(_binding_0) => {
+ v.visit_impl_item_macro_mut(_binding_0);
+ }
+ crate::ImplItem::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_impl_item_const_mut<V>(v: &mut V, node: &mut crate::ImplItemConst)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.defaultness);
+ skip!(node.const_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ skip!(node.colon_token);
+ v.visit_type_mut(&mut node.ty);
+ skip!(node.eq_token);
+ v.visit_expr_mut(&mut node.expr);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_impl_item_fn_mut<V>(v: &mut V, node: &mut crate::ImplItemFn)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.defaultness);
+ v.visit_signature_mut(&mut node.sig);
+ v.visit_block_mut(&mut node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_impl_item_macro_mut<V>(v: &mut V, node: &mut crate::ImplItemMacro)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_macro_mut(&mut node.mac);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_impl_item_type_mut<V>(v: &mut V, node: &mut crate::ImplItemType)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.defaultness);
+ skip!(node.type_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ skip!(node.eq_token);
+ v.visit_type_mut(&mut node.ty);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_impl_restriction_mut<V>(v: &mut V, node: &mut crate::ImplRestriction)
+where
+ V: VisitMut + ?Sized,
+{
+ match *node {}
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_index_mut<V>(v: &mut V, node: &mut crate::Index)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.index);
+ v.visit_span_mut(&mut node.span);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_mut<V>(v: &mut V, node: &mut crate::Item)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::Item::Const(_binding_0) => {
+ v.visit_item_const_mut(_binding_0);
+ }
+ crate::Item::Enum(_binding_0) => {
+ v.visit_item_enum_mut(_binding_0);
+ }
+ crate::Item::ExternCrate(_binding_0) => {
+ v.visit_item_extern_crate_mut(_binding_0);
+ }
+ crate::Item::Fn(_binding_0) => {
+ v.visit_item_fn_mut(_binding_0);
+ }
+ crate::Item::ForeignMod(_binding_0) => {
+ v.visit_item_foreign_mod_mut(_binding_0);
+ }
+ crate::Item::Impl(_binding_0) => {
+ v.visit_item_impl_mut(_binding_0);
+ }
+ crate::Item::Macro(_binding_0) => {
+ v.visit_item_macro_mut(_binding_0);
+ }
+ crate::Item::Mod(_binding_0) => {
+ v.visit_item_mod_mut(_binding_0);
+ }
+ crate::Item::Static(_binding_0) => {
+ v.visit_item_static_mut(_binding_0);
+ }
+ crate::Item::Struct(_binding_0) => {
+ v.visit_item_struct_mut(_binding_0);
+ }
+ crate::Item::Trait(_binding_0) => {
+ v.visit_item_trait_mut(_binding_0);
+ }
+ crate::Item::TraitAlias(_binding_0) => {
+ v.visit_item_trait_alias_mut(_binding_0);
+ }
+ crate::Item::Type(_binding_0) => {
+ v.visit_item_type_mut(_binding_0);
+ }
+ crate::Item::Union(_binding_0) => {
+ v.visit_item_union_mut(_binding_0);
+ }
+ crate::Item::Use(_binding_0) => {
+ v.visit_item_use_mut(_binding_0);
+ }
+ crate::Item::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_const_mut<V>(v: &mut V, node: &mut crate::ItemConst)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.const_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ skip!(node.colon_token);
+ v.visit_type_mut(&mut *node.ty);
+ skip!(node.eq_token);
+ v.visit_expr_mut(&mut *node.expr);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_enum_mut<V>(v: &mut V, node: &mut crate::ItemEnum)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.enum_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ skip!(node.brace_token);
+ for mut el in Punctuated::pairs_mut(&mut node.variants) {
+ let it = el.value_mut();
+ v.visit_variant_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_extern_crate_mut<V>(v: &mut V, node: &mut crate::ItemExternCrate)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.extern_token);
+ skip!(node.crate_token);
+ v.visit_ident_mut(&mut node.ident);
+ if let Some(it) = &mut node.rename {
+ skip!((it).0);
+ v.visit_ident_mut(&mut (it).1);
+ }
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_fn_mut<V>(v: &mut V, node: &mut crate::ItemFn)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ v.visit_signature_mut(&mut node.sig);
+ v.visit_block_mut(&mut *node.block);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_foreign_mod_mut<V>(v: &mut V, node: &mut crate::ItemForeignMod)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.unsafety);
+ v.visit_abi_mut(&mut node.abi);
+ skip!(node.brace_token);
+ for it in &mut node.items {
+ v.visit_foreign_item_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_impl_mut<V>(v: &mut V, node: &mut crate::ItemImpl)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.defaultness);
+ skip!(node.unsafety);
+ skip!(node.impl_token);
+ v.visit_generics_mut(&mut node.generics);
+ if let Some(it) = &mut node.trait_ {
+ skip!((it).0);
+ v.visit_path_mut(&mut (it).1);
+ skip!((it).2);
+ }
+ v.visit_type_mut(&mut *node.self_ty);
+ skip!(node.brace_token);
+ for it in &mut node.items {
+ v.visit_impl_item_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_macro_mut<V>(v: &mut V, node: &mut crate::ItemMacro)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.ident {
+ v.visit_ident_mut(it);
+ }
+ v.visit_macro_mut(&mut node.mac);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_mod_mut<V>(v: &mut V, node: &mut crate::ItemMod)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.unsafety);
+ skip!(node.mod_token);
+ v.visit_ident_mut(&mut node.ident);
+ if let Some(it) = &mut node.content {
+ skip!((it).0);
+ for it in &mut (it).1 {
+ v.visit_item_mut(it);
+ }
+ }
+ skip!(node.semi);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_static_mut<V>(v: &mut V, node: &mut crate::ItemStatic)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.static_token);
+ v.visit_static_mutability_mut(&mut node.mutability);
+ v.visit_ident_mut(&mut node.ident);
+ skip!(node.colon_token);
+ v.visit_type_mut(&mut *node.ty);
+ skip!(node.eq_token);
+ v.visit_expr_mut(&mut *node.expr);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_struct_mut<V>(v: &mut V, node: &mut crate::ItemStruct)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.struct_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ v.visit_fields_mut(&mut node.fields);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_trait_mut<V>(v: &mut V, node: &mut crate::ItemTrait)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.unsafety);
+ skip!(node.auto_token);
+ if let Some(it) = &mut node.restriction {
+ v.visit_impl_restriction_mut(it);
+ }
+ skip!(node.trait_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ skip!(node.colon_token);
+ for mut el in Punctuated::pairs_mut(&mut node.supertraits) {
+ let it = el.value_mut();
+ v.visit_type_param_bound_mut(it);
+ }
+ skip!(node.brace_token);
+ for it in &mut node.items {
+ v.visit_trait_item_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_trait_alias_mut<V>(v: &mut V, node: &mut crate::ItemTraitAlias)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.trait_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ skip!(node.eq_token);
+ for mut el in Punctuated::pairs_mut(&mut node.bounds) {
+ let it = el.value_mut();
+ v.visit_type_param_bound_mut(it);
+ }
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_type_mut<V>(v: &mut V, node: &mut crate::ItemType)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.type_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ skip!(node.eq_token);
+ v.visit_type_mut(&mut *node.ty);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_union_mut<V>(v: &mut V, node: &mut crate::ItemUnion)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.union_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ v.visit_fields_named_mut(&mut node.fields);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_item_use_mut<V>(v: &mut V, node: &mut crate::ItemUse)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_visibility_mut(&mut node.vis);
+ skip!(node.use_token);
+ skip!(node.leading_colon);
+ v.visit_use_tree_mut(&mut node.tree);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_label_mut<V>(v: &mut V, node: &mut crate::Label)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_lifetime_mut(&mut node.name);
+ skip!(node.colon_token);
+}
+pub fn visit_lifetime_mut<V>(v: &mut V, node: &mut crate::Lifetime)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_span_mut(&mut node.apostrophe);
+ v.visit_ident_mut(&mut node.ident);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_lifetime_param_mut<V>(v: &mut V, node: &mut crate::LifetimeParam)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_lifetime_mut(&mut node.lifetime);
+ skip!(node.colon_token);
+ for mut el in Punctuated::pairs_mut(&mut node.bounds) {
+ let it = el.value_mut();
+ v.visit_lifetime_mut(it);
+ }
+}
+pub fn visit_lit_mut<V>(v: &mut V, node: &mut crate::Lit)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::Lit::Str(_binding_0) => {
+ v.visit_lit_str_mut(_binding_0);
+ }
+ crate::Lit::ByteStr(_binding_0) => {
+ v.visit_lit_byte_str_mut(_binding_0);
+ }
+ crate::Lit::CStr(_binding_0) => {
+ v.visit_lit_cstr_mut(_binding_0);
+ }
+ crate::Lit::Byte(_binding_0) => {
+ v.visit_lit_byte_mut(_binding_0);
+ }
+ crate::Lit::Char(_binding_0) => {
+ v.visit_lit_char_mut(_binding_0);
+ }
+ crate::Lit::Int(_binding_0) => {
+ v.visit_lit_int_mut(_binding_0);
+ }
+ crate::Lit::Float(_binding_0) => {
+ v.visit_lit_float_mut(_binding_0);
+ }
+ crate::Lit::Bool(_binding_0) => {
+ v.visit_lit_bool_mut(_binding_0);
+ }
+ crate::Lit::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+pub fn visit_lit_bool_mut<V>(v: &mut V, node: &mut crate::LitBool)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.value);
+ v.visit_span_mut(&mut node.span);
+}
+pub fn visit_lit_byte_mut<V>(v: &mut V, node: &mut crate::LitByte)
+where
+ V: VisitMut + ?Sized,
+{}
+pub fn visit_lit_byte_str_mut<V>(v: &mut V, node: &mut crate::LitByteStr)
+where
+ V: VisitMut + ?Sized,
+{}
+pub fn visit_lit_cstr_mut<V>(v: &mut V, node: &mut crate::LitCStr)
+where
+ V: VisitMut + ?Sized,
+{}
+pub fn visit_lit_char_mut<V>(v: &mut V, node: &mut crate::LitChar)
+where
+ V: VisitMut + ?Sized,
+{}
+pub fn visit_lit_float_mut<V>(v: &mut V, node: &mut crate::LitFloat)
+where
+ V: VisitMut + ?Sized,
+{}
+pub fn visit_lit_int_mut<V>(v: &mut V, node: &mut crate::LitInt)
+where
+ V: VisitMut + ?Sized,
+{}
+pub fn visit_lit_str_mut<V>(v: &mut V, node: &mut crate::LitStr)
+where
+ V: VisitMut + ?Sized,
+{}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_local_mut<V>(v: &mut V, node: &mut crate::Local)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.let_token);
+ v.visit_pat_mut(&mut node.pat);
+ if let Some(it) = &mut node.init {
+ v.visit_local_init_mut(it);
+ }
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_local_init_mut<V>(v: &mut V, node: &mut crate::LocalInit)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.eq_token);
+ v.visit_expr_mut(&mut *node.expr);
+ if let Some(it) = &mut node.diverge {
+ skip!((it).0);
+ v.visit_expr_mut(&mut *(it).1);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_macro_mut<V>(v: &mut V, node: &mut crate::Macro)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_path_mut(&mut node.path);
+ skip!(node.bang_token);
+ v.visit_macro_delimiter_mut(&mut node.delimiter);
+ skip!(node.tokens);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_macro_delimiter_mut<V>(v: &mut V, node: &mut crate::MacroDelimiter)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::MacroDelimiter::Paren(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::MacroDelimiter::Brace(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::MacroDelimiter::Bracket(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_member_mut<V>(v: &mut V, node: &mut crate::Member)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::Member::Named(_binding_0) => {
+ v.visit_ident_mut(_binding_0);
+ }
+ crate::Member::Unnamed(_binding_0) => {
+ v.visit_index_mut(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_meta_mut<V>(v: &mut V, node: &mut crate::Meta)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::Meta::Path(_binding_0) => {
+ v.visit_path_mut(_binding_0);
+ }
+ crate::Meta::List(_binding_0) => {
+ v.visit_meta_list_mut(_binding_0);
+ }
+ crate::Meta::NameValue(_binding_0) => {
+ v.visit_meta_name_value_mut(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_meta_list_mut<V>(v: &mut V, node: &mut crate::MetaList)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_path_mut(&mut node.path);
+ v.visit_macro_delimiter_mut(&mut node.delimiter);
+ skip!(node.tokens);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_meta_name_value_mut<V>(v: &mut V, node: &mut crate::MetaNameValue)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_path_mut(&mut node.path);
+ skip!(node.eq_token);
+ v.visit_expr_mut(&mut node.value);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_parenthesized_generic_arguments_mut<V>(
+ v: &mut V,
+ node: &mut crate::ParenthesizedGenericArguments,
+)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.paren_token);
+ for mut el in Punctuated::pairs_mut(&mut node.inputs) {
+ let it = el.value_mut();
+ v.visit_type_mut(it);
+ }
+ v.visit_return_type_mut(&mut node.output);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_mut<V>(v: &mut V, node: &mut crate::Pat)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::Pat::Const(_binding_0) => {
+ v.visit_expr_const_mut(_binding_0);
+ }
+ crate::Pat::Ident(_binding_0) => {
+ v.visit_pat_ident_mut(_binding_0);
+ }
+ crate::Pat::Lit(_binding_0) => {
+ v.visit_expr_lit_mut(_binding_0);
+ }
+ crate::Pat::Macro(_binding_0) => {
+ v.visit_expr_macro_mut(_binding_0);
+ }
+ crate::Pat::Or(_binding_0) => {
+ v.visit_pat_or_mut(_binding_0);
+ }
+ crate::Pat::Paren(_binding_0) => {
+ v.visit_pat_paren_mut(_binding_0);
+ }
+ crate::Pat::Path(_binding_0) => {
+ v.visit_expr_path_mut(_binding_0);
+ }
+ crate::Pat::Range(_binding_0) => {
+ v.visit_expr_range_mut(_binding_0);
+ }
+ crate::Pat::Reference(_binding_0) => {
+ v.visit_pat_reference_mut(_binding_0);
+ }
+ crate::Pat::Rest(_binding_0) => {
+ v.visit_pat_rest_mut(_binding_0);
+ }
+ crate::Pat::Slice(_binding_0) => {
+ v.visit_pat_slice_mut(_binding_0);
+ }
+ crate::Pat::Struct(_binding_0) => {
+ v.visit_pat_struct_mut(_binding_0);
+ }
+ crate::Pat::Tuple(_binding_0) => {
+ v.visit_pat_tuple_mut(_binding_0);
+ }
+ crate::Pat::TupleStruct(_binding_0) => {
+ v.visit_pat_tuple_struct_mut(_binding_0);
+ }
+ crate::Pat::Type(_binding_0) => {
+ v.visit_pat_type_mut(_binding_0);
+ }
+ crate::Pat::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::Pat::Wild(_binding_0) => {
+ v.visit_pat_wild_mut(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_ident_mut<V>(v: &mut V, node: &mut crate::PatIdent)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.by_ref);
+ skip!(node.mutability);
+ v.visit_ident_mut(&mut node.ident);
+ if let Some(it) = &mut node.subpat {
+ skip!((it).0);
+ v.visit_pat_mut(&mut *(it).1);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_or_mut<V>(v: &mut V, node: &mut crate::PatOr)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.leading_vert);
+ for mut el in Punctuated::pairs_mut(&mut node.cases) {
+ let it = el.value_mut();
+ v.visit_pat_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_paren_mut<V>(v: &mut V, node: &mut crate::PatParen)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.paren_token);
+ v.visit_pat_mut(&mut *node.pat);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_reference_mut<V>(v: &mut V, node: &mut crate::PatReference)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.and_token);
+ skip!(node.mutability);
+ v.visit_pat_mut(&mut *node.pat);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_rest_mut<V>(v: &mut V, node: &mut crate::PatRest)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.dot2_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_slice_mut<V>(v: &mut V, node: &mut crate::PatSlice)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.bracket_token);
+ for mut el in Punctuated::pairs_mut(&mut node.elems) {
+ let it = el.value_mut();
+ v.visit_pat_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_struct_mut<V>(v: &mut V, node: &mut crate::PatStruct)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.qself {
+ v.visit_qself_mut(it);
+ }
+ v.visit_path_mut(&mut node.path);
+ skip!(node.brace_token);
+ for mut el in Punctuated::pairs_mut(&mut node.fields) {
+ let it = el.value_mut();
+ v.visit_field_pat_mut(it);
+ }
+ if let Some(it) = &mut node.rest {
+ v.visit_pat_rest_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_tuple_mut<V>(v: &mut V, node: &mut crate::PatTuple)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.paren_token);
+ for mut el in Punctuated::pairs_mut(&mut node.elems) {
+ let it = el.value_mut();
+ v.visit_pat_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_tuple_struct_mut<V>(v: &mut V, node: &mut crate::PatTupleStruct)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.qself {
+ v.visit_qself_mut(it);
+ }
+ v.visit_path_mut(&mut node.path);
+ skip!(node.paren_token);
+ for mut el in Punctuated::pairs_mut(&mut node.elems) {
+ let it = el.value_mut();
+ v.visit_pat_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_type_mut<V>(v: &mut V, node: &mut crate::PatType)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_pat_mut(&mut *node.pat);
+ skip!(node.colon_token);
+ v.visit_type_mut(&mut *node.ty);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_pat_wild_mut<V>(v: &mut V, node: &mut crate::PatWild)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.underscore_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_path_mut<V>(v: &mut V, node: &mut crate::Path)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.leading_colon);
+ for mut el in Punctuated::pairs_mut(&mut node.segments) {
+ let it = el.value_mut();
+ v.visit_path_segment_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_path_arguments_mut<V>(v: &mut V, node: &mut crate::PathArguments)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::PathArguments::None => {}
+ crate::PathArguments::AngleBracketed(_binding_0) => {
+ v.visit_angle_bracketed_generic_arguments_mut(_binding_0);
+ }
+ crate::PathArguments::Parenthesized(_binding_0) => {
+ v.visit_parenthesized_generic_arguments_mut(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_path_segment_mut<V>(v: &mut V, node: &mut crate::PathSegment)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_path_arguments_mut(&mut node.arguments);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_predicate_lifetime_mut<V>(v: &mut V, node: &mut crate::PredicateLifetime)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_lifetime_mut(&mut node.lifetime);
+ skip!(node.colon_token);
+ for mut el in Punctuated::pairs_mut(&mut node.bounds) {
+ let it = el.value_mut();
+ v.visit_lifetime_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_predicate_type_mut<V>(v: &mut V, node: &mut crate::PredicateType)
+where
+ V: VisitMut + ?Sized,
+{
+ if let Some(it) = &mut node.lifetimes {
+ v.visit_bound_lifetimes_mut(it);
+ }
+ v.visit_type_mut(&mut node.bounded_ty);
+ skip!(node.colon_token);
+ for mut el in Punctuated::pairs_mut(&mut node.bounds) {
+ let it = el.value_mut();
+ v.visit_type_param_bound_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_qself_mut<V>(v: &mut V, node: &mut crate::QSelf)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.lt_token);
+ v.visit_type_mut(&mut *node.ty);
+ skip!(node.position);
+ skip!(node.as_token);
+ skip!(node.gt_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_range_limits_mut<V>(v: &mut V, node: &mut crate::RangeLimits)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::RangeLimits::HalfOpen(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::RangeLimits::Closed(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_receiver_mut<V>(v: &mut V, node: &mut crate::Receiver)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.reference {
+ skip!((it).0);
+ if let Some(it) = &mut (it).1 {
+ v.visit_lifetime_mut(it);
+ }
+ }
+ skip!(node.mutability);
+ skip!(node.self_token);
+ skip!(node.colon_token);
+ v.visit_type_mut(&mut *node.ty);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_return_type_mut<V>(v: &mut V, node: &mut crate::ReturnType)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::ReturnType::Default => {}
+ crate::ReturnType::Type(_binding_0, _binding_1) => {
+ skip!(_binding_0);
+ v.visit_type_mut(&mut **_binding_1);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_signature_mut<V>(v: &mut V, node: &mut crate::Signature)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.constness);
+ skip!(node.asyncness);
+ skip!(node.unsafety);
+ if let Some(it) = &mut node.abi {
+ v.visit_abi_mut(it);
+ }
+ skip!(node.fn_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ skip!(node.paren_token);
+ for mut el in Punctuated::pairs_mut(&mut node.inputs) {
+ let it = el.value_mut();
+ v.visit_fn_arg_mut(it);
+ }
+ if let Some(it) = &mut node.variadic {
+ v.visit_variadic_mut(it);
+ }
+ v.visit_return_type_mut(&mut node.output);
+}
+pub fn visit_span_mut<V>(v: &mut V, node: &mut proc_macro2::Span)
+where
+ V: VisitMut + ?Sized,
+{}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_static_mutability_mut<V>(v: &mut V, node: &mut crate::StaticMutability)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::StaticMutability::Mut(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::StaticMutability::None => {}
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_stmt_mut<V>(v: &mut V, node: &mut crate::Stmt)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::Stmt::Local(_binding_0) => {
+ v.visit_local_mut(_binding_0);
+ }
+ crate::Stmt::Item(_binding_0) => {
+ v.visit_item_mut(_binding_0);
+ }
+ crate::Stmt::Expr(_binding_0, _binding_1) => {
+ v.visit_expr_mut(_binding_0);
+ skip!(_binding_1);
+ }
+ crate::Stmt::Macro(_binding_0) => {
+ v.visit_stmt_macro_mut(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_stmt_macro_mut<V>(v: &mut V, node: &mut crate::StmtMacro)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_macro_mut(&mut node.mac);
+ skip!(node.semi_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_trait_bound_mut<V>(v: &mut V, node: &mut crate::TraitBound)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.paren_token);
+ v.visit_trait_bound_modifier_mut(&mut node.modifier);
+ if let Some(it) = &mut node.lifetimes {
+ v.visit_bound_lifetimes_mut(it);
+ }
+ v.visit_path_mut(&mut node.path);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_trait_bound_modifier_mut<V>(v: &mut V, node: &mut crate::TraitBoundModifier)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::TraitBoundModifier::None => {}
+ crate::TraitBoundModifier::Maybe(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_trait_item_mut<V>(v: &mut V, node: &mut crate::TraitItem)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::TraitItem::Const(_binding_0) => {
+ v.visit_trait_item_const_mut(_binding_0);
+ }
+ crate::TraitItem::Fn(_binding_0) => {
+ v.visit_trait_item_fn_mut(_binding_0);
+ }
+ crate::TraitItem::Type(_binding_0) => {
+ v.visit_trait_item_type_mut(_binding_0);
+ }
+ crate::TraitItem::Macro(_binding_0) => {
+ v.visit_trait_item_macro_mut(_binding_0);
+ }
+ crate::TraitItem::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_trait_item_const_mut<V>(v: &mut V, node: &mut crate::TraitItemConst)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.const_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ skip!(node.colon_token);
+ v.visit_type_mut(&mut node.ty);
+ if let Some(it) = &mut node.default {
+ skip!((it).0);
+ v.visit_expr_mut(&mut (it).1);
+ }
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_trait_item_fn_mut<V>(v: &mut V, node: &mut crate::TraitItemFn)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_signature_mut(&mut node.sig);
+ if let Some(it) = &mut node.default {
+ v.visit_block_mut(it);
+ }
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_trait_item_macro_mut<V>(v: &mut V, node: &mut crate::TraitItemMacro)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_macro_mut(&mut node.mac);
+ skip!(node.semi_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_trait_item_type_mut<V>(v: &mut V, node: &mut crate::TraitItemType)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ skip!(node.type_token);
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_generics_mut(&mut node.generics);
+ skip!(node.colon_token);
+ for mut el in Punctuated::pairs_mut(&mut node.bounds) {
+ let it = el.value_mut();
+ v.visit_type_param_bound_mut(it);
+ }
+ if let Some(it) = &mut node.default {
+ skip!((it).0);
+ v.visit_type_mut(&mut (it).1);
+ }
+ skip!(node.semi_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_mut<V>(v: &mut V, node: &mut crate::Type)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::Type::Array(_binding_0) => {
+ v.visit_type_array_mut(_binding_0);
+ }
+ crate::Type::BareFn(_binding_0) => {
+ v.visit_type_bare_fn_mut(_binding_0);
+ }
+ crate::Type::Group(_binding_0) => {
+ v.visit_type_group_mut(_binding_0);
+ }
+ crate::Type::ImplTrait(_binding_0) => {
+ v.visit_type_impl_trait_mut(_binding_0);
+ }
+ crate::Type::Infer(_binding_0) => {
+ v.visit_type_infer_mut(_binding_0);
+ }
+ crate::Type::Macro(_binding_0) => {
+ v.visit_type_macro_mut(_binding_0);
+ }
+ crate::Type::Never(_binding_0) => {
+ v.visit_type_never_mut(_binding_0);
+ }
+ crate::Type::Paren(_binding_0) => {
+ v.visit_type_paren_mut(_binding_0);
+ }
+ crate::Type::Path(_binding_0) => {
+ v.visit_type_path_mut(_binding_0);
+ }
+ crate::Type::Ptr(_binding_0) => {
+ v.visit_type_ptr_mut(_binding_0);
+ }
+ crate::Type::Reference(_binding_0) => {
+ v.visit_type_reference_mut(_binding_0);
+ }
+ crate::Type::Slice(_binding_0) => {
+ v.visit_type_slice_mut(_binding_0);
+ }
+ crate::Type::TraitObject(_binding_0) => {
+ v.visit_type_trait_object_mut(_binding_0);
+ }
+ crate::Type::Tuple(_binding_0) => {
+ v.visit_type_tuple_mut(_binding_0);
+ }
+ crate::Type::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_array_mut<V>(v: &mut V, node: &mut crate::TypeArray)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.bracket_token);
+ v.visit_type_mut(&mut *node.elem);
+ skip!(node.semi_token);
+ v.visit_expr_mut(&mut node.len);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_bare_fn_mut<V>(v: &mut V, node: &mut crate::TypeBareFn)
+where
+ V: VisitMut + ?Sized,
+{
+ if let Some(it) = &mut node.lifetimes {
+ v.visit_bound_lifetimes_mut(it);
+ }
+ skip!(node.unsafety);
+ if let Some(it) = &mut node.abi {
+ v.visit_abi_mut(it);
+ }
+ skip!(node.fn_token);
+ skip!(node.paren_token);
+ for mut el in Punctuated::pairs_mut(&mut node.inputs) {
+ let it = el.value_mut();
+ v.visit_bare_fn_arg_mut(it);
+ }
+ if let Some(it) = &mut node.variadic {
+ v.visit_bare_variadic_mut(it);
+ }
+ v.visit_return_type_mut(&mut node.output);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_group_mut<V>(v: &mut V, node: &mut crate::TypeGroup)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.group_token);
+ v.visit_type_mut(&mut *node.elem);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_impl_trait_mut<V>(v: &mut V, node: &mut crate::TypeImplTrait)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.impl_token);
+ for mut el in Punctuated::pairs_mut(&mut node.bounds) {
+ let it = el.value_mut();
+ v.visit_type_param_bound_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_infer_mut<V>(v: &mut V, node: &mut crate::TypeInfer)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.underscore_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_macro_mut<V>(v: &mut V, node: &mut crate::TypeMacro)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_macro_mut(&mut node.mac);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_never_mut<V>(v: &mut V, node: &mut crate::TypeNever)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.bang_token);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_param_mut<V>(v: &mut V, node: &mut crate::TypeParam)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_ident_mut(&mut node.ident);
+ skip!(node.colon_token);
+ for mut el in Punctuated::pairs_mut(&mut node.bounds) {
+ let it = el.value_mut();
+ v.visit_type_param_bound_mut(it);
+ }
+ skip!(node.eq_token);
+ if let Some(it) = &mut node.default {
+ v.visit_type_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_param_bound_mut<V>(v: &mut V, node: &mut crate::TypeParamBound)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::TypeParamBound::Trait(_binding_0) => {
+ v.visit_trait_bound_mut(_binding_0);
+ }
+ crate::TypeParamBound::Lifetime(_binding_0) => {
+ v.visit_lifetime_mut(_binding_0);
+ }
+ crate::TypeParamBound::Verbatim(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_paren_mut<V>(v: &mut V, node: &mut crate::TypeParen)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.paren_token);
+ v.visit_type_mut(&mut *node.elem);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_path_mut<V>(v: &mut V, node: &mut crate::TypePath)
+where
+ V: VisitMut + ?Sized,
+{
+ if let Some(it) = &mut node.qself {
+ v.visit_qself_mut(it);
+ }
+ v.visit_path_mut(&mut node.path);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_ptr_mut<V>(v: &mut V, node: &mut crate::TypePtr)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.star_token);
+ skip!(node.const_token);
+ skip!(node.mutability);
+ v.visit_type_mut(&mut *node.elem);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_reference_mut<V>(v: &mut V, node: &mut crate::TypeReference)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.and_token);
+ if let Some(it) = &mut node.lifetime {
+ v.visit_lifetime_mut(it);
+ }
+ skip!(node.mutability);
+ v.visit_type_mut(&mut *node.elem);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_slice_mut<V>(v: &mut V, node: &mut crate::TypeSlice)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.bracket_token);
+ v.visit_type_mut(&mut *node.elem);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_trait_object_mut<V>(v: &mut V, node: &mut crate::TypeTraitObject)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.dyn_token);
+ for mut el in Punctuated::pairs_mut(&mut node.bounds) {
+ let it = el.value_mut();
+ v.visit_type_param_bound_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_type_tuple_mut<V>(v: &mut V, node: &mut crate::TypeTuple)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.paren_token);
+ for mut el in Punctuated::pairs_mut(&mut node.elems) {
+ let it = el.value_mut();
+ v.visit_type_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_un_op_mut<V>(v: &mut V, node: &mut crate::UnOp)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::UnOp::Deref(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::UnOp::Not(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::UnOp::Neg(_binding_0) => {
+ skip!(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_use_glob_mut<V>(v: &mut V, node: &mut crate::UseGlob)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.star_token);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_use_group_mut<V>(v: &mut V, node: &mut crate::UseGroup)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.brace_token);
+ for mut el in Punctuated::pairs_mut(&mut node.items) {
+ let it = el.value_mut();
+ v.visit_use_tree_mut(it);
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_use_name_mut<V>(v: &mut V, node: &mut crate::UseName)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_ident_mut(&mut node.ident);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_use_path_mut<V>(v: &mut V, node: &mut crate::UsePath)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_ident_mut(&mut node.ident);
+ skip!(node.colon2_token);
+ v.visit_use_tree_mut(&mut *node.tree);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_use_rename_mut<V>(v: &mut V, node: &mut crate::UseRename)
+where
+ V: VisitMut + ?Sized,
+{
+ v.visit_ident_mut(&mut node.ident);
+ skip!(node.as_token);
+ v.visit_ident_mut(&mut node.rename);
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_use_tree_mut<V>(v: &mut V, node: &mut crate::UseTree)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::UseTree::Path(_binding_0) => {
+ v.visit_use_path_mut(_binding_0);
+ }
+ crate::UseTree::Name(_binding_0) => {
+ v.visit_use_name_mut(_binding_0);
+ }
+ crate::UseTree::Rename(_binding_0) => {
+ v.visit_use_rename_mut(_binding_0);
+ }
+ crate::UseTree::Glob(_binding_0) => {
+ v.visit_use_glob_mut(_binding_0);
+ }
+ crate::UseTree::Group(_binding_0) => {
+ v.visit_use_group_mut(_binding_0);
+ }
+ }
+}
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub fn visit_variadic_mut<V>(v: &mut V, node: &mut crate::Variadic)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ if let Some(it) = &mut node.pat {
+ v.visit_pat_mut(&mut *(it).0);
+ skip!((it).1);
+ }
+ skip!(node.dots);
+ skip!(node.comma);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_variant_mut<V>(v: &mut V, node: &mut crate::Variant)
+where
+ V: VisitMut + ?Sized,
+{
+ for it in &mut node.attrs {
+ v.visit_attribute_mut(it);
+ }
+ v.visit_ident_mut(&mut node.ident);
+ v.visit_fields_mut(&mut node.fields);
+ if let Some(it) = &mut node.discriminant {
+ skip!((it).0);
+ v.visit_expr_mut(&mut (it).1);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_vis_restricted_mut<V>(v: &mut V, node: &mut crate::VisRestricted)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.pub_token);
+ skip!(node.paren_token);
+ skip!(node.in_token);
+ v.visit_path_mut(&mut *node.path);
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_visibility_mut<V>(v: &mut V, node: &mut crate::Visibility)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::Visibility::Public(_binding_0) => {
+ skip!(_binding_0);
+ }
+ crate::Visibility::Restricted(_binding_0) => {
+ v.visit_vis_restricted_mut(_binding_0);
+ }
+ crate::Visibility::Inherited => {}
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_where_clause_mut<V>(v: &mut V, node: &mut crate::WhereClause)
+where
+ V: VisitMut + ?Sized,
+{
+ skip!(node.where_token);
+ for mut el in Punctuated::pairs_mut(&mut node.predicates) {
+ let it = el.value_mut();
+ v.visit_where_predicate_mut(it);
+ }
+}
+#[cfg(any(feature = "derive", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "derive", feature = "full"))))]
+pub fn visit_where_predicate_mut<V>(v: &mut V, node: &mut crate::WherePredicate)
+where
+ V: VisitMut + ?Sized,
+{
+ match node {
+ crate::WherePredicate::Lifetime(_binding_0) => {
+ v.visit_predicate_lifetime_mut(_binding_0);
+ }
+ crate::WherePredicate::Type(_binding_0) => {
+ v.visit_predicate_type_mut(_binding_0);
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/generics.rs b/rust/hw/char/pl011/vendor/syn/src/generics.rs
new file mode 100644
index 0000000000..c755151d4b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/generics.rs
@@ -0,0 +1,1286 @@
+use crate::attr::Attribute;
+use crate::expr::Expr;
+use crate::ident::Ident;
+use crate::lifetime::Lifetime;
+use crate::path::Path;
+use crate::punctuated::{Iter, IterMut, Punctuated};
+use crate::token;
+use crate::ty::Type;
+use proc_macro2::TokenStream;
+#[cfg(all(feature = "printing", feature = "extra-traits"))]
+use std::fmt::{self, Debug};
+#[cfg(all(feature = "printing", feature = "extra-traits"))]
+use std::hash::{Hash, Hasher};
+
+ast_struct! {
+ /// Lifetimes and type parameters attached to a declaration of a function,
+ /// enum, trait, etc.
+ ///
+ /// This struct represents two distinct optional syntactic elements,
+ /// [generic parameters] and [where clause]. In some locations of the
+ /// grammar, there may be other tokens in between these two things.
+ ///
+ /// [generic parameters]: https://doc.rust-lang.org/stable/reference/items/generics.html#generic-parameters
+ /// [where clause]: https://doc.rust-lang.org/stable/reference/items/generics.html#where-clauses
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct Generics {
+ pub lt_token: Option<Token![<]>,
+ pub params: Punctuated<GenericParam, Token![,]>,
+ pub gt_token: Option<Token![>]>,
+ pub where_clause: Option<WhereClause>,
+ }
+}
+
+ast_enum_of_structs! {
+ /// A generic type parameter, lifetime, or const generic: `T: Into<String>`,
+ /// `'a: 'b`, `const LEN: usize`.
+ ///
+ /// # 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 GenericParam {
+ /// A lifetime parameter: `'a: 'b + 'c + 'd`.
+ Lifetime(LifetimeParam),
+
+ /// A generic type parameter: `T: Into<String>`.
+ Type(TypeParam),
+
+ /// A const generic parameter: `const LENGTH: usize`.
+ Const(ConstParam),
+ }
+}
+
+ast_struct! {
+ /// A lifetime definition: `'a: 'b + 'c + 'd`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct LifetimeParam {
+ pub attrs: Vec<Attribute>,
+ pub lifetime: Lifetime,
+ pub colon_token: Option<Token![:]>,
+ pub bounds: Punctuated<Lifetime, Token![+]>,
+ }
+}
+
+ast_struct! {
+ /// A generic type parameter: `T: Into<String>`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeParam {
+ pub attrs: Vec<Attribute>,
+ pub ident: Ident,
+ pub colon_token: Option<Token![:]>,
+ pub bounds: Punctuated<TypeParamBound, Token![+]>,
+ pub eq_token: Option<Token![=]>,
+ pub default: Option<Type>,
+ }
+}
+
+ast_struct! {
+ /// A const generic parameter: `const LENGTH: usize`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ConstParam {
+ pub attrs: Vec<Attribute>,
+ pub const_token: Token![const],
+ pub ident: Ident,
+ pub colon_token: Token![:],
+ pub ty: Type,
+ pub eq_token: Option<Token![=]>,
+ pub default: Option<Expr>,
+ }
+}
+
+impl Default for Generics {
+ fn default() -> Self {
+ Generics {
+ lt_token: None,
+ params: Punctuated::new(),
+ gt_token: None,
+ where_clause: None,
+ }
+ }
+}
+
+impl Generics {
+ /// Returns an
+ /// <code
+ /// style="padding-right:0;">Iterator<Item = &</code><a
+ /// href="struct.LifetimeParam.html"><code
+ /// style="padding-left:0;padding-right:0;">LifetimeParam</code></a><code
+ /// style="padding-left:0;">></code>
+ /// over the lifetime parameters in `self.params`.
+ pub fn lifetimes(&self) -> Lifetimes {
+ Lifetimes(self.params.iter())
+ }
+
+ /// Returns an
+ /// <code
+ /// style="padding-right:0;">Iterator<Item = &mut </code><a
+ /// href="struct.LifetimeParam.html"><code
+ /// style="padding-left:0;padding-right:0;">LifetimeParam</code></a><code
+ /// style="padding-left:0;">></code>
+ /// over the lifetime parameters in `self.params`.
+ pub fn lifetimes_mut(&mut self) -> LifetimesMut {
+ LifetimesMut(self.params.iter_mut())
+ }
+
+ /// Returns an
+ /// <code
+ /// style="padding-right:0;">Iterator<Item = &</code><a
+ /// href="struct.TypeParam.html"><code
+ /// style="padding-left:0;padding-right:0;">TypeParam</code></a><code
+ /// style="padding-left:0;">></code>
+ /// over the type parameters in `self.params`.
+ pub fn type_params(&self) -> TypeParams {
+ TypeParams(self.params.iter())
+ }
+
+ /// Returns an
+ /// <code
+ /// style="padding-right:0;">Iterator<Item = &mut </code><a
+ /// href="struct.TypeParam.html"><code
+ /// style="padding-left:0;padding-right:0;">TypeParam</code></a><code
+ /// style="padding-left:0;">></code>
+ /// over the type parameters in `self.params`.
+ pub fn type_params_mut(&mut self) -> TypeParamsMut {
+ TypeParamsMut(self.params.iter_mut())
+ }
+
+ /// Returns an
+ /// <code
+ /// style="padding-right:0;">Iterator<Item = &</code><a
+ /// href="struct.ConstParam.html"><code
+ /// style="padding-left:0;padding-right:0;">ConstParam</code></a><code
+ /// style="padding-left:0;">></code>
+ /// over the constant parameters in `self.params`.
+ pub fn const_params(&self) -> ConstParams {
+ ConstParams(self.params.iter())
+ }
+
+ /// Returns an
+ /// <code
+ /// style="padding-right:0;">Iterator<Item = &mut </code><a
+ /// href="struct.ConstParam.html"><code
+ /// style="padding-left:0;padding-right:0;">ConstParam</code></a><code
+ /// style="padding-left:0;">></code>
+ /// over the constant parameters in `self.params`.
+ pub fn const_params_mut(&mut self) -> ConstParamsMut {
+ ConstParamsMut(self.params.iter_mut())
+ }
+
+ /// Initializes an empty `where`-clause if there is not one present already.
+ pub fn make_where_clause(&mut self) -> &mut WhereClause {
+ self.where_clause.get_or_insert_with(|| WhereClause {
+ where_token: <Token![where]>::default(),
+ predicates: Punctuated::new(),
+ })
+ }
+}
+
+pub struct Lifetimes<'a>(Iter<'a, GenericParam>);
+
+impl<'a> Iterator for Lifetimes<'a> {
+ type Item = &'a LifetimeParam;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let next = match self.0.next() {
+ Some(item) => item,
+ None => return None,
+ };
+ if let GenericParam::Lifetime(lifetime) = next {
+ Some(lifetime)
+ } else {
+ self.next()
+ }
+ }
+}
+
+pub struct LifetimesMut<'a>(IterMut<'a, GenericParam>);
+
+impl<'a> Iterator for LifetimesMut<'a> {
+ type Item = &'a mut LifetimeParam;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let next = match self.0.next() {
+ Some(item) => item,
+ None => return None,
+ };
+ if let GenericParam::Lifetime(lifetime) = next {
+ Some(lifetime)
+ } else {
+ self.next()
+ }
+ }
+}
+
+pub struct TypeParams<'a>(Iter<'a, GenericParam>);
+
+impl<'a> Iterator for TypeParams<'a> {
+ type Item = &'a TypeParam;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let next = match self.0.next() {
+ Some(item) => item,
+ None => return None,
+ };
+ if let GenericParam::Type(type_param) = next {
+ Some(type_param)
+ } else {
+ self.next()
+ }
+ }
+}
+
+pub struct TypeParamsMut<'a>(IterMut<'a, GenericParam>);
+
+impl<'a> Iterator for TypeParamsMut<'a> {
+ type Item = &'a mut TypeParam;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let next = match self.0.next() {
+ Some(item) => item,
+ None => return None,
+ };
+ if let GenericParam::Type(type_param) = next {
+ Some(type_param)
+ } else {
+ self.next()
+ }
+ }
+}
+
+pub struct ConstParams<'a>(Iter<'a, GenericParam>);
+
+impl<'a> Iterator for ConstParams<'a> {
+ type Item = &'a ConstParam;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let next = match self.0.next() {
+ Some(item) => item,
+ None => return None,
+ };
+ if let GenericParam::Const(const_param) = next {
+ Some(const_param)
+ } else {
+ self.next()
+ }
+ }
+}
+
+pub struct ConstParamsMut<'a>(IterMut<'a, GenericParam>);
+
+impl<'a> Iterator for ConstParamsMut<'a> {
+ type Item = &'a mut ConstParam;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let next = match self.0.next() {
+ Some(item) => item,
+ None => return None,
+ };
+ if let GenericParam::Const(const_param) = next {
+ Some(const_param)
+ } else {
+ self.next()
+ }
+ }
+}
+
+/// Returned by `Generics::split_for_impl`.
+#[cfg(feature = "printing")]
+#[cfg_attr(
+ docsrs,
+ doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+)]
+pub struct ImplGenerics<'a>(&'a Generics);
+
+/// Returned by `Generics::split_for_impl`.
+#[cfg(feature = "printing")]
+#[cfg_attr(
+ docsrs,
+ doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+)]
+pub struct TypeGenerics<'a>(&'a Generics);
+
+/// Returned by `TypeGenerics::as_turbofish`.
+#[cfg(feature = "printing")]
+#[cfg_attr(
+ docsrs,
+ doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+)]
+pub struct Turbofish<'a>(&'a Generics);
+
+#[cfg(feature = "printing")]
+impl Generics {
+ /// Split a type's generics into the pieces required for impl'ing a trait
+ /// for that type.
+ ///
+ /// ```
+ /// # use proc_macro2::{Span, Ident};
+ /// # use quote::quote;
+ /// #
+ /// # let generics: syn::Generics = Default::default();
+ /// # let name = Ident::new("MyType", Span::call_site());
+ /// #
+ /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+ /// quote! {
+ /// impl #impl_generics MyTrait for #name #ty_generics #where_clause {
+ /// // ...
+ /// }
+ /// }
+ /// # ;
+ /// ```
+ #[cfg_attr(
+ docsrs,
+ doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+ )]
+ pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>) {
+ (
+ ImplGenerics(self),
+ TypeGenerics(self),
+ self.where_clause.as_ref(),
+ )
+ }
+}
+
+#[cfg(feature = "printing")]
+macro_rules! generics_wrapper_impls {
+ ($ty:ident) => {
+ #[cfg(feature = "clone-impls")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+ impl<'a> Clone for $ty<'a> {
+ fn clone(&self) -> Self {
+ $ty(self.0)
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl<'a> Debug for $ty<'a> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_tuple(stringify!($ty))
+ .field(self.0)
+ .finish()
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl<'a> Eq for $ty<'a> {}
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl<'a> PartialEq for $ty<'a> {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl<'a> Hash for $ty<'a> {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.0.hash(state);
+ }
+ }
+ };
+}
+
+#[cfg(feature = "printing")]
+generics_wrapper_impls!(ImplGenerics);
+#[cfg(feature = "printing")]
+generics_wrapper_impls!(TypeGenerics);
+#[cfg(feature = "printing")]
+generics_wrapper_impls!(Turbofish);
+
+#[cfg(feature = "printing")]
+impl<'a> TypeGenerics<'a> {
+ /// Turn a type's generics like `<X, Y>` into a turbofish like `::<X, Y>`.
+ pub fn as_turbofish(&self) -> Turbofish {
+ Turbofish(self.0)
+ }
+}
+
+ast_struct! {
+ /// A set of bound lifetimes: `for<'a, 'b, 'c>`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct BoundLifetimes {
+ pub for_token: Token![for],
+ pub lt_token: Token![<],
+ pub lifetimes: Punctuated<GenericParam, Token![,]>,
+ pub gt_token: Token![>],
+ }
+}
+
+impl Default for BoundLifetimes {
+ fn default() -> Self {
+ BoundLifetimes {
+ for_token: Default::default(),
+ lt_token: Default::default(),
+ lifetimes: Punctuated::new(),
+ gt_token: Default::default(),
+ }
+ }
+}
+
+impl LifetimeParam {
+ pub fn new(lifetime: Lifetime) -> Self {
+ LifetimeParam {
+ attrs: Vec::new(),
+ lifetime,
+ colon_token: None,
+ bounds: Punctuated::new(),
+ }
+ }
+}
+
+impl From<Ident> for TypeParam {
+ fn from(ident: Ident) -> Self {
+ TypeParam {
+ attrs: vec![],
+ ident,
+ colon_token: None,
+ bounds: Punctuated::new(),
+ eq_token: None,
+ default: None,
+ }
+ }
+}
+
+ast_enum_of_structs! {
+ /// A trait or lifetime used as a bound on a type parameter.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ #[non_exhaustive]
+ pub enum TypeParamBound {
+ Trait(TraitBound),
+ Lifetime(Lifetime),
+ Verbatim(TokenStream),
+ }
+}
+
+ast_struct! {
+ /// A trait used as a bound on a type parameter.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TraitBound {
+ pub paren_token: Option<token::Paren>,
+ pub modifier: TraitBoundModifier,
+ /// The `for<'a>` in `for<'a> Foo<&'a T>`
+ pub lifetimes: Option<BoundLifetimes>,
+ /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
+ pub path: Path,
+ }
+}
+
+ast_enum! {
+ /// A modifier on a trait bound, currently only used for the `?` in
+ /// `?Sized`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub enum TraitBoundModifier {
+ None,
+ Maybe(Token![?]),
+ }
+}
+
+ast_struct! {
+ /// A `where` clause in a definition: `where T: Deserialize<'de>, D:
+ /// 'static`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct WhereClause {
+ pub where_token: Token![where],
+ pub predicates: Punctuated<WherePredicate, Token![,]>,
+ }
+}
+
+ast_enum_of_structs! {
+ /// A single predicate in a `where` clause: `T: Deserialize<'de>`.
+ ///
+ /// # 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"))))]
+ #[non_exhaustive]
+ pub enum WherePredicate {
+ /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
+ Lifetime(PredicateLifetime),
+
+ /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
+ Type(PredicateType),
+ }
+}
+
+ast_struct! {
+ /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct PredicateLifetime {
+ pub lifetime: Lifetime,
+ pub colon_token: Token![:],
+ pub bounds: Punctuated<Lifetime, Token![+]>,
+ }
+}
+
+ast_struct! {
+ /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct PredicateType {
+ /// Any lifetimes from a `for` binding
+ pub lifetimes: Option<BoundLifetimes>,
+ /// The type being bounded
+ pub bounded_ty: Type,
+ pub colon_token: Token![:],
+ /// Trait and lifetime bounds (`Clone+Send+'static`)
+ pub bounds: Punctuated<TypeParamBound, Token![+]>,
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::attr::Attribute;
+ use crate::error::Result;
+ use crate::ext::IdentExt as _;
+ use crate::generics::{
+ BoundLifetimes, ConstParam, GenericParam, Generics, LifetimeParam, PredicateLifetime,
+ PredicateType, TraitBound, TraitBoundModifier, TypeParam, TypeParamBound, WhereClause,
+ WherePredicate,
+ };
+ use crate::ident::Ident;
+ use crate::lifetime::Lifetime;
+ use crate::parse::{Parse, ParseStream};
+ use crate::path::{self, ParenthesizedGenericArguments, Path, PathArguments};
+ use crate::punctuated::Punctuated;
+ use crate::token;
+ use crate::ty::Type;
+ use crate::verbatim;
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Generics {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if !input.peek(Token![<]) {
+ return Ok(Generics::default());
+ }
+
+ let lt_token: Token![<] = input.parse()?;
+
+ let mut params = Punctuated::new();
+ loop {
+ if input.peek(Token![>]) {
+ break;
+ }
+
+ let attrs = input.call(Attribute::parse_outer)?;
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Lifetime) {
+ params.push_value(GenericParam::Lifetime(LifetimeParam {
+ attrs,
+ ..input.parse()?
+ }));
+ } else if lookahead.peek(Ident) {
+ params.push_value(GenericParam::Type(TypeParam {
+ attrs,
+ ..input.parse()?
+ }));
+ } else if lookahead.peek(Token![const]) {
+ params.push_value(GenericParam::Const(ConstParam {
+ attrs,
+ ..input.parse()?
+ }));
+ } else if input.peek(Token![_]) {
+ params.push_value(GenericParam::Type(TypeParam {
+ attrs,
+ ident: input.call(Ident::parse_any)?,
+ colon_token: None,
+ bounds: Punctuated::new(),
+ eq_token: None,
+ default: None,
+ }));
+ } else {
+ return Err(lookahead.error());
+ }
+
+ if input.peek(Token![>]) {
+ break;
+ }
+ let punct = input.parse()?;
+ params.push_punct(punct);
+ }
+
+ let gt_token: Token![>] = input.parse()?;
+
+ Ok(Generics {
+ lt_token: Some(lt_token),
+ params,
+ gt_token: Some(gt_token),
+ where_clause: None,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for GenericParam {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Ident) {
+ Ok(GenericParam::Type(TypeParam {
+ attrs,
+ ..input.parse()?
+ }))
+ } else if lookahead.peek(Lifetime) {
+ Ok(GenericParam::Lifetime(LifetimeParam {
+ attrs,
+ ..input.parse()?
+ }))
+ } else if lookahead.peek(Token![const]) {
+ Ok(GenericParam::Const(ConstParam {
+ attrs,
+ ..input.parse()?
+ }))
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for LifetimeParam {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let has_colon;
+ Ok(LifetimeParam {
+ attrs: input.call(Attribute::parse_outer)?,
+ lifetime: input.parse()?,
+ colon_token: {
+ if input.peek(Token![:]) {
+ has_colon = true;
+ Some(input.parse()?)
+ } else {
+ has_colon = false;
+ None
+ }
+ },
+ bounds: {
+ let mut bounds = Punctuated::new();
+ if has_colon {
+ loop {
+ if input.peek(Token![,]) || input.peek(Token![>]) {
+ break;
+ }
+ let value = input.parse()?;
+ bounds.push_value(value);
+ if !input.peek(Token![+]) {
+ break;
+ }
+ let punct = input.parse()?;
+ bounds.push_punct(punct);
+ }
+ }
+ bounds
+ },
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for BoundLifetimes {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(BoundLifetimes {
+ for_token: input.parse()?,
+ lt_token: input.parse()?,
+ lifetimes: {
+ let mut lifetimes = Punctuated::new();
+ while !input.peek(Token![>]) {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let lifetime: Lifetime = input.parse()?;
+ lifetimes.push_value(GenericParam::Lifetime(LifetimeParam {
+ attrs,
+ lifetime,
+ colon_token: None,
+ bounds: Punctuated::new(),
+ }));
+ if input.peek(Token![>]) {
+ break;
+ }
+ lifetimes.push_punct(input.parse()?);
+ }
+ lifetimes
+ },
+ gt_token: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Option<BoundLifetimes> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![for]) {
+ input.parse().map(Some)
+ } else {
+ Ok(None)
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeParam {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let ident: Ident = input.parse()?;
+ let colon_token: Option<Token![:]> = input.parse()?;
+
+ let mut bounds = Punctuated::new();
+ if colon_token.is_some() {
+ loop {
+ if input.peek(Token![,]) || input.peek(Token![>]) || input.peek(Token![=]) {
+ break;
+ }
+ let value: TypeParamBound = input.parse()?;
+ bounds.push_value(value);
+ if !input.peek(Token![+]) {
+ break;
+ }
+ let punct: Token![+] = input.parse()?;
+ bounds.push_punct(punct);
+ }
+ }
+
+ let eq_token: Option<Token![=]> = input.parse()?;
+ let default = if eq_token.is_some() {
+ Some(input.parse::<Type>()?)
+ } else {
+ None
+ };
+
+ Ok(TypeParam {
+ attrs,
+ ident,
+ colon_token,
+ bounds,
+ eq_token,
+ default,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeParamBound {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Lifetime) {
+ return input.parse().map(TypeParamBound::Lifetime);
+ }
+
+ let begin = input.fork();
+
+ let content;
+ let (paren_token, content) = if input.peek(token::Paren) {
+ (Some(parenthesized!(content in input)), &content)
+ } else {
+ (None, input)
+ };
+
+ let is_tilde_const =
+ cfg!(feature = "full") && content.peek(Token![~]) && content.peek2(Token![const]);
+ if is_tilde_const {
+ content.parse::<Token![~]>()?;
+ content.parse::<Token![const]>()?;
+ }
+
+ let mut bound: TraitBound = content.parse()?;
+ bound.paren_token = paren_token;
+
+ if is_tilde_const {
+ Ok(TypeParamBound::Verbatim(verbatim::between(&begin, input)))
+ } else {
+ Ok(TypeParamBound::Trait(bound))
+ }
+ }
+ }
+
+ impl TypeParamBound {
+ pub(crate) fn parse_multiple(
+ input: ParseStream,
+ allow_plus: bool,
+ ) -> Result<Punctuated<Self, Token![+]>> {
+ let mut bounds = Punctuated::new();
+ loop {
+ bounds.push_value(input.parse()?);
+ if !(allow_plus && input.peek(Token![+])) {
+ break;
+ }
+ bounds.push_punct(input.parse()?);
+ if !(input.peek(Ident::peek_any)
+ || input.peek(Token![::])
+ || input.peek(Token![?])
+ || input.peek(Lifetime)
+ || input.peek(token::Paren)
+ || input.peek(Token![~]))
+ {
+ break;
+ }
+ }
+ Ok(bounds)
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TraitBound {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let modifier: TraitBoundModifier = input.parse()?;
+ let lifetimes: Option<BoundLifetimes> = input.parse()?;
+
+ let mut path: Path = input.parse()?;
+ if path.segments.last().unwrap().arguments.is_empty()
+ && (input.peek(token::Paren) || input.peek(Token![::]) && input.peek3(token::Paren))
+ {
+ input.parse::<Option<Token![::]>>()?;
+ let args: ParenthesizedGenericArguments = input.parse()?;
+ let parenthesized = PathArguments::Parenthesized(args);
+ path.segments.last_mut().unwrap().arguments = parenthesized;
+ }
+
+ Ok(TraitBound {
+ paren_token: None,
+ modifier,
+ lifetimes,
+ path,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TraitBoundModifier {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![?]) {
+ input.parse().map(TraitBoundModifier::Maybe)
+ } else {
+ Ok(TraitBoundModifier::None)
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ConstParam {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut default = None;
+ Ok(ConstParam {
+ attrs: input.call(Attribute::parse_outer)?,
+ const_token: input.parse()?,
+ ident: input.parse()?,
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ eq_token: {
+ if input.peek(Token![=]) {
+ let eq_token = input.parse()?;
+ default = Some(path::parsing::const_argument(input)?);
+ Some(eq_token)
+ } else {
+ None
+ }
+ },
+ default,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for WhereClause {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(WhereClause {
+ where_token: input.parse()?,
+ predicates: {
+ let mut predicates = Punctuated::new();
+ loop {
+ if input.is_empty()
+ || input.peek(token::Brace)
+ || input.peek(Token![,])
+ || input.peek(Token![;])
+ || input.peek(Token![:]) && !input.peek(Token![::])
+ || input.peek(Token![=])
+ {
+ break;
+ }
+ let value = input.parse()?;
+ predicates.push_value(value);
+ if !input.peek(Token![,]) {
+ break;
+ }
+ let punct = input.parse()?;
+ predicates.push_punct(punct);
+ }
+ predicates
+ },
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Option<WhereClause> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![where]) {
+ input.parse().map(Some)
+ } else {
+ Ok(None)
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for WherePredicate {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Lifetime) && input.peek2(Token![:]) {
+ Ok(WherePredicate::Lifetime(PredicateLifetime {
+ lifetime: input.parse()?,
+ colon_token: input.parse()?,
+ bounds: {
+ let mut bounds = Punctuated::new();
+ loop {
+ if input.is_empty()
+ || input.peek(token::Brace)
+ || input.peek(Token![,])
+ || input.peek(Token![;])
+ || input.peek(Token![:])
+ || input.peek(Token![=])
+ {
+ break;
+ }
+ let value = input.parse()?;
+ bounds.push_value(value);
+ if !input.peek(Token![+]) {
+ break;
+ }
+ let punct = input.parse()?;
+ bounds.push_punct(punct);
+ }
+ bounds
+ },
+ }))
+ } else {
+ Ok(WherePredicate::Type(PredicateType {
+ lifetimes: input.parse()?,
+ bounded_ty: input.parse()?,
+ colon_token: input.parse()?,
+ bounds: {
+ let mut bounds = Punctuated::new();
+ loop {
+ if input.is_empty()
+ || input.peek(token::Brace)
+ || input.peek(Token![,])
+ || input.peek(Token![;])
+ || input.peek(Token![:]) && !input.peek(Token![::])
+ || input.peek(Token![=])
+ {
+ break;
+ }
+ let value = input.parse()?;
+ bounds.push_value(value);
+ if !input.peek(Token![+]) {
+ break;
+ }
+ let punct = input.parse()?;
+ bounds.push_punct(punct);
+ }
+ bounds
+ },
+ }))
+ }
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+pub(crate) mod printing {
+ use crate::attr::FilterAttrs;
+ #[cfg(feature = "full")]
+ use crate::expr;
+ use crate::expr::Expr;
+ #[cfg(feature = "full")]
+ use crate::fixup::FixupContext;
+ use crate::generics::{
+ BoundLifetimes, ConstParam, GenericParam, Generics, ImplGenerics, LifetimeParam,
+ PredicateLifetime, PredicateType, TraitBound, TraitBoundModifier, Turbofish, TypeGenerics,
+ TypeParam, WhereClause,
+ };
+ use crate::print::TokensOrDefault;
+ use crate::token;
+ use proc_macro2::TokenStream;
+ use quote::{ToTokens, TokenStreamExt};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Generics {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ if self.params.is_empty() {
+ return;
+ }
+
+ TokensOrDefault(&self.lt_token).to_tokens(tokens);
+
+ // Print lifetimes before types and consts, regardless of their
+ // order in self.params.
+ let mut trailing_or_empty = true;
+ for param in self.params.pairs() {
+ if let GenericParam::Lifetime(_) = **param.value() {
+ param.to_tokens(tokens);
+ trailing_or_empty = param.punct().is_some();
+ }
+ }
+ for param in self.params.pairs() {
+ match param.value() {
+ GenericParam::Type(_) | GenericParam::Const(_) => {
+ if !trailing_or_empty {
+ <Token![,]>::default().to_tokens(tokens);
+ trailing_or_empty = true;
+ }
+ param.to_tokens(tokens);
+ }
+ GenericParam::Lifetime(_) => {}
+ }
+ }
+
+ TokensOrDefault(&self.gt_token).to_tokens(tokens);
+ }
+ }
+
+ impl<'a> ToTokens for ImplGenerics<'a> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ if self.0.params.is_empty() {
+ return;
+ }
+
+ TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
+
+ // Print lifetimes before types and consts, regardless of their
+ // order in self.params.
+ let mut trailing_or_empty = true;
+ for param in self.0.params.pairs() {
+ if let GenericParam::Lifetime(_) = **param.value() {
+ param.to_tokens(tokens);
+ trailing_or_empty = param.punct().is_some();
+ }
+ }
+ for param in self.0.params.pairs() {
+ if let GenericParam::Lifetime(_) = **param.value() {
+ continue;
+ }
+ if !trailing_or_empty {
+ <Token![,]>::default().to_tokens(tokens);
+ trailing_or_empty = true;
+ }
+ match param.value() {
+ GenericParam::Lifetime(_) => unreachable!(),
+ GenericParam::Type(param) => {
+ // Leave off the type parameter defaults
+ tokens.append_all(param.attrs.outer());
+ param.ident.to_tokens(tokens);
+ if !param.bounds.is_empty() {
+ TokensOrDefault(¶m.colon_token).to_tokens(tokens);
+ param.bounds.to_tokens(tokens);
+ }
+ }
+ GenericParam::Const(param) => {
+ // Leave off the const parameter defaults
+ tokens.append_all(param.attrs.outer());
+ param.const_token.to_tokens(tokens);
+ param.ident.to_tokens(tokens);
+ param.colon_token.to_tokens(tokens);
+ param.ty.to_tokens(tokens);
+ }
+ }
+ param.punct().to_tokens(tokens);
+ }
+
+ TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
+ }
+ }
+
+ impl<'a> ToTokens for TypeGenerics<'a> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ if self.0.params.is_empty() {
+ return;
+ }
+
+ TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
+
+ // Print lifetimes before types and consts, regardless of their
+ // order in self.params.
+ let mut trailing_or_empty = true;
+ for param in self.0.params.pairs() {
+ if let GenericParam::Lifetime(def) = *param.value() {
+ // Leave off the lifetime bounds and attributes
+ def.lifetime.to_tokens(tokens);
+ param.punct().to_tokens(tokens);
+ trailing_or_empty = param.punct().is_some();
+ }
+ }
+ for param in self.0.params.pairs() {
+ if let GenericParam::Lifetime(_) = **param.value() {
+ continue;
+ }
+ if !trailing_or_empty {
+ <Token![,]>::default().to_tokens(tokens);
+ trailing_or_empty = true;
+ }
+ match param.value() {
+ GenericParam::Lifetime(_) => unreachable!(),
+ GenericParam::Type(param) => {
+ // Leave off the type parameter defaults
+ param.ident.to_tokens(tokens);
+ }
+ GenericParam::Const(param) => {
+ // Leave off the const parameter defaults
+ param.ident.to_tokens(tokens);
+ }
+ }
+ param.punct().to_tokens(tokens);
+ }
+
+ TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
+ }
+ }
+
+ impl<'a> ToTokens for Turbofish<'a> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ if !self.0.params.is_empty() {
+ <Token![::]>::default().to_tokens(tokens);
+ TypeGenerics(self.0).to_tokens(tokens);
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for BoundLifetimes {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.for_token.to_tokens(tokens);
+ self.lt_token.to_tokens(tokens);
+ self.lifetimes.to_tokens(tokens);
+ self.gt_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for LifetimeParam {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.lifetime.to_tokens(tokens);
+ if !self.bounds.is_empty() {
+ TokensOrDefault(&self.colon_token).to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeParam {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.ident.to_tokens(tokens);
+ if !self.bounds.is_empty() {
+ TokensOrDefault(&self.colon_token).to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ }
+ if let Some(default) = &self.default {
+ TokensOrDefault(&self.eq_token).to_tokens(tokens);
+ default.to_tokens(tokens);
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TraitBound {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let to_tokens = |tokens: &mut TokenStream| {
+ self.modifier.to_tokens(tokens);
+ self.lifetimes.to_tokens(tokens);
+ self.path.to_tokens(tokens);
+ };
+ match &self.paren_token {
+ Some(paren) => paren.surround(tokens, to_tokens),
+ None => to_tokens(tokens),
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TraitBoundModifier {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ TraitBoundModifier::None => {}
+ TraitBoundModifier::Maybe(t) => t.to_tokens(tokens),
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ConstParam {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.const_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ if let Some(default) = &self.default {
+ TokensOrDefault(&self.eq_token).to_tokens(tokens);
+ print_const_argument(default, tokens);
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for WhereClause {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ if !self.predicates.is_empty() {
+ self.where_token.to_tokens(tokens);
+ self.predicates.to_tokens(tokens);
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PredicateLifetime {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.lifetime.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PredicateType {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.lifetimes.to_tokens(tokens);
+ self.bounded_ty.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ }
+ }
+
+ pub(crate) fn print_const_argument(expr: &Expr, tokens: &mut TokenStream) {
+ match expr {
+ Expr::Lit(expr) => expr.to_tokens(tokens),
+
+ Expr::Path(expr)
+ if expr.attrs.is_empty()
+ && expr.qself.is_none()
+ && expr.path.get_ident().is_some() =>
+ {
+ expr.to_tokens(tokens);
+ }
+
+ #[cfg(feature = "full")]
+ Expr::Block(expr) => expr.to_tokens(tokens),
+
+ #[cfg(not(feature = "full"))]
+ Expr::Verbatim(expr) => expr.to_tokens(tokens),
+
+ // ERROR CORRECTION: Add braces to make sure that the
+ // generated code is valid.
+ _ => token::Brace::default().surround(tokens, |tokens| {
+ #[cfg(feature = "full")]
+ expr::printing::print_expr(expr, tokens, FixupContext::new_stmt());
+
+ #[cfg(not(feature = "full"))]
+ expr.to_tokens(tokens);
+ }),
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/group.rs b/rust/hw/char/pl011/vendor/syn/src/group.rs
new file mode 100644
index 0000000000..b742927eef
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/group.rs
@@ -0,0 +1,291 @@
+use crate::error::Result;
+use crate::parse::ParseBuffer;
+use crate::token;
+use proc_macro2::extra::DelimSpan;
+use proc_macro2::Delimiter;
+
+// Not public API.
+#[doc(hidden)]
+pub struct Parens<'a> {
+ #[doc(hidden)]
+ pub token: token::Paren,
+ #[doc(hidden)]
+ pub content: ParseBuffer<'a>,
+}
+
+// Not public API.
+#[doc(hidden)]
+pub struct Braces<'a> {
+ #[doc(hidden)]
+ pub token: token::Brace,
+ #[doc(hidden)]
+ pub content: ParseBuffer<'a>,
+}
+
+// Not public API.
+#[doc(hidden)]
+pub struct Brackets<'a> {
+ #[doc(hidden)]
+ pub token: token::Bracket,
+ #[doc(hidden)]
+ pub content: ParseBuffer<'a>,
+}
+
+// Not public API.
+#[cfg(any(feature = "full", feature = "derive"))]
+#[doc(hidden)]
+pub struct Group<'a> {
+ #[doc(hidden)]
+ pub token: token::Group,
+ #[doc(hidden)]
+ pub content: ParseBuffer<'a>,
+}
+
+// Not public API.
+#[doc(hidden)]
+pub fn parse_parens<'a>(input: &ParseBuffer<'a>) -> Result<Parens<'a>> {
+ parse_delimited(input, Delimiter::Parenthesis).map(|(span, content)| Parens {
+ token: token::Paren(span),
+ content,
+ })
+}
+
+// Not public API.
+#[doc(hidden)]
+pub fn parse_braces<'a>(input: &ParseBuffer<'a>) -> Result<Braces<'a>> {
+ parse_delimited(input, Delimiter::Brace).map(|(span, content)| Braces {
+ token: token::Brace(span),
+ content,
+ })
+}
+
+// Not public API.
+#[doc(hidden)]
+pub fn parse_brackets<'a>(input: &ParseBuffer<'a>) -> Result<Brackets<'a>> {
+ parse_delimited(input, Delimiter::Bracket).map(|(span, content)| Brackets {
+ token: token::Bracket(span),
+ content,
+ })
+}
+
+#[cfg(any(feature = "full", feature = "derive"))]
+pub(crate) fn parse_group<'a>(input: &ParseBuffer<'a>) -> Result<Group<'a>> {
+ parse_delimited(input, Delimiter::None).map(|(span, content)| Group {
+ token: token::Group(span.join()),
+ content,
+ })
+}
+
+fn parse_delimited<'a>(
+ input: &ParseBuffer<'a>,
+ delimiter: Delimiter,
+) -> Result<(DelimSpan, ParseBuffer<'a>)> {
+ input.step(|cursor| {
+ if let Some((content, span, rest)) = cursor.group(delimiter) {
+ let scope = crate::buffer::close_span_of_group(*cursor);
+ let nested = crate::parse::advance_step_cursor(cursor, content);
+ let unexpected = crate::parse::get_unexpected(input);
+ let content = crate::parse::new_parse_buffer(scope, nested, unexpected);
+ Ok(((span, content), rest))
+ } else {
+ let message = match delimiter {
+ Delimiter::Parenthesis => "expected parentheses",
+ Delimiter::Brace => "expected curly braces",
+ Delimiter::Bracket => "expected square brackets",
+ Delimiter::None => "expected invisible group",
+ };
+ Err(cursor.error(message))
+ }
+ })
+}
+
+/// Parse a set of parentheses and expose their content to subsequent parsers.
+///
+/// # Example
+///
+/// ```
+/// # use quote::quote;
+/// #
+/// use syn::{parenthesized, token, Ident, Result, Token, Type};
+/// use syn::parse::{Parse, ParseStream};
+/// use syn::punctuated::Punctuated;
+///
+/// // Parse a simplified tuple struct syntax like:
+/// //
+/// // struct S(A, B);
+/// struct TupleStruct {
+/// struct_token: Token![struct],
+/// ident: Ident,
+/// paren_token: token::Paren,
+/// fields: Punctuated<Type, Token![,]>,
+/// semi_token: Token![;],
+/// }
+///
+/// impl Parse for TupleStruct {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// let content;
+/// Ok(TupleStruct {
+/// struct_token: input.parse()?,
+/// ident: input.parse()?,
+/// paren_token: parenthesized!(content in input),
+/// fields: content.parse_terminated(Type::parse, Token![,])?,
+/// semi_token: input.parse()?,
+/// })
+/// }
+/// }
+/// #
+/// # fn main() {
+/// # let input = quote! {
+/// # struct S(A, B);
+/// # };
+/// # syn::parse2::<TupleStruct>(input).unwrap();
+/// # }
+/// ```
+#[macro_export]
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+macro_rules! parenthesized {
+ ($content:ident in $cursor:expr) => {
+ match $crate::__private::parse_parens(&$cursor) {
+ $crate::__private::Ok(parens) => {
+ $content = parens.content;
+ parens.token
+ }
+ $crate::__private::Err(error) => {
+ return $crate::__private::Err(error);
+ }
+ }
+ };
+}
+
+/// Parse a set of curly braces and expose their content to subsequent parsers.
+///
+/// # Example
+///
+/// ```
+/// # use quote::quote;
+/// #
+/// use syn::{braced, token, Ident, Result, Token, Type};
+/// use syn::parse::{Parse, ParseStream};
+/// use syn::punctuated::Punctuated;
+///
+/// // Parse a simplified struct syntax like:
+/// //
+/// // struct S {
+/// // a: A,
+/// // b: B,
+/// // }
+/// struct Struct {
+/// struct_token: Token![struct],
+/// ident: Ident,
+/// brace_token: token::Brace,
+/// fields: Punctuated<Field, Token![,]>,
+/// }
+///
+/// struct Field {
+/// name: Ident,
+/// colon_token: Token![:],
+/// ty: Type,
+/// }
+///
+/// impl Parse for Struct {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// let content;
+/// Ok(Struct {
+/// struct_token: input.parse()?,
+/// ident: input.parse()?,
+/// brace_token: braced!(content in input),
+/// fields: content.parse_terminated(Field::parse, Token![,])?,
+/// })
+/// }
+/// }
+///
+/// impl Parse for Field {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// Ok(Field {
+/// name: input.parse()?,
+/// colon_token: input.parse()?,
+/// ty: input.parse()?,
+/// })
+/// }
+/// }
+/// #
+/// # fn main() {
+/// # let input = quote! {
+/// # struct S {
+/// # a: A,
+/// # b: B,
+/// # }
+/// # };
+/// # syn::parse2::<Struct>(input).unwrap();
+/// # }
+/// ```
+#[macro_export]
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+macro_rules! braced {
+ ($content:ident in $cursor:expr) => {
+ match $crate::__private::parse_braces(&$cursor) {
+ $crate::__private::Ok(braces) => {
+ $content = braces.content;
+ braces.token
+ }
+ $crate::__private::Err(error) => {
+ return $crate::__private::Err(error);
+ }
+ }
+ };
+}
+
+/// Parse a set of square brackets and expose their content to subsequent
+/// parsers.
+///
+/// # Example
+///
+/// ```
+/// # use quote::quote;
+/// #
+/// use proc_macro2::TokenStream;
+/// use syn::{bracketed, token, Result, Token};
+/// use syn::parse::{Parse, ParseStream};
+///
+/// // Parse an outer attribute like:
+/// //
+/// // #[repr(C, packed)]
+/// struct OuterAttribute {
+/// pound_token: Token![#],
+/// bracket_token: token::Bracket,
+/// content: TokenStream,
+/// }
+///
+/// impl Parse for OuterAttribute {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// let content;
+/// Ok(OuterAttribute {
+/// pound_token: input.parse()?,
+/// bracket_token: bracketed!(content in input),
+/// content: content.parse()?,
+/// })
+/// }
+/// }
+/// #
+/// # fn main() {
+/// # let input = quote! {
+/// # #[repr(C, packed)]
+/// # };
+/// # syn::parse2::<OuterAttribute>(input).unwrap();
+/// # }
+/// ```
+#[macro_export]
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+macro_rules! bracketed {
+ ($content:ident in $cursor:expr) => {
+ match $crate::__private::parse_brackets(&$cursor) {
+ $crate::__private::Ok(brackets) => {
+ $content = brackets.content;
+ brackets.token
+ }
+ $crate::__private::Err(error) => {
+ return $crate::__private::Err(error);
+ }
+ }
+ };
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/ident.rs b/rust/hw/char/pl011/vendor/syn/src/ident.rs
new file mode 100644
index 0000000000..8a8e8a50d9
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/ident.rs
@@ -0,0 +1,108 @@
+#[cfg(feature = "parsing")]
+use crate::lookahead;
+
+pub use proc_macro2::Ident;
+
+#[cfg(feature = "parsing")]
+pub_if_not_doc! {
+ #[doc(hidden)]
+ #[allow(non_snake_case)]
+ pub fn Ident(marker: lookahead::TokenMarker) -> Ident {
+ match marker {}
+ }
+}
+
+macro_rules! ident_from_token {
+ ($token:ident) => {
+ impl From<Token![$token]> for Ident {
+ fn from(token: Token![$token]) -> Ident {
+ Ident::new(stringify!($token), token.span)
+ }
+ }
+ };
+}
+
+ident_from_token!(self);
+ident_from_token!(Self);
+ident_from_token!(super);
+ident_from_token!(crate);
+ident_from_token!(extern);
+
+impl From<Token![_]> for Ident {
+ fn from(token: Token![_]) -> Ident {
+ Ident::new("_", token.span)
+ }
+}
+
+pub(crate) fn xid_ok(symbol: &str) -> bool {
+ let mut chars = symbol.chars();
+ let first = chars.next().unwrap();
+ if !(first == '_' || unicode_ident::is_xid_start(first)) {
+ return false;
+ }
+ for ch in chars {
+ if !unicode_ident::is_xid_continue(ch) {
+ return false;
+ }
+ }
+ true
+}
+
+#[cfg(feature = "parsing")]
+mod parsing {
+ use crate::buffer::Cursor;
+ use crate::error::Result;
+ use crate::parse::{Parse, ParseStream};
+ use crate::token::Token;
+ use proc_macro2::Ident;
+
+ fn accept_as_ident(ident: &Ident) -> bool {
+ match ident.to_string().as_str() {
+ "_" |
+ // Based on https://doc.rust-lang.org/1.65.0/reference/keywords.html
+ "abstract" | "as" | "async" | "await" | "become" | "box" | "break" |
+ "const" | "continue" | "crate" | "do" | "dyn" | "else" | "enum" |
+ "extern" | "false" | "final" | "fn" | "for" | "if" | "impl" | "in" |
+ "let" | "loop" | "macro" | "match" | "mod" | "move" | "mut" |
+ "override" | "priv" | "pub" | "ref" | "return" | "Self" | "self" |
+ "static" | "struct" | "super" | "trait" | "true" | "try" | "type" |
+ "typeof" | "unsafe" | "unsized" | "use" | "virtual" | "where" |
+ "while" | "yield" => false,
+ _ => true,
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Ident {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| {
+ if let Some((ident, rest)) = cursor.ident() {
+ if accept_as_ident(&ident) {
+ Ok((ident, rest))
+ } else {
+ Err(cursor.error(format_args!(
+ "expected identifier, found keyword `{}`",
+ ident,
+ )))
+ }
+ } else {
+ Err(cursor.error("expected identifier"))
+ }
+ })
+ }
+ }
+
+ impl Token for Ident {
+ fn peek(cursor: Cursor) -> bool {
+ if let Some((ident, _rest)) = cursor.ident() {
+ accept_as_ident(&ident)
+ } else {
+ false
+ }
+ }
+
+ fn display() -> &'static str {
+ "identifier"
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/item.rs b/rust/hw/char/pl011/vendor/syn/src/item.rs
new file mode 100644
index 0000000000..fa87b42b96
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/item.rs
@@ -0,0 +1,3441 @@
+use crate::attr::Attribute;
+use crate::data::{Fields, FieldsNamed, Variant};
+use crate::derive::{Data, DataEnum, DataStruct, DataUnion, DeriveInput};
+use crate::expr::Expr;
+use crate::generics::{Generics, TypeParamBound};
+use crate::ident::Ident;
+use crate::lifetime::Lifetime;
+use crate::mac::Macro;
+use crate::pat::{Pat, PatType};
+use crate::path::Path;
+use crate::punctuated::Punctuated;
+use crate::restriction::Visibility;
+use crate::stmt::Block;
+use crate::token;
+use crate::ty::{Abi, ReturnType, Type};
+use proc_macro2::TokenStream;
+#[cfg(feature = "parsing")]
+use std::mem;
+
+ast_enum_of_structs! {
+ /// Things that can appear directly inside of a module or scope.
+ ///
+ /// # 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 = "full")))]
+ #[non_exhaustive]
+ pub enum Item {
+ /// A constant item: `const MAX: u16 = 65535`.
+ Const(ItemConst),
+
+ /// An enum definition: `enum Foo<A, B> { A(A), B(B) }`.
+ Enum(ItemEnum),
+
+ /// An `extern crate` item: `extern crate serde`.
+ ExternCrate(ItemExternCrate),
+
+ /// A free-standing function: `fn process(n: usize) -> Result<()> { ...
+ /// }`.
+ Fn(ItemFn),
+
+ /// A block of foreign items: `extern "C" { ... }`.
+ ForeignMod(ItemForeignMod),
+
+ /// An impl block providing trait or associated items: `impl<A> Trait
+ /// for Data<A> { ... }`.
+ Impl(ItemImpl),
+
+ /// A macro invocation, which includes `macro_rules!` definitions.
+ Macro(ItemMacro),
+
+ /// A module or module declaration: `mod m` or `mod m { ... }`.
+ Mod(ItemMod),
+
+ /// A static item: `static BIKE: Shed = Shed(42)`.
+ Static(ItemStatic),
+
+ /// A struct definition: `struct Foo<A> { x: A }`.
+ Struct(ItemStruct),
+
+ /// A trait definition: `pub trait Iterator { ... }`.
+ Trait(ItemTrait),
+
+ /// A trait alias: `pub trait SharableIterator = Iterator + Sync`.
+ TraitAlias(ItemTraitAlias),
+
+ /// A type alias: `type Result<T> = std::result::Result<T, MyError>`.
+ Type(ItemType),
+
+ /// A union definition: `union Foo<A, B> { x: A, y: B }`.
+ Union(ItemUnion),
+
+ /// A use declaration: `use std::collections::HashMap`.
+ Use(ItemUse),
+
+ /// Tokens forming an item not interpreted by Syn.
+ Verbatim(TokenStream),
+
+ // For testing exhaustiveness in downstream code, use the following idiom:
+ //
+ // match item {
+ // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
+ //
+ // Item::Const(item) => {...}
+ // Item::Enum(item) => {...}
+ // ...
+ // Item::Verbatim(item) => {...}
+ //
+ // _ => { /* 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.
+ }
+}
+
+ast_struct! {
+ /// A constant item: `const MAX: u16 = 65535`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemConst {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub const_token: Token![const],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub colon_token: Token![:],
+ pub ty: Box<Type>,
+ pub eq_token: Token![=],
+ pub expr: Box<Expr>,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// An enum definition: `enum Foo<A, B> { A(A), B(B) }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemEnum {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub enum_token: Token![enum],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub brace_token: token::Brace,
+ pub variants: Punctuated<Variant, Token![,]>,
+ }
+}
+
+ast_struct! {
+ /// An `extern crate` item: `extern crate serde`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemExternCrate {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub extern_token: Token![extern],
+ pub crate_token: Token![crate],
+ pub ident: Ident,
+ pub rename: Option<(Token![as], Ident)>,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// A free-standing function: `fn process(n: usize) -> Result<()> { ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemFn {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub sig: Signature,
+ pub block: Box<Block>,
+ }
+}
+
+ast_struct! {
+ /// A block of foreign items: `extern "C" { ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemForeignMod {
+ pub attrs: Vec<Attribute>,
+ pub unsafety: Option<Token![unsafe]>,
+ pub abi: Abi,
+ pub brace_token: token::Brace,
+ pub items: Vec<ForeignItem>,
+ }
+}
+
+ast_struct! {
+ /// An impl block providing trait or associated items: `impl<A> Trait
+ /// for Data<A> { ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemImpl {
+ pub attrs: Vec<Attribute>,
+ pub defaultness: Option<Token![default]>,
+ pub unsafety: Option<Token![unsafe]>,
+ pub impl_token: Token![impl],
+ pub generics: Generics,
+ /// Trait this impl implements.
+ pub trait_: Option<(Option<Token![!]>, Path, Token![for])>,
+ /// The Self type of the impl.
+ pub self_ty: Box<Type>,
+ pub brace_token: token::Brace,
+ pub items: Vec<ImplItem>,
+ }
+}
+
+ast_struct! {
+ /// A macro invocation, which includes `macro_rules!` definitions.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemMacro {
+ pub attrs: Vec<Attribute>,
+ /// The `example` in `macro_rules! example { ... }`.
+ pub ident: Option<Ident>,
+ pub mac: Macro,
+ pub semi_token: Option<Token![;]>,
+ }
+}
+
+ast_struct! {
+ /// A module or module declaration: `mod m` or `mod m { ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemMod {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub unsafety: Option<Token![unsafe]>,
+ pub mod_token: Token![mod],
+ pub ident: Ident,
+ pub content: Option<(token::Brace, Vec<Item>)>,
+ pub semi: Option<Token![;]>,
+ }
+}
+
+ast_struct! {
+ /// A static item: `static BIKE: Shed = Shed(42)`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemStatic {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub static_token: Token![static],
+ pub mutability: StaticMutability,
+ pub ident: Ident,
+ pub colon_token: Token![:],
+ pub ty: Box<Type>,
+ pub eq_token: Token![=],
+ pub expr: Box<Expr>,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// A struct definition: `struct Foo<A> { x: A }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemStruct {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub struct_token: Token![struct],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub fields: Fields,
+ pub semi_token: Option<Token![;]>,
+ }
+}
+
+ast_struct! {
+ /// A trait definition: `pub trait Iterator { ... }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemTrait {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub unsafety: Option<Token![unsafe]>,
+ pub auto_token: Option<Token![auto]>,
+ pub restriction: Option<ImplRestriction>,
+ pub trait_token: Token![trait],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub colon_token: Option<Token![:]>,
+ pub supertraits: Punctuated<TypeParamBound, Token![+]>,
+ pub brace_token: token::Brace,
+ pub items: Vec<TraitItem>,
+ }
+}
+
+ast_struct! {
+ /// A trait alias: `pub trait SharableIterator = Iterator + Sync`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemTraitAlias {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub trait_token: Token![trait],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub eq_token: Token![=],
+ pub bounds: Punctuated<TypeParamBound, Token![+]>,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// A type alias: `type Result<T> = std::result::Result<T, MyError>`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemType {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub type_token: Token![type],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub eq_token: Token![=],
+ pub ty: Box<Type>,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// A union definition: `union Foo<A, B> { x: A, y: B }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemUnion {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub union_token: Token![union],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub fields: FieldsNamed,
+ }
+}
+
+ast_struct! {
+ /// A use declaration: `use std::collections::HashMap`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ItemUse {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub use_token: Token![use],
+ pub leading_colon: Option<Token![::]>,
+ pub tree: UseTree,
+ pub semi_token: Token![;],
+ }
+}
+
+impl Item {
+ #[cfg(feature = "parsing")]
+ pub(crate) fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
+ match self {
+ Item::Const(ItemConst { attrs, .. })
+ | Item::Enum(ItemEnum { attrs, .. })
+ | Item::ExternCrate(ItemExternCrate { attrs, .. })
+ | Item::Fn(ItemFn { attrs, .. })
+ | Item::ForeignMod(ItemForeignMod { attrs, .. })
+ | Item::Impl(ItemImpl { attrs, .. })
+ | Item::Macro(ItemMacro { attrs, .. })
+ | Item::Mod(ItemMod { attrs, .. })
+ | Item::Static(ItemStatic { attrs, .. })
+ | Item::Struct(ItemStruct { attrs, .. })
+ | Item::Trait(ItemTrait { attrs, .. })
+ | Item::TraitAlias(ItemTraitAlias { attrs, .. })
+ | Item::Type(ItemType { attrs, .. })
+ | Item::Union(ItemUnion { attrs, .. })
+ | Item::Use(ItemUse { attrs, .. }) => mem::replace(attrs, new),
+ Item::Verbatim(_) => Vec::new(),
+ }
+ }
+}
+
+impl From<DeriveInput> for Item {
+ fn from(input: DeriveInput) -> Item {
+ match input.data {
+ Data::Struct(data) => Item::Struct(ItemStruct {
+ attrs: input.attrs,
+ vis: input.vis,
+ struct_token: data.struct_token,
+ ident: input.ident,
+ generics: input.generics,
+ fields: data.fields,
+ semi_token: data.semi_token,
+ }),
+ Data::Enum(data) => Item::Enum(ItemEnum {
+ attrs: input.attrs,
+ vis: input.vis,
+ enum_token: data.enum_token,
+ ident: input.ident,
+ generics: input.generics,
+ brace_token: data.brace_token,
+ variants: data.variants,
+ }),
+ Data::Union(data) => Item::Union(ItemUnion {
+ attrs: input.attrs,
+ vis: input.vis,
+ union_token: data.union_token,
+ ident: input.ident,
+ generics: input.generics,
+ fields: data.fields,
+ }),
+ }
+ }
+}
+
+impl From<ItemStruct> for DeriveInput {
+ fn from(input: ItemStruct) -> DeriveInput {
+ DeriveInput {
+ attrs: input.attrs,
+ vis: input.vis,
+ ident: input.ident,
+ generics: input.generics,
+ data: Data::Struct(DataStruct {
+ struct_token: input.struct_token,
+ fields: input.fields,
+ semi_token: input.semi_token,
+ }),
+ }
+ }
+}
+
+impl From<ItemEnum> for DeriveInput {
+ fn from(input: ItemEnum) -> DeriveInput {
+ DeriveInput {
+ attrs: input.attrs,
+ vis: input.vis,
+ ident: input.ident,
+ generics: input.generics,
+ data: Data::Enum(DataEnum {
+ enum_token: input.enum_token,
+ brace_token: input.brace_token,
+ variants: input.variants,
+ }),
+ }
+ }
+}
+
+impl From<ItemUnion> for DeriveInput {
+ fn from(input: ItemUnion) -> DeriveInput {
+ DeriveInput {
+ attrs: input.attrs,
+ vis: input.vis,
+ ident: input.ident,
+ generics: input.generics,
+ data: Data::Union(DataUnion {
+ union_token: input.union_token,
+ fields: input.fields,
+ }),
+ }
+ }
+}
+
+ast_enum_of_structs! {
+ /// A suffix of an import tree in a `use` item: `Type as Renamed` or `*`.
+ ///
+ /// # 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 = "full")))]
+ pub enum UseTree {
+ /// A path prefix of imports in a `use` item: `std::...`.
+ Path(UsePath),
+
+ /// An identifier imported by a `use` item: `HashMap`.
+ Name(UseName),
+
+ /// An renamed identifier imported by a `use` item: `HashMap as Map`.
+ Rename(UseRename),
+
+ /// A glob import in a `use` item: `*`.
+ Glob(UseGlob),
+
+ /// A braced group of imports in a `use` item: `{A, B, C}`.
+ Group(UseGroup),
+ }
+}
+
+ast_struct! {
+ /// A path prefix of imports in a `use` item: `std::...`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct UsePath {
+ pub ident: Ident,
+ pub colon2_token: Token![::],
+ pub tree: Box<UseTree>,
+ }
+}
+
+ast_struct! {
+ /// An identifier imported by a `use` item: `HashMap`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct UseName {
+ pub ident: Ident,
+ }
+}
+
+ast_struct! {
+ /// An renamed identifier imported by a `use` item: `HashMap as Map`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct UseRename {
+ pub ident: Ident,
+ pub as_token: Token![as],
+ pub rename: Ident,
+ }
+}
+
+ast_struct! {
+ /// A glob import in a `use` item: `*`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct UseGlob {
+ pub star_token: Token![*],
+ }
+}
+
+ast_struct! {
+ /// A braced group of imports in a `use` item: `{A, B, C}`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct UseGroup {
+ pub brace_token: token::Brace,
+ pub items: Punctuated<UseTree, Token![,]>,
+ }
+}
+
+ast_enum_of_structs! {
+ /// An item within an `extern` block.
+ ///
+ /// # 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 = "full")))]
+ #[non_exhaustive]
+ pub enum ForeignItem {
+ /// A foreign function in an `extern` block.
+ Fn(ForeignItemFn),
+
+ /// A foreign static item in an `extern` block: `static ext: u8`.
+ Static(ForeignItemStatic),
+
+ /// A foreign type in an `extern` block: `type void`.
+ Type(ForeignItemType),
+
+ /// A macro invocation within an extern block.
+ Macro(ForeignItemMacro),
+
+ /// Tokens in an `extern` block not interpreted by Syn.
+ Verbatim(TokenStream),
+
+ // For testing exhaustiveness in downstream code, use the following idiom:
+ //
+ // match item {
+ // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
+ //
+ // ForeignItem::Fn(item) => {...}
+ // ForeignItem::Static(item) => {...}
+ // ...
+ // ForeignItem::Verbatim(item) => {...}
+ //
+ // _ => { /* 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.
+ }
+}
+
+ast_struct! {
+ /// A foreign function in an `extern` block.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ForeignItemFn {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub sig: Signature,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// A foreign static item in an `extern` block: `static ext: u8`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ForeignItemStatic {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub static_token: Token![static],
+ pub mutability: StaticMutability,
+ pub ident: Ident,
+ pub colon_token: Token![:],
+ pub ty: Box<Type>,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// A foreign type in an `extern` block: `type void`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ForeignItemType {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub type_token: Token![type],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// A macro invocation within an extern block.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ForeignItemMacro {
+ pub attrs: Vec<Attribute>,
+ pub mac: Macro,
+ pub semi_token: Option<Token![;]>,
+ }
+}
+
+ast_enum_of_structs! {
+ /// An item declaration within the definition of a trait.
+ ///
+ /// # 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 = "full")))]
+ #[non_exhaustive]
+ pub enum TraitItem {
+ /// An associated constant within the definition of a trait.
+ Const(TraitItemConst),
+
+ /// An associated function within the definition of a trait.
+ Fn(TraitItemFn),
+
+ /// An associated type within the definition of a trait.
+ Type(TraitItemType),
+
+ /// A macro invocation within the definition of a trait.
+ Macro(TraitItemMacro),
+
+ /// Tokens within the definition of a trait not interpreted by Syn.
+ Verbatim(TokenStream),
+
+ // For testing exhaustiveness in downstream code, use the following idiom:
+ //
+ // match item {
+ // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
+ //
+ // TraitItem::Const(item) => {...}
+ // TraitItem::Fn(item) => {...}
+ // ...
+ // TraitItem::Verbatim(item) => {...}
+ //
+ // _ => { /* 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.
+ }
+}
+
+ast_struct! {
+ /// An associated constant within the definition of a trait.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct TraitItemConst {
+ pub attrs: Vec<Attribute>,
+ pub const_token: Token![const],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub colon_token: Token![:],
+ pub ty: Type,
+ pub default: Option<(Token![=], Expr)>,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// An associated function within the definition of a trait.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct TraitItemFn {
+ pub attrs: Vec<Attribute>,
+ pub sig: Signature,
+ pub default: Option<Block>,
+ pub semi_token: Option<Token![;]>,
+ }
+}
+
+ast_struct! {
+ /// An associated type within the definition of a trait.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct TraitItemType {
+ pub attrs: Vec<Attribute>,
+ pub type_token: Token![type],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub colon_token: Option<Token![:]>,
+ pub bounds: Punctuated<TypeParamBound, Token![+]>,
+ pub default: Option<(Token![=], Type)>,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// A macro invocation within the definition of a trait.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct TraitItemMacro {
+ pub attrs: Vec<Attribute>,
+ pub mac: Macro,
+ pub semi_token: Option<Token![;]>,
+ }
+}
+
+ast_enum_of_structs! {
+ /// An item within an impl block.
+ ///
+ /// # 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 = "full")))]
+ #[non_exhaustive]
+ pub enum ImplItem {
+ /// An associated constant within an impl block.
+ Const(ImplItemConst),
+
+ /// An associated function within an impl block.
+ Fn(ImplItemFn),
+
+ /// An associated type within an impl block.
+ Type(ImplItemType),
+
+ /// A macro invocation within an impl block.
+ Macro(ImplItemMacro),
+
+ /// Tokens within an impl block not interpreted by Syn.
+ Verbatim(TokenStream),
+
+ // For testing exhaustiveness in downstream code, use the following idiom:
+ //
+ // match item {
+ // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
+ //
+ // ImplItem::Const(item) => {...}
+ // ImplItem::Fn(item) => {...}
+ // ...
+ // ImplItem::Verbatim(item) => {...}
+ //
+ // _ => { /* 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.
+ }
+}
+
+ast_struct! {
+ /// An associated constant within an impl block.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ImplItemConst {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub defaultness: Option<Token![default]>,
+ pub const_token: Token![const],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub colon_token: Token![:],
+ pub ty: Type,
+ pub eq_token: Token![=],
+ pub expr: Expr,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// An associated function within an impl block.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ImplItemFn {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub defaultness: Option<Token![default]>,
+ pub sig: Signature,
+ pub block: Block,
+ }
+}
+
+ast_struct! {
+ /// An associated type within an impl block.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ImplItemType {
+ pub attrs: Vec<Attribute>,
+ pub vis: Visibility,
+ pub defaultness: Option<Token![default]>,
+ pub type_token: Token![type],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub eq_token: Token![=],
+ pub ty: Type,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// A macro invocation within an impl block.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct ImplItemMacro {
+ pub attrs: Vec<Attribute>,
+ pub mac: Macro,
+ pub semi_token: Option<Token![;]>,
+ }
+}
+
+ast_struct! {
+ /// A function signature in a trait or implementation: `unsafe fn
+ /// initialize(&self)`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct Signature {
+ pub constness: Option<Token![const]>,
+ pub asyncness: Option<Token![async]>,
+ pub unsafety: Option<Token![unsafe]>,
+ pub abi: Option<Abi>,
+ pub fn_token: Token![fn],
+ pub ident: Ident,
+ pub generics: Generics,
+ pub paren_token: token::Paren,
+ pub inputs: Punctuated<FnArg, Token![,]>,
+ pub variadic: Option<Variadic>,
+ pub output: ReturnType,
+ }
+}
+
+impl Signature {
+ /// A method's `self` receiver, such as `&self` or `self: Box<Self>`.
+ pub fn receiver(&self) -> Option<&Receiver> {
+ let arg = self.inputs.first()?;
+ match arg {
+ FnArg::Receiver(receiver) => Some(receiver),
+ FnArg::Typed(_) => None,
+ }
+ }
+}
+
+ast_enum_of_structs! {
+ /// An argument in a function signature: the `n: usize` in `fn f(n: usize)`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub enum FnArg {
+ /// The `self` argument of an associated method.
+ Receiver(Receiver),
+
+ /// A function argument accepted by pattern and type.
+ Typed(PatType),
+ }
+}
+
+ast_struct! {
+ /// The `self` argument of an associated method.
+ ///
+ /// If `colon_token` is present, the receiver is written with an explicit
+ /// type such as `self: Box<Self>`. If `colon_token` is absent, the receiver
+ /// is written in shorthand such as `self` or `&self` or `&mut self`. In the
+ /// shorthand case, the type in `ty` is reconstructed as one of `Self`,
+ /// `&Self`, or `&mut Self`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct Receiver {
+ pub attrs: Vec<Attribute>,
+ pub reference: Option<(Token![&], Option<Lifetime>)>,
+ pub mutability: Option<Token![mut]>,
+ pub self_token: Token![self],
+ pub colon_token: Option<Token![:]>,
+ pub ty: Box<Type>,
+ }
+}
+
+impl Receiver {
+ pub fn lifetime(&self) -> Option<&Lifetime> {
+ self.reference.as_ref()?.1.as_ref()
+ }
+}
+
+ast_struct! {
+ /// The variadic argument of a foreign function.
+ ///
+ /// ```rust
+ /// # struct c_char;
+ /// # struct c_int;
+ /// #
+ /// extern "C" {
+ /// fn printf(format: *const c_char, ...) -> c_int;
+ /// // ^^^
+ /// }
+ /// ```
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct Variadic {
+ pub attrs: Vec<Attribute>,
+ pub pat: Option<(Box<Pat>, Token![:])>,
+ pub dots: Token![...],
+ pub comma: Option<Token![,]>,
+ }
+}
+
+ast_enum! {
+ /// The mutability of an `Item::Static` or `ForeignItem::Static`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ #[non_exhaustive]
+ pub enum StaticMutability {
+ Mut(Token![mut]),
+ None,
+ }
+}
+
+ast_enum! {
+ /// Unused, but reserved for RFC 3323 restrictions.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ #[non_exhaustive]
+ pub enum ImplRestriction {}
+
+
+ // TODO: https://rust-lang.github.io/rfcs/3323-restrictions.html
+ //
+ // pub struct ImplRestriction {
+ // pub impl_token: Token![impl],
+ // pub paren_token: token::Paren,
+ // pub in_token: Option<Token![in]>,
+ // pub path: Box<Path>,
+ // }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::attr::{self, Attribute};
+ use crate::derive;
+ use crate::error::{Error, Result};
+ use crate::expr::Expr;
+ use crate::ext::IdentExt as _;
+ use crate::generics::{Generics, TypeParamBound};
+ use crate::ident::Ident;
+ use crate::item::{
+ FnArg, ForeignItem, ForeignItemFn, ForeignItemMacro, ForeignItemStatic, 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, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic,
+ };
+ use crate::lifetime::Lifetime;
+ use crate::lit::LitStr;
+ use crate::mac::{self, Macro};
+ use crate::parse::discouraged::Speculative as _;
+ use crate::parse::{Parse, ParseBuffer, ParseStream};
+ use crate::pat::{Pat, PatType, PatWild};
+ use crate::path::Path;
+ use crate::punctuated::Punctuated;
+ use crate::restriction::Visibility;
+ use crate::stmt::Block;
+ use crate::token;
+ use crate::ty::{Abi, ReturnType, Type, TypePath, TypeReference};
+ use crate::verbatim;
+ use proc_macro2::TokenStream;
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Item {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let begin = input.fork();
+ let attrs = input.call(Attribute::parse_outer)?;
+ parse_rest_of_item(begin, attrs, input)
+ }
+ }
+
+ pub(crate) fn parse_rest_of_item(
+ begin: ParseBuffer,
+ mut attrs: Vec<Attribute>,
+ input: ParseStream,
+ ) -> Result<Item> {
+ let ahead = input.fork();
+ let vis: Visibility = ahead.parse()?;
+
+ let lookahead = ahead.lookahead1();
+ let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) {
+ let vis: Visibility = input.parse()?;
+ let sig: Signature = input.parse()?;
+ if input.peek(Token![;]) {
+ input.parse::<Token![;]>()?;
+ Ok(Item::Verbatim(verbatim::between(&begin, input)))
+ } else {
+ parse_rest_of_fn(input, Vec::new(), vis, sig).map(Item::Fn)
+ }
+ } else if lookahead.peek(Token![extern]) {
+ ahead.parse::<Token![extern]>()?;
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(Token![crate]) {
+ input.parse().map(Item::ExternCrate)
+ } else if lookahead.peek(token::Brace) {
+ input.parse().map(Item::ForeignMod)
+ } else if lookahead.peek(LitStr) {
+ ahead.parse::<LitStr>()?;
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(token::Brace) {
+ input.parse().map(Item::ForeignMod)
+ } else {
+ Err(lookahead.error())
+ }
+ } else {
+ Err(lookahead.error())
+ }
+ } else if lookahead.peek(Token![use]) {
+ let allow_crate_root_in_path = true;
+ match parse_item_use(input, allow_crate_root_in_path)? {
+ Some(item_use) => Ok(Item::Use(item_use)),
+ None => Ok(Item::Verbatim(verbatim::between(&begin, input))),
+ }
+ } else if lookahead.peek(Token![static]) {
+ let vis = input.parse()?;
+ let static_token = input.parse()?;
+ let mutability = input.parse()?;
+ let ident = input.parse()?;
+ if input.peek(Token![=]) {
+ input.parse::<Token![=]>()?;
+ input.parse::<Expr>()?;
+ input.parse::<Token![;]>()?;
+ Ok(Item::Verbatim(verbatim::between(&begin, input)))
+ } else {
+ let colon_token = input.parse()?;
+ let ty = input.parse()?;
+ if input.peek(Token![;]) {
+ input.parse::<Token![;]>()?;
+ Ok(Item::Verbatim(verbatim::between(&begin, input)))
+ } else {
+ Ok(Item::Static(ItemStatic {
+ attrs: Vec::new(),
+ vis,
+ static_token,
+ mutability,
+ ident,
+ colon_token,
+ ty,
+ eq_token: input.parse()?,
+ expr: input.parse()?,
+ semi_token: input.parse()?,
+ }))
+ }
+ }
+ } else if lookahead.peek(Token![const]) {
+ let vis = input.parse()?;
+ let const_token: Token![const] = input.parse()?;
+ let lookahead = input.lookahead1();
+ let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
+ input.call(Ident::parse_any)?
+ } else {
+ return Err(lookahead.error());
+ };
+ let mut generics: Generics = input.parse()?;
+ let colon_token = input.parse()?;
+ let ty = input.parse()?;
+ let value = if let Some(eq_token) = input.parse::<Option<Token![=]>>()? {
+ let expr: Expr = input.parse()?;
+ Some((eq_token, expr))
+ } else {
+ None
+ };
+ generics.where_clause = input.parse()?;
+ let semi_token: Token![;] = input.parse()?;
+ match value {
+ Some((eq_token, expr))
+ if generics.lt_token.is_none() && generics.where_clause.is_none() =>
+ {
+ Ok(Item::Const(ItemConst {
+ attrs: Vec::new(),
+ vis,
+ const_token,
+ ident,
+ generics,
+ colon_token,
+ ty,
+ eq_token,
+ expr: Box::new(expr),
+ semi_token,
+ }))
+ }
+ _ => Ok(Item::Verbatim(verbatim::between(&begin, input))),
+ }
+ } else if lookahead.peek(Token![unsafe]) {
+ ahead.parse::<Token![unsafe]>()?;
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(Token![trait])
+ || lookahead.peek(Token![auto]) && ahead.peek2(Token![trait])
+ {
+ input.parse().map(Item::Trait)
+ } else if lookahead.peek(Token![impl]) {
+ let allow_verbatim_impl = true;
+ if let Some(item) = parse_impl(input, allow_verbatim_impl)? {
+ Ok(Item::Impl(item))
+ } else {
+ Ok(Item::Verbatim(verbatim::between(&begin, input)))
+ }
+ } else if lookahead.peek(Token![extern]) {
+ input.parse().map(Item::ForeignMod)
+ } else if lookahead.peek(Token![mod]) {
+ input.parse().map(Item::Mod)
+ } else {
+ Err(lookahead.error())
+ }
+ } else if lookahead.peek(Token![mod]) {
+ input.parse().map(Item::Mod)
+ } else if lookahead.peek(Token![type]) {
+ parse_item_type(begin, input)
+ } else if lookahead.peek(Token![struct]) {
+ input.parse().map(Item::Struct)
+ } else if lookahead.peek(Token![enum]) {
+ input.parse().map(Item::Enum)
+ } else if lookahead.peek(Token![union]) && ahead.peek2(Ident) {
+ input.parse().map(Item::Union)
+ } else if lookahead.peek(Token![trait]) {
+ input.call(parse_trait_or_trait_alias)
+ } else if lookahead.peek(Token![auto]) && ahead.peek2(Token![trait]) {
+ input.parse().map(Item::Trait)
+ } else if lookahead.peek(Token![impl])
+ || lookahead.peek(Token![default]) && !ahead.peek2(Token![!])
+ {
+ let allow_verbatim_impl = true;
+ if let Some(item) = parse_impl(input, allow_verbatim_impl)? {
+ Ok(Item::Impl(item))
+ } else {
+ Ok(Item::Verbatim(verbatim::between(&begin, input)))
+ }
+ } else if lookahead.peek(Token![macro]) {
+ input.advance_to(&ahead);
+ parse_macro2(begin, vis, input)
+ } else if vis.is_inherited()
+ && (lookahead.peek(Ident)
+ || lookahead.peek(Token![self])
+ || lookahead.peek(Token![super])
+ || lookahead.peek(Token![crate])
+ || lookahead.peek(Token![::]))
+ {
+ input.parse().map(Item::Macro)
+ } else {
+ Err(lookahead.error())
+ }?;
+
+ attrs.extend(item.replace_attrs(Vec::new()));
+ item.replace_attrs(attrs);
+ Ok(item)
+ }
+
+ struct FlexibleItemType {
+ vis: Visibility,
+ defaultness: Option<Token![default]>,
+ type_token: Token![type],
+ ident: Ident,
+ generics: Generics,
+ colon_token: Option<Token![:]>,
+ bounds: Punctuated<TypeParamBound, Token![+]>,
+ ty: Option<(Token![=], Type)>,
+ semi_token: Token![;],
+ }
+
+ enum TypeDefaultness {
+ Optional,
+ Disallowed,
+ }
+
+ enum WhereClauseLocation {
+ // type Ty<T> where T: 'static = T;
+ BeforeEq,
+ // type Ty<T> = T where T: 'static;
+ AfterEq,
+ // TODO: goes away once the migration period on rust-lang/rust#89122 is over
+ Both,
+ }
+
+ impl FlexibleItemType {
+ fn parse(
+ input: ParseStream,
+ allow_defaultness: TypeDefaultness,
+ where_clause_location: WhereClauseLocation,
+ ) -> Result<Self> {
+ let vis: Visibility = input.parse()?;
+ let defaultness: Option<Token![default]> = match allow_defaultness {
+ TypeDefaultness::Optional => input.parse()?,
+ TypeDefaultness::Disallowed => None,
+ };
+ let type_token: Token![type] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let mut generics: Generics = input.parse()?;
+ let (colon_token, bounds) = Self::parse_optional_bounds(input)?;
+
+ match where_clause_location {
+ WhereClauseLocation::BeforeEq | WhereClauseLocation::Both => {
+ generics.where_clause = input.parse()?;
+ }
+ WhereClauseLocation::AfterEq => {}
+ }
+
+ let ty = Self::parse_optional_definition(input)?;
+
+ match where_clause_location {
+ WhereClauseLocation::AfterEq | WhereClauseLocation::Both
+ if generics.where_clause.is_none() =>
+ {
+ generics.where_clause = input.parse()?;
+ }
+ _ => {}
+ }
+
+ let semi_token: Token![;] = input.parse()?;
+
+ Ok(FlexibleItemType {
+ vis,
+ defaultness,
+ type_token,
+ ident,
+ generics,
+ colon_token,
+ bounds,
+ ty,
+ semi_token,
+ })
+ }
+
+ fn parse_optional_bounds(
+ input: ParseStream,
+ ) -> Result<(Option<Token![:]>, Punctuated<TypeParamBound, Token![+]>)> {
+ let colon_token: Option<Token![:]> = input.parse()?;
+
+ let mut bounds = Punctuated::new();
+ if colon_token.is_some() {
+ loop {
+ if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) {
+ break;
+ }
+ bounds.push_value(input.parse::<TypeParamBound>()?);
+ if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) {
+ break;
+ }
+ bounds.push_punct(input.parse::<Token![+]>()?);
+ }
+ }
+
+ Ok((colon_token, bounds))
+ }
+
+ fn parse_optional_definition(input: ParseStream) -> Result<Option<(Token![=], Type)>> {
+ let eq_token: Option<Token![=]> = input.parse()?;
+ if let Some(eq_token) = eq_token {
+ let definition: Type = input.parse()?;
+ Ok(Some((eq_token, definition)))
+ } else {
+ Ok(None)
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemMacro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let path = input.call(Path::parse_mod_style)?;
+ let bang_token: Token![!] = input.parse()?;
+ let ident: Option<Ident> = if input.peek(Token![try]) {
+ input.call(Ident::parse_any).map(Some)
+ } else {
+ input.parse()
+ }?;
+ let (delimiter, tokens) = input.call(mac::parse_delimiter)?;
+ let semi_token: Option<Token![;]> = if !delimiter.is_brace() {
+ Some(input.parse()?)
+ } else {
+ None
+ };
+ Ok(ItemMacro {
+ attrs,
+ ident,
+ mac: Macro {
+ path,
+ bang_token,
+ delimiter,
+ tokens,
+ },
+ semi_token,
+ })
+ }
+ }
+
+ fn parse_macro2(begin: ParseBuffer, _vis: Visibility, input: ParseStream) -> Result<Item> {
+ input.parse::<Token![macro]>()?;
+ input.parse::<Ident>()?;
+
+ let mut lookahead = input.lookahead1();
+ if lookahead.peek(token::Paren) {
+ let paren_content;
+ parenthesized!(paren_content in input);
+ paren_content.parse::<TokenStream>()?;
+ lookahead = input.lookahead1();
+ }
+
+ if lookahead.peek(token::Brace) {
+ let brace_content;
+ braced!(brace_content in input);
+ brace_content.parse::<TokenStream>()?;
+ } else {
+ return Err(lookahead.error());
+ }
+
+ Ok(Item::Verbatim(verbatim::between(&begin, input)))
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemExternCrate {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ItemExternCrate {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ extern_token: input.parse()?,
+ crate_token: input.parse()?,
+ ident: {
+ if input.peek(Token![self]) {
+ input.call(Ident::parse_any)?
+ } else {
+ input.parse()?
+ }
+ },
+ rename: {
+ if input.peek(Token![as]) {
+ let as_token: Token![as] = input.parse()?;
+ let rename: Ident = if input.peek(Token![_]) {
+ Ident::from(input.parse::<Token![_]>()?)
+ } else {
+ input.parse()?
+ };
+ Some((as_token, rename))
+ } else {
+ None
+ }
+ },
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemUse {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_crate_root_in_path = false;
+ parse_item_use(input, allow_crate_root_in_path).map(Option::unwrap)
+ }
+ }
+
+ fn parse_item_use(
+ input: ParseStream,
+ allow_crate_root_in_path: bool,
+ ) -> Result<Option<ItemUse>> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let use_token: Token![use] = input.parse()?;
+ let leading_colon: Option<Token![::]> = input.parse()?;
+ let tree = parse_use_tree(input, allow_crate_root_in_path && leading_colon.is_none())?;
+ let semi_token: Token![;] = input.parse()?;
+
+ let tree = match tree {
+ Some(tree) => tree,
+ None => return Ok(None),
+ };
+
+ Ok(Some(ItemUse {
+ attrs,
+ vis,
+ use_token,
+ leading_colon,
+ tree,
+ semi_token,
+ }))
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for UseTree {
+ fn parse(input: ParseStream) -> Result<UseTree> {
+ let allow_crate_root_in_path = false;
+ parse_use_tree(input, allow_crate_root_in_path).map(Option::unwrap)
+ }
+ }
+
+ fn parse_use_tree(
+ input: ParseStream,
+ allow_crate_root_in_path: bool,
+ ) -> Result<Option<UseTree>> {
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Ident)
+ || lookahead.peek(Token![self])
+ || lookahead.peek(Token![super])
+ || lookahead.peek(Token![crate])
+ || lookahead.peek(Token![try])
+ {
+ let ident = input.call(Ident::parse_any)?;
+ if input.peek(Token![::]) {
+ Ok(Some(UseTree::Path(UsePath {
+ ident,
+ colon2_token: input.parse()?,
+ tree: Box::new(input.parse()?),
+ })))
+ } else if input.peek(Token![as]) {
+ Ok(Some(UseTree::Rename(UseRename {
+ ident,
+ as_token: input.parse()?,
+ rename: {
+ if input.peek(Ident) {
+ input.parse()?
+ } else if input.peek(Token![_]) {
+ Ident::from(input.parse::<Token![_]>()?)
+ } else {
+ return Err(input.error("expected identifier or underscore"));
+ }
+ },
+ })))
+ } else {
+ Ok(Some(UseTree::Name(UseName { ident })))
+ }
+ } else if lookahead.peek(Token![*]) {
+ Ok(Some(UseTree::Glob(UseGlob {
+ star_token: input.parse()?,
+ })))
+ } else if lookahead.peek(token::Brace) {
+ let content;
+ let brace_token = braced!(content in input);
+ let mut items = Punctuated::new();
+ let mut has_any_crate_root_in_path = false;
+ loop {
+ if content.is_empty() {
+ break;
+ }
+ let this_tree_starts_with_crate_root =
+ allow_crate_root_in_path && content.parse::<Option<Token![::]>>()?.is_some();
+ has_any_crate_root_in_path |= this_tree_starts_with_crate_root;
+ match parse_use_tree(
+ &content,
+ allow_crate_root_in_path && !this_tree_starts_with_crate_root,
+ )? {
+ Some(tree) => items.push_value(tree),
+ None => has_any_crate_root_in_path = true,
+ }
+ if content.is_empty() {
+ break;
+ }
+ let comma: Token![,] = content.parse()?;
+ items.push_punct(comma);
+ }
+ if has_any_crate_root_in_path {
+ Ok(None)
+ } else {
+ Ok(Some(UseTree::Group(UseGroup { brace_token, items })))
+ }
+ } else {
+ Err(lookahead.error())
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemStatic {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ItemStatic {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ static_token: input.parse()?,
+ mutability: input.parse()?,
+ ident: input.parse()?,
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ eq_token: input.parse()?,
+ expr: input.parse()?,
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemConst {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let const_token: Token![const] = input.parse()?;
+
+ let lookahead = input.lookahead1();
+ let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
+ input.call(Ident::parse_any)?
+ } else {
+ return Err(lookahead.error());
+ };
+
+ let colon_token: Token![:] = input.parse()?;
+ let ty: Type = input.parse()?;
+ let eq_token: Token![=] = input.parse()?;
+ let expr: Expr = input.parse()?;
+ let semi_token: Token![;] = input.parse()?;
+
+ Ok(ItemConst {
+ attrs,
+ vis,
+ const_token,
+ ident,
+ generics: Generics::default(),
+ colon_token,
+ ty: Box::new(ty),
+ eq_token,
+ expr: Box::new(expr),
+ semi_token,
+ })
+ }
+ }
+
+ fn peek_signature(input: ParseStream) -> bool {
+ let fork = input.fork();
+ fork.parse::<Option<Token![const]>>().is_ok()
+ && fork.parse::<Option<Token![async]>>().is_ok()
+ && fork.parse::<Option<Token![unsafe]>>().is_ok()
+ && fork.parse::<Option<Abi>>().is_ok()
+ && fork.peek(Token![fn])
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Signature {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let constness: Option<Token![const]> = input.parse()?;
+ let asyncness: Option<Token![async]> = input.parse()?;
+ let unsafety: Option<Token![unsafe]> = input.parse()?;
+ let abi: Option<Abi> = input.parse()?;
+ let fn_token: Token![fn] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let mut generics: Generics = input.parse()?;
+
+ let content;
+ let paren_token = parenthesized!(content in input);
+ let (inputs, variadic) = parse_fn_args(&content)?;
+
+ let output: ReturnType = input.parse()?;
+ generics.where_clause = input.parse()?;
+
+ Ok(Signature {
+ constness,
+ asyncness,
+ unsafety,
+ abi,
+ fn_token,
+ ident,
+ generics,
+ paren_token,
+ inputs,
+ variadic,
+ output,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemFn {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let outer_attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let sig: Signature = input.parse()?;
+ parse_rest_of_fn(input, outer_attrs, vis, sig)
+ }
+ }
+
+ fn parse_rest_of_fn(
+ input: ParseStream,
+ mut attrs: Vec<Attribute>,
+ vis: Visibility,
+ sig: Signature,
+ ) -> Result<ItemFn> {
+ let content;
+ let brace_token = braced!(content in input);
+ attr::parsing::parse_inner(&content, &mut attrs)?;
+ let stmts = content.call(Block::parse_within)?;
+
+ Ok(ItemFn {
+ attrs,
+ vis,
+ sig,
+ block: Box::new(Block { brace_token, stmts }),
+ })
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for FnArg {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_variadic = false;
+ let attrs = input.call(Attribute::parse_outer)?;
+ match parse_fn_arg_or_variadic(input, attrs, allow_variadic)? {
+ FnArgOrVariadic::FnArg(arg) => Ok(arg),
+ FnArgOrVariadic::Variadic(_) => unreachable!(),
+ }
+ }
+ }
+
+ enum FnArgOrVariadic {
+ FnArg(FnArg),
+ Variadic(Variadic),
+ }
+
+ fn parse_fn_arg_or_variadic(
+ input: ParseStream,
+ attrs: Vec<Attribute>,
+ allow_variadic: bool,
+ ) -> Result<FnArgOrVariadic> {
+ let ahead = input.fork();
+ if let Ok(mut receiver) = ahead.parse::<Receiver>() {
+ input.advance_to(&ahead);
+ receiver.attrs = attrs;
+ return Ok(FnArgOrVariadic::FnArg(FnArg::Receiver(receiver)));
+ }
+
+ // Hack to parse pre-2018 syntax in
+ // test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
+ // because the rest of the test case is valuable.
+ if input.peek(Ident) && input.peek2(Token![<]) {
+ let span = input.fork().parse::<Ident>()?.span();
+ return Ok(FnArgOrVariadic::FnArg(FnArg::Typed(PatType {
+ attrs,
+ pat: Box::new(Pat::Wild(PatWild {
+ attrs: Vec::new(),
+ underscore_token: Token,
+ })),
+ colon_token: Token,
+ ty: input.parse()?,
+ })));
+ }
+
+ let pat = Box::new(Pat::parse_single(input)?);
+ let colon_token: Token![:] = input.parse()?;
+
+ if allow_variadic {
+ if let Some(dots) = input.parse::<Option<Token![...]>>()? {
+ return Ok(FnArgOrVariadic::Variadic(Variadic {
+ attrs,
+ pat: Some((pat, colon_token)),
+ dots,
+ comma: None,
+ }));
+ }
+ }
+
+ Ok(FnArgOrVariadic::FnArg(FnArg::Typed(PatType {
+ attrs,
+ pat,
+ colon_token,
+ ty: input.parse()?,
+ })))
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Receiver {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let reference = if input.peek(Token![&]) {
+ let ampersand: Token![&] = input.parse()?;
+ let lifetime: Option<Lifetime> = input.parse()?;
+ Some((ampersand, lifetime))
+ } else {
+ None
+ };
+ let mutability: Option<Token![mut]> = input.parse()?;
+ let self_token: Token![self] = input.parse()?;
+ let colon_token: Option<Token![:]> = if reference.is_some() {
+ None
+ } else {
+ input.parse()?
+ };
+ let ty: Type = if colon_token.is_some() {
+ input.parse()?
+ } else {
+ let mut ty = Type::Path(TypePath {
+ qself: None,
+ path: Path::from(Ident::new("Self", self_token.span)),
+ });
+ if let Some((ampersand, lifetime)) = reference.as_ref() {
+ ty = Type::Reference(TypeReference {
+ and_token: Token,
+ lifetime: lifetime.clone(),
+ mutability: mutability.as_ref().map(|m| Token),
+ elem: Box::new(ty),
+ });
+ }
+ ty
+ };
+ Ok(Receiver {
+ attrs: Vec::new(),
+ reference,
+ mutability,
+ self_token,
+ colon_token,
+ ty: Box::new(ty),
+ })
+ }
+ }
+
+ fn parse_fn_args(
+ input: ParseStream,
+ ) -> Result<(Punctuated<FnArg, Token![,]>, Option<Variadic>)> {
+ let mut args = Punctuated::new();
+ let mut variadic = None;
+ let mut has_receiver = false;
+
+ while !input.is_empty() {
+ let attrs = input.call(Attribute::parse_outer)?;
+
+ if let Some(dots) = input.parse::<Option<Token![...]>>()? {
+ variadic = Some(Variadic {
+ attrs,
+ pat: None,
+ dots,
+ comma: if input.is_empty() {
+ None
+ } else {
+ Some(input.parse()?)
+ },
+ });
+ break;
+ }
+
+ let allow_variadic = true;
+ let arg = match parse_fn_arg_or_variadic(input, attrs, allow_variadic)? {
+ FnArgOrVariadic::FnArg(arg) => arg,
+ FnArgOrVariadic::Variadic(arg) => {
+ variadic = Some(Variadic {
+ comma: if input.is_empty() {
+ None
+ } else {
+ Some(input.parse()?)
+ },
+ ..arg
+ });
+ break;
+ }
+ };
+
+ match &arg {
+ FnArg::Receiver(receiver) if has_receiver => {
+ return Err(Error::new(
+ receiver.self_token.span,
+ "unexpected second method receiver",
+ ));
+ }
+ FnArg::Receiver(receiver) if !args.is_empty() => {
+ return Err(Error::new(
+ receiver.self_token.span,
+ "unexpected method receiver",
+ ));
+ }
+ FnArg::Receiver(_) => has_receiver = true,
+ FnArg::Typed(_) => {}
+ }
+ args.push_value(arg);
+
+ if input.is_empty() {
+ break;
+ }
+
+ let comma: Token![,] = input.parse()?;
+ args.push_punct(comma);
+ }
+
+ Ok((args, variadic))
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemMod {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let unsafety: Option<Token![unsafe]> = input.parse()?;
+ let mod_token: Token![mod] = input.parse()?;
+ let ident: Ident = if input.peek(Token![try]) {
+ input.call(Ident::parse_any)
+ } else {
+ input.parse()
+ }?;
+
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Token![;]) {
+ Ok(ItemMod {
+ attrs,
+ vis,
+ unsafety,
+ mod_token,
+ ident,
+ content: None,
+ semi: Some(input.parse()?),
+ })
+ } else if lookahead.peek(token::Brace) {
+ let content;
+ let brace_token = braced!(content in input);
+ attr::parsing::parse_inner(&content, &mut attrs)?;
+
+ let mut items = Vec::new();
+ while !content.is_empty() {
+ items.push(content.parse()?);
+ }
+
+ Ok(ItemMod {
+ attrs,
+ vis,
+ unsafety,
+ mod_token,
+ ident,
+ content: Some((brace_token, items)),
+ semi: None,
+ })
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemForeignMod {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let unsafety: Option<Token![unsafe]> = input.parse()?;
+ let abi: Abi = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ attr::parsing::parse_inner(&content, &mut attrs)?;
+ let mut items = Vec::new();
+ while !content.is_empty() {
+ items.push(content.parse()?);
+ }
+
+ Ok(ItemForeignMod {
+ attrs,
+ unsafety,
+ abi,
+ brace_token,
+ items,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ForeignItem {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let begin = input.fork();
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let ahead = input.fork();
+ let vis: Visibility = ahead.parse()?;
+
+ let lookahead = ahead.lookahead1();
+ let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) {
+ let vis: Visibility = input.parse()?;
+ let sig: Signature = input.parse()?;
+ if input.peek(token::Brace) {
+ let content;
+ braced!(content in input);
+ content.call(Attribute::parse_inner)?;
+ content.call(Block::parse_within)?;
+
+ Ok(ForeignItem::Verbatim(verbatim::between(&begin, input)))
+ } else {
+ Ok(ForeignItem::Fn(ForeignItemFn {
+ attrs: Vec::new(),
+ vis,
+ sig,
+ semi_token: input.parse()?,
+ }))
+ }
+ } else if lookahead.peek(Token![static]) {
+ let vis = input.parse()?;
+ let static_token = input.parse()?;
+ let mutability = input.parse()?;
+ let ident = input.parse()?;
+ let colon_token = input.parse()?;
+ let ty = input.parse()?;
+ if input.peek(Token![=]) {
+ input.parse::<Token![=]>()?;
+ input.parse::<Expr>()?;
+ input.parse::<Token![;]>()?;
+ Ok(ForeignItem::Verbatim(verbatim::between(&begin, input)))
+ } else {
+ Ok(ForeignItem::Static(ForeignItemStatic {
+ attrs: Vec::new(),
+ vis,
+ static_token,
+ mutability,
+ ident,
+ colon_token,
+ ty,
+ semi_token: input.parse()?,
+ }))
+ }
+ } else if lookahead.peek(Token![type]) {
+ parse_foreign_item_type(begin, input)
+ } else if vis.is_inherited()
+ && (lookahead.peek(Ident)
+ || lookahead.peek(Token![self])
+ || lookahead.peek(Token![super])
+ || lookahead.peek(Token![crate])
+ || lookahead.peek(Token![::]))
+ {
+ input.parse().map(ForeignItem::Macro)
+ } else {
+ Err(lookahead.error())
+ }?;
+
+ let item_attrs = match &mut item {
+ ForeignItem::Fn(item) => &mut item.attrs,
+ ForeignItem::Static(item) => &mut item.attrs,
+ ForeignItem::Type(item) => &mut item.attrs,
+ ForeignItem::Macro(item) => &mut item.attrs,
+ ForeignItem::Verbatim(_) => return Ok(item),
+ };
+ attrs.append(item_attrs);
+ *item_attrs = attrs;
+
+ Ok(item)
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ForeignItemFn {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let sig: Signature = input.parse()?;
+ let semi_token: Token![;] = input.parse()?;
+ Ok(ForeignItemFn {
+ attrs,
+ vis,
+ sig,
+ semi_token,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ForeignItemStatic {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ForeignItemStatic {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ static_token: input.parse()?,
+ mutability: input.parse()?,
+ ident: input.parse()?,
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ForeignItemType {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ForeignItemType {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ type_token: input.parse()?,
+ ident: input.parse()?,
+ generics: {
+ let mut generics: Generics = input.parse()?;
+ generics.where_clause = input.parse()?;
+ generics
+ },
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ fn parse_foreign_item_type(begin: ParseBuffer, input: ParseStream) -> Result<ForeignItem> {
+ let FlexibleItemType {
+ vis,
+ defaultness: _,
+ type_token,
+ ident,
+ generics,
+ colon_token,
+ bounds: _,
+ ty,
+ semi_token,
+ } = FlexibleItemType::parse(
+ input,
+ TypeDefaultness::Disallowed,
+ WhereClauseLocation::Both,
+ )?;
+
+ if colon_token.is_some() || ty.is_some() {
+ Ok(ForeignItem::Verbatim(verbatim::between(&begin, input)))
+ } else {
+ Ok(ForeignItem::Type(ForeignItemType {
+ attrs: Vec::new(),
+ vis,
+ type_token,
+ ident,
+ generics,
+ semi_token,
+ }))
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ForeignItemMacro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let mac: Macro = input.parse()?;
+ let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
+ None
+ } else {
+ Some(input.parse()?)
+ };
+ Ok(ForeignItemMacro {
+ attrs,
+ mac,
+ semi_token,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemType {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(ItemType {
+ attrs: input.call(Attribute::parse_outer)?,
+ vis: input.parse()?,
+ type_token: input.parse()?,
+ ident: input.parse()?,
+ generics: {
+ let mut generics: Generics = input.parse()?;
+ generics.where_clause = input.parse()?;
+ generics
+ },
+ eq_token: input.parse()?,
+ ty: input.parse()?,
+ semi_token: input.parse()?,
+ })
+ }
+ }
+
+ fn parse_item_type(begin: ParseBuffer, input: ParseStream) -> Result<Item> {
+ let FlexibleItemType {
+ vis,
+ defaultness: _,
+ type_token,
+ ident,
+ generics,
+ colon_token,
+ bounds: _,
+ ty,
+ semi_token,
+ } = FlexibleItemType::parse(
+ input,
+ TypeDefaultness::Disallowed,
+ WhereClauseLocation::BeforeEq,
+ )?;
+
+ let (eq_token, ty) = match ty {
+ Some(ty) if colon_token.is_none() => ty,
+ _ => return Ok(Item::Verbatim(verbatim::between(&begin, input))),
+ };
+
+ Ok(Item::Type(ItemType {
+ attrs: Vec::new(),
+ vis,
+ type_token,
+ ident,
+ generics,
+ eq_token,
+ ty: Box::new(ty),
+ semi_token,
+ }))
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemStruct {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis = input.parse::<Visibility>()?;
+ let struct_token = input.parse::<Token![struct]>()?;
+ let ident = input.parse::<Ident>()?;
+ let generics = input.parse::<Generics>()?;
+ let (where_clause, fields, semi_token) = derive::parsing::data_struct(input)?;
+ Ok(ItemStruct {
+ attrs,
+ vis,
+ struct_token,
+ ident,
+ generics: Generics {
+ where_clause,
+ ..generics
+ },
+ fields,
+ semi_token,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemEnum {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis = input.parse::<Visibility>()?;
+ let enum_token = input.parse::<Token![enum]>()?;
+ let ident = input.parse::<Ident>()?;
+ let generics = input.parse::<Generics>()?;
+ let (where_clause, brace_token, variants) = derive::parsing::data_enum(input)?;
+ Ok(ItemEnum {
+ attrs,
+ vis,
+ enum_token,
+ ident,
+ generics: Generics {
+ where_clause,
+ ..generics
+ },
+ brace_token,
+ variants,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemUnion {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis = input.parse::<Visibility>()?;
+ let union_token = input.parse::<Token![union]>()?;
+ let ident = input.parse::<Ident>()?;
+ let generics = input.parse::<Generics>()?;
+ let (where_clause, fields) = derive::parsing::data_union(input)?;
+ Ok(ItemUnion {
+ attrs,
+ vis,
+ union_token,
+ ident,
+ generics: Generics {
+ where_clause,
+ ..generics
+ },
+ fields,
+ })
+ }
+ }
+
+ fn parse_trait_or_trait_alias(input: ParseStream) -> Result<Item> {
+ let (attrs, vis, trait_token, ident, generics) = parse_start_of_trait_alias(input)?;
+ let lookahead = input.lookahead1();
+ if lookahead.peek(token::Brace)
+ || lookahead.peek(Token![:])
+ || lookahead.peek(Token![where])
+ {
+ let unsafety = None;
+ let auto_token = None;
+ parse_rest_of_trait(
+ input,
+ attrs,
+ vis,
+ unsafety,
+ auto_token,
+ trait_token,
+ ident,
+ generics,
+ )
+ .map(Item::Trait)
+ } else if lookahead.peek(Token![=]) {
+ parse_rest_of_trait_alias(input, attrs, vis, trait_token, ident, generics)
+ .map(Item::TraitAlias)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemTrait {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let outer_attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let unsafety: Option<Token![unsafe]> = input.parse()?;
+ let auto_token: Option<Token![auto]> = input.parse()?;
+ let trait_token: Token![trait] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let generics: Generics = input.parse()?;
+ parse_rest_of_trait(
+ input,
+ outer_attrs,
+ vis,
+ unsafety,
+ auto_token,
+ trait_token,
+ ident,
+ generics,
+ )
+ }
+ }
+
+ fn parse_rest_of_trait(
+ input: ParseStream,
+ mut attrs: Vec<Attribute>,
+ vis: Visibility,
+ unsafety: Option<Token![unsafe]>,
+ auto_token: Option<Token![auto]>,
+ trait_token: Token![trait],
+ ident: Ident,
+ mut generics: Generics,
+ ) -> Result<ItemTrait> {
+ let colon_token: Option<Token![:]> = input.parse()?;
+
+ let mut supertraits = Punctuated::new();
+ if colon_token.is_some() {
+ loop {
+ if input.peek(Token![where]) || input.peek(token::Brace) {
+ break;
+ }
+ supertraits.push_value(input.parse()?);
+ if input.peek(Token![where]) || input.peek(token::Brace) {
+ break;
+ }
+ supertraits.push_punct(input.parse()?);
+ }
+ }
+
+ generics.where_clause = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ attr::parsing::parse_inner(&content, &mut attrs)?;
+ let mut items = Vec::new();
+ while !content.is_empty() {
+ items.push(content.parse()?);
+ }
+
+ Ok(ItemTrait {
+ attrs,
+ vis,
+ unsafety,
+ auto_token,
+ restriction: None,
+ trait_token,
+ ident,
+ generics,
+ colon_token,
+ supertraits,
+ brace_token,
+ items,
+ })
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemTraitAlias {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let (attrs, vis, trait_token, ident, generics) = parse_start_of_trait_alias(input)?;
+ parse_rest_of_trait_alias(input, attrs, vis, trait_token, ident, generics)
+ }
+ }
+
+ fn parse_start_of_trait_alias(
+ input: ParseStream,
+ ) -> Result<(Vec<Attribute>, Visibility, Token![trait], Ident, Generics)> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let trait_token: Token![trait] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let generics: Generics = input.parse()?;
+ Ok((attrs, vis, trait_token, ident, generics))
+ }
+
+ fn parse_rest_of_trait_alias(
+ input: ParseStream,
+ attrs: Vec<Attribute>,
+ vis: Visibility,
+ trait_token: Token![trait],
+ ident: Ident,
+ mut generics: Generics,
+ ) -> Result<ItemTraitAlias> {
+ let eq_token: Token![=] = input.parse()?;
+
+ let mut bounds = Punctuated::new();
+ loop {
+ if input.peek(Token![where]) || input.peek(Token![;]) {
+ break;
+ }
+ bounds.push_value(input.parse()?);
+ if input.peek(Token![where]) || input.peek(Token![;]) {
+ break;
+ }
+ bounds.push_punct(input.parse()?);
+ }
+
+ generics.where_clause = input.parse()?;
+ let semi_token: Token![;] = input.parse()?;
+
+ Ok(ItemTraitAlias {
+ attrs,
+ vis,
+ trait_token,
+ ident,
+ generics,
+ eq_token,
+ bounds,
+ semi_token,
+ })
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TraitItem {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let begin = input.fork();
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let defaultness: Option<Token![default]> = input.parse()?;
+ let ahead = input.fork();
+
+ let lookahead = ahead.lookahead1();
+ let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) {
+ input.parse().map(TraitItem::Fn)
+ } else if lookahead.peek(Token![const]) {
+ let const_token: Token![const] = ahead.parse()?;
+ let lookahead = ahead.lookahead1();
+ if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
+ input.advance_to(&ahead);
+ let ident = input.call(Ident::parse_any)?;
+ let mut generics: Generics = input.parse()?;
+ let colon_token: Token![:] = input.parse()?;
+ let ty: Type = input.parse()?;
+ let default = if let Some(eq_token) = input.parse::<Option<Token![=]>>()? {
+ let expr: Expr = input.parse()?;
+ Some((eq_token, expr))
+ } else {
+ None
+ };
+ generics.where_clause = input.parse()?;
+ let semi_token: Token![;] = input.parse()?;
+ if generics.lt_token.is_none() && generics.where_clause.is_none() {
+ Ok(TraitItem::Const(TraitItemConst {
+ attrs: Vec::new(),
+ const_token,
+ ident,
+ generics,
+ colon_token,
+ ty,
+ default,
+ semi_token,
+ }))
+ } else {
+ return Ok(TraitItem::Verbatim(verbatim::between(&begin, input)));
+ }
+ } else if lookahead.peek(Token![async])
+ || lookahead.peek(Token![unsafe])
+ || lookahead.peek(Token![extern])
+ || lookahead.peek(Token![fn])
+ {
+ input.parse().map(TraitItem::Fn)
+ } else {
+ Err(lookahead.error())
+ }
+ } else if lookahead.peek(Token![type]) {
+ parse_trait_item_type(begin.fork(), input)
+ } else if vis.is_inherited()
+ && defaultness.is_none()
+ && (lookahead.peek(Ident)
+ || lookahead.peek(Token![self])
+ || lookahead.peek(Token![super])
+ || lookahead.peek(Token![crate])
+ || lookahead.peek(Token![::]))
+ {
+ input.parse().map(TraitItem::Macro)
+ } else {
+ Err(lookahead.error())
+ }?;
+
+ match (vis, defaultness) {
+ (Visibility::Inherited, None) => {}
+ _ => return Ok(TraitItem::Verbatim(verbatim::between(&begin, input))),
+ }
+
+ let item_attrs = match &mut item {
+ TraitItem::Const(item) => &mut item.attrs,
+ TraitItem::Fn(item) => &mut item.attrs,
+ TraitItem::Type(item) => &mut item.attrs,
+ TraitItem::Macro(item) => &mut item.attrs,
+ TraitItem::Verbatim(_) => unreachable!(),
+ };
+ attrs.append(item_attrs);
+ *item_attrs = attrs;
+ Ok(item)
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TraitItemConst {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let const_token: Token![const] = input.parse()?;
+
+ let lookahead = input.lookahead1();
+ let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
+ input.call(Ident::parse_any)?
+ } else {
+ return Err(lookahead.error());
+ };
+
+ let colon_token: Token![:] = input.parse()?;
+ let ty: Type = input.parse()?;
+ let default = if input.peek(Token![=]) {
+ let eq_token: Token![=] = input.parse()?;
+ let default: Expr = input.parse()?;
+ Some((eq_token, default))
+ } else {
+ None
+ };
+ let semi_token: Token![;] = input.parse()?;
+
+ Ok(TraitItemConst {
+ attrs,
+ const_token,
+ ident,
+ generics: Generics::default(),
+ colon_token,
+ ty,
+ default,
+ semi_token,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TraitItemFn {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let sig: Signature = input.parse()?;
+
+ let lookahead = input.lookahead1();
+ let (brace_token, stmts, semi_token) = if lookahead.peek(token::Brace) {
+ let content;
+ let brace_token = braced!(content in input);
+ attr::parsing::parse_inner(&content, &mut attrs)?;
+ let stmts = content.call(Block::parse_within)?;
+ (Some(brace_token), stmts, None)
+ } else if lookahead.peek(Token![;]) {
+ let semi_token: Token![;] = input.parse()?;
+ (None, Vec::new(), Some(semi_token))
+ } else {
+ return Err(lookahead.error());
+ };
+
+ Ok(TraitItemFn {
+ attrs,
+ sig,
+ default: brace_token.map(|brace_token| Block { brace_token, stmts }),
+ semi_token,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TraitItemType {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let type_token: Token![type] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let mut generics: Generics = input.parse()?;
+ let (colon_token, bounds) = FlexibleItemType::parse_optional_bounds(input)?;
+ let default = FlexibleItemType::parse_optional_definition(input)?;
+ generics.where_clause = input.parse()?;
+ let semi_token: Token![;] = input.parse()?;
+ Ok(TraitItemType {
+ attrs,
+ type_token,
+ ident,
+ generics,
+ colon_token,
+ bounds,
+ default,
+ semi_token,
+ })
+ }
+ }
+
+ fn parse_trait_item_type(begin: ParseBuffer, input: ParseStream) -> Result<TraitItem> {
+ let FlexibleItemType {
+ vis,
+ defaultness: _,
+ type_token,
+ ident,
+ generics,
+ colon_token,
+ bounds,
+ ty,
+ semi_token,
+ } = FlexibleItemType::parse(
+ input,
+ TypeDefaultness::Disallowed,
+ WhereClauseLocation::AfterEq,
+ )?;
+
+ if vis.is_some() {
+ Ok(TraitItem::Verbatim(verbatim::between(&begin, input)))
+ } else {
+ Ok(TraitItem::Type(TraitItemType {
+ attrs: Vec::new(),
+ type_token,
+ ident,
+ generics,
+ colon_token,
+ bounds,
+ default: ty,
+ semi_token,
+ }))
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TraitItemMacro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let mac: Macro = input.parse()?;
+ let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
+ None
+ } else {
+ Some(input.parse()?)
+ };
+ Ok(TraitItemMacro {
+ attrs,
+ mac,
+ semi_token,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ItemImpl {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_verbatim_impl = false;
+ parse_impl(input, allow_verbatim_impl).map(Option::unwrap)
+ }
+ }
+
+ fn parse_impl(input: ParseStream, allow_verbatim_impl: bool) -> Result<Option<ItemImpl>> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let has_visibility = allow_verbatim_impl && input.parse::<Visibility>()?.is_some();
+ let defaultness: Option<Token![default]> = input.parse()?;
+ let unsafety: Option<Token![unsafe]> = input.parse()?;
+ let impl_token: Token![impl] = input.parse()?;
+
+ let has_generics = input.peek(Token![<])
+ && (input.peek2(Token![>])
+ || input.peek2(Token![#])
+ || (input.peek2(Ident) || input.peek2(Lifetime))
+ && (input.peek3(Token![:])
+ || input.peek3(Token![,])
+ || input.peek3(Token![>])
+ || input.peek3(Token![=]))
+ || input.peek2(Token![const]));
+ let mut generics: Generics = if has_generics {
+ input.parse()?
+ } else {
+ Generics::default()
+ };
+
+ let is_const_impl = allow_verbatim_impl
+ && (input.peek(Token![const]) || input.peek(Token![?]) && input.peek2(Token![const]));
+ if is_const_impl {
+ input.parse::<Option<Token![?]>>()?;
+ input.parse::<Token![const]>()?;
+ }
+
+ let begin = input.fork();
+ let polarity = if input.peek(Token![!]) && !input.peek2(token::Brace) {
+ Some(input.parse::<Token![!]>()?)
+ } else {
+ None
+ };
+
+ #[cfg(not(feature = "printing"))]
+ let first_ty_span = input.span();
+ let mut first_ty: Type = input.parse()?;
+ let self_ty: Type;
+ let trait_;
+
+ let is_impl_for = input.peek(Token![for]);
+ if is_impl_for {
+ let for_token: Token![for] = input.parse()?;
+ let mut first_ty_ref = &first_ty;
+ while let Type::Group(ty) = first_ty_ref {
+ first_ty_ref = &ty.elem;
+ }
+ if let Type::Path(TypePath { qself: None, .. }) = first_ty_ref {
+ while let Type::Group(ty) = first_ty {
+ first_ty = *ty.elem;
+ }
+ if let Type::Path(TypePath { qself: None, path }) = first_ty {
+ trait_ = Some((polarity, path, for_token));
+ } else {
+ unreachable!();
+ }
+ } else if !allow_verbatim_impl {
+ #[cfg(feature = "printing")]
+ return Err(Error::new_spanned(first_ty_ref, "expected trait path"));
+ #[cfg(not(feature = "printing"))]
+ return Err(Error::new(first_ty_span, "expected trait path"));
+ } else {
+ trait_ = None;
+ }
+ self_ty = input.parse()?;
+ } else {
+ trait_ = None;
+ self_ty = if polarity.is_none() {
+ first_ty
+ } else {
+ Type::Verbatim(verbatim::between(&begin, input))
+ };
+ }
+
+ generics.where_clause = input.parse()?;
+
+ let content;
+ let brace_token = braced!(content in input);
+ attr::parsing::parse_inner(&content, &mut attrs)?;
+
+ let mut items = Vec::new();
+ while !content.is_empty() {
+ items.push(content.parse()?);
+ }
+
+ if has_visibility || is_const_impl || is_impl_for && trait_.is_none() {
+ Ok(None)
+ } else {
+ Ok(Some(ItemImpl {
+ attrs,
+ defaultness,
+ unsafety,
+ impl_token,
+ generics,
+ trait_,
+ self_ty: Box::new(self_ty),
+ brace_token,
+ items,
+ }))
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ImplItem {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let begin = input.fork();
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let ahead = input.fork();
+ let vis: Visibility = ahead.parse()?;
+
+ let mut lookahead = ahead.lookahead1();
+ let defaultness = if lookahead.peek(Token![default]) && !ahead.peek2(Token![!]) {
+ let defaultness: Token![default] = ahead.parse()?;
+ lookahead = ahead.lookahead1();
+ Some(defaultness)
+ } else {
+ None
+ };
+
+ let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) {
+ let allow_omitted_body = true;
+ if let Some(item) = parse_impl_item_fn(input, allow_omitted_body)? {
+ Ok(ImplItem::Fn(item))
+ } else {
+ Ok(ImplItem::Verbatim(verbatim::between(&begin, input)))
+ }
+ } else if lookahead.peek(Token![const]) {
+ input.advance_to(&ahead);
+ let const_token: Token![const] = input.parse()?;
+ let lookahead = input.lookahead1();
+ let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
+ input.call(Ident::parse_any)?
+ } else {
+ return Err(lookahead.error());
+ };
+ let mut generics: Generics = input.parse()?;
+ let colon_token: Token![:] = input.parse()?;
+ let ty: Type = input.parse()?;
+ let value = if let Some(eq_token) = input.parse::<Option<Token![=]>>()? {
+ let expr: Expr = input.parse()?;
+ Some((eq_token, expr))
+ } else {
+ None
+ };
+ generics.where_clause = input.parse()?;
+ let semi_token: Token![;] = input.parse()?;
+ return match value {
+ Some((eq_token, expr))
+ if generics.lt_token.is_none() && generics.where_clause.is_none() =>
+ {
+ Ok(ImplItem::Const(ImplItemConst {
+ attrs,
+ vis,
+ defaultness,
+ const_token,
+ ident,
+ generics,
+ colon_token,
+ ty,
+ eq_token,
+ expr,
+ semi_token,
+ }))
+ }
+ _ => Ok(ImplItem::Verbatim(verbatim::between(&begin, input))),
+ };
+ } else if lookahead.peek(Token![type]) {
+ parse_impl_item_type(begin, input)
+ } else if vis.is_inherited()
+ && defaultness.is_none()
+ && (lookahead.peek(Ident)
+ || lookahead.peek(Token![self])
+ || lookahead.peek(Token![super])
+ || lookahead.peek(Token![crate])
+ || lookahead.peek(Token![::]))
+ {
+ input.parse().map(ImplItem::Macro)
+ } else {
+ Err(lookahead.error())
+ }?;
+
+ {
+ let item_attrs = match &mut item {
+ ImplItem::Const(item) => &mut item.attrs,
+ ImplItem::Fn(item) => &mut item.attrs,
+ ImplItem::Type(item) => &mut item.attrs,
+ ImplItem::Macro(item) => &mut item.attrs,
+ ImplItem::Verbatim(_) => return Ok(item),
+ };
+ attrs.append(item_attrs);
+ *item_attrs = attrs;
+ }
+
+ Ok(item)
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ImplItemConst {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let defaultness: Option<Token![default]> = input.parse()?;
+ let const_token: Token![const] = input.parse()?;
+
+ let lookahead = input.lookahead1();
+ let ident = if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
+ input.call(Ident::parse_any)?
+ } else {
+ return Err(lookahead.error());
+ };
+
+ let colon_token: Token![:] = input.parse()?;
+ let ty: Type = input.parse()?;
+ let eq_token: Token![=] = input.parse()?;
+ let expr: Expr = input.parse()?;
+ let semi_token: Token![;] = input.parse()?;
+
+ Ok(ImplItemConst {
+ attrs,
+ vis,
+ defaultness,
+ const_token,
+ ident,
+ generics: Generics::default(),
+ colon_token,
+ ty,
+ eq_token,
+ expr,
+ semi_token,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ImplItemFn {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_omitted_body = false;
+ parse_impl_item_fn(input, allow_omitted_body).map(Option::unwrap)
+ }
+ }
+
+ fn parse_impl_item_fn(
+ input: ParseStream,
+ allow_omitted_body: bool,
+ ) -> Result<Option<ImplItemFn>> {
+ let mut attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let defaultness: Option<Token![default]> = input.parse()?;
+ let sig: Signature = input.parse()?;
+
+ // Accept functions without a body in an impl block because rustc's
+ // *parser* does not reject them (the compilation error is emitted later
+ // than parsing) and it can be useful for macro DSLs.
+ if allow_omitted_body && input.parse::<Option<Token![;]>>()?.is_some() {
+ return Ok(None);
+ }
+
+ let content;
+ let brace_token = braced!(content in input);
+ attrs.extend(content.call(Attribute::parse_inner)?);
+ let block = Block {
+ brace_token,
+ stmts: content.call(Block::parse_within)?,
+ };
+
+ Ok(Some(ImplItemFn {
+ attrs,
+ vis,
+ defaultness,
+ sig,
+ block,
+ }))
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ImplItemType {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let defaultness: Option<Token![default]> = input.parse()?;
+ let type_token: Token![type] = input.parse()?;
+ let ident: Ident = input.parse()?;
+ let mut generics: Generics = input.parse()?;
+ let eq_token: Token![=] = input.parse()?;
+ let ty: Type = input.parse()?;
+ generics.where_clause = input.parse()?;
+ let semi_token: Token![;] = input.parse()?;
+ Ok(ImplItemType {
+ attrs,
+ vis,
+ defaultness,
+ type_token,
+ ident,
+ generics,
+ eq_token,
+ ty,
+ semi_token,
+ })
+ }
+ }
+
+ fn parse_impl_item_type(begin: ParseBuffer, input: ParseStream) -> Result<ImplItem> {
+ let FlexibleItemType {
+ vis,
+ defaultness,
+ type_token,
+ ident,
+ generics,
+ colon_token,
+ bounds: _,
+ ty,
+ semi_token,
+ } = FlexibleItemType::parse(
+ input,
+ TypeDefaultness::Optional,
+ WhereClauseLocation::AfterEq,
+ )?;
+
+ let (eq_token, ty) = match ty {
+ Some(ty) if colon_token.is_none() => ty,
+ _ => return Ok(ImplItem::Verbatim(verbatim::between(&begin, input))),
+ };
+
+ Ok(ImplItem::Type(ImplItemType {
+ attrs: Vec::new(),
+ vis,
+ defaultness,
+ type_token,
+ ident,
+ generics,
+ eq_token,
+ ty,
+ semi_token,
+ }))
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ImplItemMacro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let mac: Macro = input.parse()?;
+ let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
+ None
+ } else {
+ Some(input.parse()?)
+ };
+ Ok(ImplItemMacro {
+ attrs,
+ mac,
+ semi_token,
+ })
+ }
+ }
+
+ impl Visibility {
+ fn is_inherited(&self) -> bool {
+ match self {
+ Visibility::Inherited => true,
+ _ => false,
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for StaticMutability {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut_token: Option<Token![mut]> = input.parse()?;
+ Ok(mut_token.map_or(StaticMutability::None, StaticMutability::Mut))
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use crate::attr::FilterAttrs;
+ use crate::data::Fields;
+ use crate::item::{
+ ForeignItemFn, ForeignItemMacro, ForeignItemStatic, ForeignItemType, ImplItemConst,
+ ImplItemFn, ImplItemMacro, ImplItemType, ItemConst, ItemEnum, ItemExternCrate, ItemFn,
+ ItemForeignMod, ItemImpl, ItemMacro, ItemMod, ItemStatic, ItemStruct, ItemTrait,
+ ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver, Signature, StaticMutability,
+ TraitItemConst, TraitItemFn, TraitItemMacro, TraitItemType, UseGlob, UseGroup, UseName,
+ UsePath, UseRename, Variadic,
+ };
+ use crate::mac::MacroDelimiter;
+ use crate::print::TokensOrDefault;
+ use crate::ty::Type;
+ use proc_macro2::TokenStream;
+ use quote::{ToTokens, TokenStreamExt};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemExternCrate {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.extern_token.to_tokens(tokens);
+ self.crate_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ if let Some((as_token, rename)) = &self.rename {
+ as_token.to_tokens(tokens);
+ rename.to_tokens(tokens);
+ }
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemUse {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.use_token.to_tokens(tokens);
+ self.leading_colon.to_tokens(tokens);
+ self.tree.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemStatic {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.static_token.to_tokens(tokens);
+ self.mutability.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ self.eq_token.to_tokens(tokens);
+ self.expr.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemConst {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.const_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ self.eq_token.to_tokens(tokens);
+ self.expr.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemFn {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.sig.to_tokens(tokens);
+ self.block.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(self.attrs.inner());
+ tokens.append_all(&self.block.stmts);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemMod {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.unsafety.to_tokens(tokens);
+ self.mod_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ if let Some((brace, items)) = &self.content {
+ brace.surround(tokens, |tokens| {
+ tokens.append_all(self.attrs.inner());
+ tokens.append_all(items);
+ });
+ } else {
+ TokensOrDefault(&self.semi).to_tokens(tokens);
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemForeignMod {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.unsafety.to_tokens(tokens);
+ self.abi.to_tokens(tokens);
+ self.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(self.attrs.inner());
+ tokens.append_all(&self.items);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemType {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.type_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.generics.where_clause.to_tokens(tokens);
+ self.eq_token.to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemEnum {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.enum_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.generics.where_clause.to_tokens(tokens);
+ self.brace_token.surround(tokens, |tokens| {
+ self.variants.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemStruct {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.struct_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ match &self.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(&self.semi_token).to_tokens(tokens);
+ }
+ Fields::Unit => {
+ self.generics.where_clause.to_tokens(tokens);
+ TokensOrDefault(&self.semi_token).to_tokens(tokens);
+ }
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemUnion {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.union_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.generics.where_clause.to_tokens(tokens);
+ self.fields.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemTrait {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.unsafety.to_tokens(tokens);
+ self.auto_token.to_tokens(tokens);
+ self.trait_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ if !self.supertraits.is_empty() {
+ TokensOrDefault(&self.colon_token).to_tokens(tokens);
+ self.supertraits.to_tokens(tokens);
+ }
+ self.generics.where_clause.to_tokens(tokens);
+ self.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(self.attrs.inner());
+ tokens.append_all(&self.items);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemTraitAlias {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.trait_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.eq_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ self.generics.where_clause.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemImpl {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.defaultness.to_tokens(tokens);
+ self.unsafety.to_tokens(tokens);
+ self.impl_token.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ if let Some((polarity, path, for_token)) = &self.trait_ {
+ polarity.to_tokens(tokens);
+ path.to_tokens(tokens);
+ for_token.to_tokens(tokens);
+ }
+ self.self_ty.to_tokens(tokens);
+ self.generics.where_clause.to_tokens(tokens);
+ self.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(self.attrs.inner());
+ tokens.append_all(&self.items);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ItemMacro {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.mac.path.to_tokens(tokens);
+ self.mac.bang_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ match &self.mac.delimiter {
+ MacroDelimiter::Paren(paren) => {
+ paren.surround(tokens, |tokens| self.mac.tokens.to_tokens(tokens));
+ }
+ MacroDelimiter::Brace(brace) => {
+ brace.surround(tokens, |tokens| self.mac.tokens.to_tokens(tokens));
+ }
+ MacroDelimiter::Bracket(bracket) => {
+ bracket.surround(tokens, |tokens| self.mac.tokens.to_tokens(tokens));
+ }
+ }
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for UsePath {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.ident.to_tokens(tokens);
+ self.colon2_token.to_tokens(tokens);
+ self.tree.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for UseName {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.ident.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for UseRename {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.ident.to_tokens(tokens);
+ self.as_token.to_tokens(tokens);
+ self.rename.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for UseGlob {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.star_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for UseGroup {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.brace_token.surround(tokens, |tokens| {
+ self.items.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TraitItemConst {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.const_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ 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);
+ }
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TraitItemFn {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.sig.to_tokens(tokens);
+ match &self.default {
+ Some(block) => {
+ block.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(self.attrs.inner());
+ tokens.append_all(&block.stmts);
+ });
+ }
+ None => {
+ TokensOrDefault(&self.semi_token).to_tokens(tokens);
+ }
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TraitItemType {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.type_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ if !self.bounds.is_empty() {
+ TokensOrDefault(&self.colon_token).to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ }
+ if let Some((eq_token, default)) = &self.default {
+ eq_token.to_tokens(tokens);
+ default.to_tokens(tokens);
+ }
+ self.generics.where_clause.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TraitItemMacro {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.mac.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ImplItemConst {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.defaultness.to_tokens(tokens);
+ self.const_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ self.eq_token.to_tokens(tokens);
+ self.expr.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ImplItemFn {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.defaultness.to_tokens(tokens);
+ self.sig.to_tokens(tokens);
+ self.block.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(self.attrs.inner());
+ tokens.append_all(&self.block.stmts);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ImplItemType {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.defaultness.to_tokens(tokens);
+ self.type_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.eq_token.to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ self.generics.where_clause.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ImplItemMacro {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.mac.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ForeignItemFn {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.sig.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ForeignItemStatic {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.static_token.to_tokens(tokens);
+ self.mutability.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ForeignItemType {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.vis.to_tokens(tokens);
+ self.type_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.generics.where_clause.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ForeignItemMacro {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.mac.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Signature {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.constness.to_tokens(tokens);
+ self.asyncness.to_tokens(tokens);
+ self.unsafety.to_tokens(tokens);
+ self.abi.to_tokens(tokens);
+ self.fn_token.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.paren_token.surround(tokens, |tokens| {
+ self.inputs.to_tokens(tokens);
+ if let Some(variadic) = &self.variadic {
+ if !self.inputs.empty_or_trailing() {
+ <Token![,]>::default().to_tokens(tokens);
+ }
+ variadic.to_tokens(tokens);
+ }
+ });
+ self.output.to_tokens(tokens);
+ self.generics.where_clause.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Receiver {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ if let Some((ampersand, lifetime)) = &self.reference {
+ ampersand.to_tokens(tokens);
+ lifetime.to_tokens(tokens);
+ }
+ self.mutability.to_tokens(tokens);
+ self.self_token.to_tokens(tokens);
+ if let Some(colon_token) = &self.colon_token {
+ colon_token.to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ } else {
+ let consistent = match (&self.reference, &self.mutability, &*self.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,
+ }
+ }
+ (None, _, Type::Path(ty)) => ty.qself.is_none() && ty.path.is_ident("Self"),
+ _ => false,
+ };
+ if !consistent {
+ <Token![:]>::default().to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ }
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Variadic {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ if let Some((pat, colon)) = &self.pat {
+ pat.to_tokens(tokens);
+ colon.to_tokens(tokens);
+ }
+ self.dots.to_tokens(tokens);
+ self.comma.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for StaticMutability {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ StaticMutability::None => {}
+ StaticMutability::Mut(mut_token) => mut_token.to_tokens(tokens),
+ }
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/lib.rs b/rust/hw/char/pl011/vendor/syn/src/lib.rs
new file mode 100644
index 0000000000..a8372e8079
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/lib.rs
@@ -0,0 +1,1019 @@
+//! [![github]](https://github.com/dtolnay/syn) [![crates-io]](https://crates.io/crates/syn) [![docs-rs]](crate)
+//!
+//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
+//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
+//!
+//! <br>
+//!
+//! 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 complete syntax tree that can
+//! represent any valid Rust source code. 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<T>`. 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`]: File
+//! [`syn::Item`]: Item
+//! [`syn::Expr`]: Expr
+//! [`syn::Type`]: Type
+//! [`syn::DeriveInput`]: DeriveInput
+//! [parser functions]: mod@parse
+//!
+//! <br>
+//!
+//! # 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`]: proc_macro::TokenStream
+//!
+//! ```toml
+//! [dependencies]
+//! syn = "2.0"
+//! quote = "1.0"
+//!
+//! [lib]
+//! proc-macro = true
+//! ```
+//!
+//! ```
+//! # extern crate proc_macro;
+//! #
+//! use proc_macro::TokenStream;
+//! use quote::quote;
+//! use syn::{parse_macro_input, DeriveInput};
+//!
+//! # const IGNORE_TOKENS: &str = stringify! {
+//! #[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`]: https://github.com/dtolnay/syn/tree/master/examples/heapsize
+//!
+//! ```
+//! 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.
+//!
+//! ```
+//! # const IGNORE_TOKENS: &str = stringify! {
+//! #[derive(HeapSize)]
+//! # };
+//! struct Demo<'a, T: ?Sized> {
+//! a: Box<T>,
+//! b: u8,
+//! c: &'a str,
+//! d: String,
+//! }
+//! ```
+//!
+//! <p><br></p>
+//!
+//! # 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`.
+//!
+//! ```
+//! # const IGNORE_TOKENS: &str = stringify! {
+//! #[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.
+//!
+//! ```text
+//! error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied
+//! --> src/main.rs:7:5
+//! |
+//! 7 | bad: std::thread::Thread,
+//! | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `Thread`
+//! ```
+//!
+//! <br>
+//!
+//! # 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`]: https://github.com/dtolnay/syn/tree/master/examples/lazy-static
+//!
+//! The example reimplements the popular `lazy_static` crate from crates.io as a
+//! procedural macro.
+//!
+//! ```
+//! # macro_rules! lazy_static {
+//! # ($($tt:tt)*) => {}
+//! # }
+//! #
+//! 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.
+//!
+//! ```text
+//! warning: come on, pick a more creative name
+//! --> src/main.rs:10:16
+//! |
+//! 10 | static ref FOO: String = "lazy_static".to_owned();
+//! | ^^^
+//! ```
+//!
+//! <br>
+//!
+//! # 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
+//!
+//! <br>
+//!
+//! # Debugging
+//!
+//! When developing a procedural macro it can be helpful to look at what the
+//! generated code looks like. Use `cargo rustc -- -Zunstable-options
+//! --pretty=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/
+//!
+//! <br>
+//!
+//! # 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.
+
+// Syn types in rustdoc of other crates get linked to here.
+#![doc(html_root_url = "https://docs.rs/syn/2.0.66")]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![deny(unsafe_op_in_unsafe_fn)]
+#![allow(non_camel_case_types)]
+#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]
+#![allow(
+ clippy::bool_to_int_with_if,
+ clippy::cast_lossless,
+ clippy::cast_possible_truncation,
+ clippy::cast_possible_wrap,
+ clippy::cast_ptr_alignment,
+ clippy::default_trait_access,
+ clippy::derivable_impls,
+ clippy::diverging_sub_expression,
+ clippy::doc_markdown,
+ clippy::expl_impl_clone_on_copy,
+ clippy::explicit_auto_deref,
+ clippy::if_not_else,
+ clippy::inherent_to_string,
+ clippy::into_iter_without_iter,
+ clippy::items_after_statements,
+ clippy::large_enum_variant,
+ clippy::let_underscore_untyped, // https://github.com/rust-lang/rust-clippy/issues/10410
+ clippy::manual_assert,
+ clippy::manual_let_else,
+ clippy::manual_map,
+ clippy::match_like_matches_macro,
+ clippy::match_on_vec_items,
+ clippy::match_same_arms,
+ clippy::match_wildcard_for_single_variants, // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984
+ clippy::missing_errors_doc,
+ clippy::missing_panics_doc,
+ clippy::module_name_repetitions,
+ clippy::must_use_candidate,
+ clippy::needless_doctest_main,
+ clippy::needless_pass_by_value,
+ clippy::never_loop,
+ clippy::range_plus_one,
+ clippy::redundant_else,
+ clippy::return_self_not_must_use,
+ clippy::similar_names,
+ clippy::single_match_else,
+ clippy::struct_excessive_bools,
+ clippy::too_many_arguments,
+ clippy::too_many_lines,
+ clippy::trivially_copy_pass_by_ref,
+ clippy::unconditional_recursion, // https://github.com/rust-lang/rust-clippy/issues/12133
+ clippy::uninhabited_references,
+ clippy::uninlined_format_args,
+ clippy::unnecessary_box_returns,
+ clippy::unnecessary_unwrap,
+ clippy::used_underscore_binding,
+ clippy::wildcard_imports,
+)]
+
+#[cfg(feature = "proc-macro")]
+extern crate proc_macro;
+
+#[macro_use]
+mod macros;
+
+#[cfg(feature = "parsing")]
+#[macro_use]
+mod group;
+
+#[macro_use]
+pub mod token;
+
+#[cfg(any(feature = "full", feature = "derive"))]
+mod attr;
+#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+pub use crate::attr::{AttrStyle, Attribute, Meta, MetaList, MetaNameValue};
+
+mod bigint;
+
+#[cfg(feature = "parsing")]
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+pub mod buffer;
+
+#[cfg(any(
+ all(feature = "parsing", feature = "full"),
+ all(feature = "printing", any(feature = "full", feature = "derive")),
+))]
+mod classify;
+
+mod custom_keyword;
+
+mod custom_punctuation;
+
+#[cfg(any(feature = "full", feature = "derive"))]
+mod data;
+#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+pub use crate::data::{Field, Fields, FieldsNamed, FieldsUnnamed, Variant};
+
+#[cfg(any(feature = "full", feature = "derive"))]
+mod derive;
+#[cfg(feature = "derive")]
+#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
+pub use crate::derive::{Data, DataEnum, DataStruct, DataUnion, DeriveInput};
+
+mod drops;
+
+mod error;
+pub use crate::error::{Error, Result};
+
+#[cfg(any(feature = "full", feature = "derive"))]
+mod expr;
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub use crate::expr::{Arm, Label, RangeLimits};
+#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+pub use crate::expr::{
+ Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprIndex, ExprLit, ExprMacro, ExprMethodCall,
+ ExprParen, ExprPath, ExprReference, ExprStruct, ExprUnary, FieldValue, Index, Member,
+};
+#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub use crate::expr::{
+ ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure, ExprConst,
+ ExprContinue, ExprForLoop, ExprGroup, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch,
+ ExprRange, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprTuple, ExprUnsafe, ExprWhile,
+ ExprYield,
+};
+
+#[cfg(feature = "parsing")]
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+pub mod ext;
+
+#[cfg(feature = "full")]
+mod file;
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub use crate::file::File;
+
+#[cfg(all(feature = "full", feature = "printing"))]
+mod fixup;
+
+#[cfg(any(feature = "full", feature = "derive"))]
+mod generics;
+#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+pub use crate::generics::{
+ BoundLifetimes, ConstParam, GenericParam, Generics, LifetimeParam, PredicateLifetime,
+ PredicateType, TraitBound, TraitBoundModifier, TypeParam, TypeParamBound, WhereClause,
+ WherePredicate,
+};
+#[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))]
+#[cfg_attr(
+ docsrs,
+ doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
+)]
+pub use crate::generics::{ImplGenerics, Turbofish, TypeGenerics};
+
+mod ident;
+#[doc(inline)]
+pub use crate::ident::Ident;
+
+#[cfg(feature = "full")]
+mod item;
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub use crate::item::{
+ FnArg, ForeignItem, ForeignItemFn, ForeignItemMacro, ForeignItemStatic, ForeignItemType,
+ ImplItem, ImplItemConst, ImplItemFn, ImplItemMacro, ImplItemType, ImplRestriction, Item,
+ ItemConst, ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMod,
+ ItemStatic, ItemStruct, ItemTrait, ItemTraitAlias, ItemType, ItemUnion, ItemUse, Receiver,
+ Signature, StaticMutability, TraitItem, TraitItemConst, TraitItemFn, TraitItemMacro,
+ TraitItemType, UseGlob, UseGroup, UseName, UsePath, UseRename, UseTree, Variadic,
+};
+
+mod lifetime;
+#[doc(inline)]
+pub use crate::lifetime::Lifetime;
+
+mod lit;
+#[doc(hidden)] // https://github.com/dtolnay/syn/issues/1566
+pub use crate::lit::StrStyle;
+#[doc(inline)]
+pub use crate::lit::{
+ Lit, LitBool, LitByte, LitByteStr, LitCStr, LitChar, LitFloat, LitInt, LitStr,
+};
+
+#[cfg(feature = "parsing")]
+mod lookahead;
+
+#[cfg(any(feature = "full", feature = "derive"))]
+mod mac;
+#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+pub use crate::mac::{Macro, MacroDelimiter};
+
+#[cfg(all(feature = "parsing", any(feature = "full", feature = "derive")))]
+#[cfg_attr(
+ docsrs,
+ doc(cfg(all(feature = "parsing", any(feature = "full", feature = "derive"))))
+)]
+pub mod meta;
+
+#[cfg(any(feature = "full", feature = "derive"))]
+mod op;
+#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+pub use crate::op::{BinOp, UnOp};
+
+#[cfg(feature = "parsing")]
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+pub mod parse;
+
+#[cfg(all(feature = "parsing", feature = "proc-macro"))]
+mod parse_macro_input;
+
+#[cfg(all(feature = "parsing", feature = "printing"))]
+mod parse_quote;
+
+#[cfg(feature = "full")]
+mod pat;
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub use crate::pat::{
+ FieldPat, Pat, PatConst, PatIdent, PatLit, PatMacro, PatOr, PatParen, PatPath, PatRange,
+ PatReference, PatRest, PatSlice, PatStruct, PatTuple, PatTupleStruct, PatType, PatWild,
+};
+
+#[cfg(any(feature = "full", feature = "derive"))]
+mod path;
+#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+pub use crate::path::{
+ AngleBracketedGenericArguments, AssocConst, AssocType, Constraint, GenericArgument,
+ ParenthesizedGenericArguments, Path, PathArguments, PathSegment, QSelf,
+};
+
+#[cfg(all(
+ any(feature = "full", feature = "derive"),
+ any(feature = "parsing", feature = "printing")
+))]
+mod precedence;
+
+#[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))]
+mod print;
+
+pub mod punctuated;
+
+#[cfg(any(feature = "full", feature = "derive"))]
+mod restriction;
+#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+pub use crate::restriction::{FieldMutability, VisRestricted, Visibility};
+
+mod sealed;
+
+mod span;
+
+#[cfg(all(feature = "parsing", feature = "printing"))]
+#[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "printing"))))]
+pub mod spanned;
+
+#[cfg(feature = "full")]
+mod stmt;
+#[cfg(feature = "full")]
+#[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+pub use crate::stmt::{Block, Local, LocalInit, Stmt, StmtMacro};
+
+mod thread;
+
+#[cfg(all(any(feature = "full", feature = "derive"), feature = "extra-traits"))]
+mod tt;
+
+#[cfg(any(feature = "full", feature = "derive"))]
+mod ty;
+#[cfg(any(feature = "full", feature = "derive"))]
+#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+pub use crate::ty::{
+ Abi, BareFnArg, BareVariadic, ReturnType, Type, TypeArray, TypeBareFn, TypeGroup,
+ TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr, TypeReference,
+ TypeSlice, TypeTraitObject, TypeTuple,
+};
+
+#[cfg(all(any(feature = "full", feature = "derive"), feature = "parsing"))]
+mod verbatim;
+
+#[cfg(all(feature = "parsing", feature = "full"))]
+mod whitespace;
+
+mod gen {
+ /// Syntax tree traversal to transform the nodes of an owned syntax tree.
+ ///
+ /// Each method of the [`Fold`] trait is a hook that can be overridden to
+ /// customize the behavior when transforming the corresponding type of node.
+ /// By default, every method recursively visits the substructure of the
+ /// input by invoking the right visitor method of each of its fields.
+ ///
+ /// [`Fold`]: fold::Fold
+ ///
+ /// ```
+ /// # use syn::{Attribute, BinOp, Expr, ExprBinary};
+ /// #
+ /// pub trait Fold {
+ /// /* ... */
+ ///
+ /// fn fold_expr_binary(&mut self, node: ExprBinary) -> ExprBinary {
+ /// fold_expr_binary(self, node)
+ /// }
+ ///
+ /// /* ... */
+ /// # fn fold_attribute(&mut self, node: Attribute) -> Attribute;
+ /// # fn fold_expr(&mut self, node: Expr) -> Expr;
+ /// # fn fold_bin_op(&mut self, node: BinOp) -> BinOp;
+ /// }
+ ///
+ /// pub fn fold_expr_binary<V>(v: &mut V, node: ExprBinary) -> ExprBinary
+ /// where
+ /// V: Fold + ?Sized,
+ /// {
+ /// ExprBinary {
+ /// attrs: node
+ /// .attrs
+ /// .into_iter()
+ /// .map(|attr| v.fold_attribute(attr))
+ /// .collect(),
+ /// left: Box::new(v.fold_expr(*node.left)),
+ /// op: v.fold_bin_op(node.op),
+ /// right: Box::new(v.fold_expr(*node.right)),
+ /// }
+ /// }
+ ///
+ /// /* ... */
+ /// ```
+ ///
+ /// <br>
+ ///
+ /// # Example
+ ///
+ /// This fold inserts parentheses to fully parenthesizes any expression.
+ ///
+ /// ```
+ /// // [dependencies]
+ /// // quote = "1.0"
+ /// // syn = { version = "2.0", features = ["fold", "full"] }
+ ///
+ /// use quote::quote;
+ /// use syn::fold::{fold_expr, Fold};
+ /// use syn::{token, Expr, ExprParen};
+ ///
+ /// struct ParenthesizeEveryExpr;
+ ///
+ /// impl Fold for ParenthesizeEveryExpr {
+ /// fn fold_expr(&mut self, expr: Expr) -> Expr {
+ /// Expr::Paren(ExprParen {
+ /// attrs: Vec::new(),
+ /// expr: Box::new(fold_expr(self, expr)),
+ /// paren_token: token::Paren::default(),
+ /// })
+ /// }
+ /// }
+ ///
+ /// fn main() {
+ /// let code = quote! { a() + b(1) * c.d };
+ /// let expr: Expr = syn::parse2(code).unwrap();
+ /// let parenthesized = ParenthesizeEveryExpr.fold_expr(expr);
+ /// println!("{}", quote!(#parenthesized));
+ ///
+ /// // Output: (((a)()) + (((b)((1))) * ((c).d)))
+ /// }
+ /// ```
+ #[cfg(feature = "fold")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "fold")))]
+ #[rustfmt::skip]
+ pub mod fold;
+
+ /// Syntax tree traversal to walk a shared borrow of a syntax tree.
+ ///
+ /// Each method of the [`Visit`] trait is a hook that can be overridden to
+ /// customize the behavior when visiting the corresponding type of node. By
+ /// default, every method recursively visits the substructure of the input
+ /// by invoking the right visitor method of each of its fields.
+ ///
+ /// [`Visit`]: visit::Visit
+ ///
+ /// ```
+ /// # use syn::{Attribute, BinOp, Expr, ExprBinary};
+ /// #
+ /// pub trait Visit<'ast> {
+ /// /* ... */
+ ///
+ /// fn visit_expr_binary(&mut self, node: &'ast ExprBinary) {
+ /// visit_expr_binary(self, node);
+ /// }
+ ///
+ /// /* ... */
+ /// # fn visit_attribute(&mut self, node: &'ast Attribute);
+ /// # fn visit_expr(&mut self, node: &'ast Expr);
+ /// # fn visit_bin_op(&mut self, node: &'ast BinOp);
+ /// }
+ ///
+ /// pub fn visit_expr_binary<'ast, V>(v: &mut V, node: &'ast ExprBinary)
+ /// where
+ /// V: Visit<'ast> + ?Sized,
+ /// {
+ /// for attr in &node.attrs {
+ /// v.visit_attribute(attr);
+ /// }
+ /// v.visit_expr(&*node.left);
+ /// v.visit_bin_op(&node.op);
+ /// v.visit_expr(&*node.right);
+ /// }
+ ///
+ /// /* ... */
+ /// ```
+ ///
+ /// <br>
+ ///
+ /// # Example
+ ///
+ /// This visitor will print the name of every freestanding function in the
+ /// syntax tree, including nested functions.
+ ///
+ /// ```
+ /// // [dependencies]
+ /// // quote = "1.0"
+ /// // syn = { version = "2.0", features = ["full", "visit"] }
+ ///
+ /// use quote::quote;
+ /// use syn::visit::{self, Visit};
+ /// use syn::{File, ItemFn};
+ ///
+ /// struct FnVisitor;
+ ///
+ /// impl<'ast> Visit<'ast> for FnVisitor {
+ /// fn visit_item_fn(&mut self, node: &'ast ItemFn) {
+ /// println!("Function with name={}", node.sig.ident);
+ ///
+ /// // Delegate to the default impl to visit any nested functions.
+ /// visit::visit_item_fn(self, node);
+ /// }
+ /// }
+ ///
+ /// fn main() {
+ /// let code = quote! {
+ /// pub fn f() {
+ /// fn g() {}
+ /// }
+ /// };
+ ///
+ /// let syntax_tree: File = syn::parse2(code).unwrap();
+ /// FnVisitor.visit_file(&syntax_tree);
+ /// }
+ /// ```
+ ///
+ /// The `'ast` lifetime on the input references means that the syntax tree
+ /// outlives the complete recursive visit call, so the visitor is allowed to
+ /// hold on to references into the syntax tree.
+ ///
+ /// ```
+ /// use quote::quote;
+ /// use syn::visit::{self, Visit};
+ /// use syn::{File, ItemFn};
+ ///
+ /// struct FnVisitor<'ast> {
+ /// functions: Vec<&'ast ItemFn>,
+ /// }
+ ///
+ /// impl<'ast> Visit<'ast> for FnVisitor<'ast> {
+ /// fn visit_item_fn(&mut self, node: &'ast ItemFn) {
+ /// self.functions.push(node);
+ /// visit::visit_item_fn(self, node);
+ /// }
+ /// }
+ ///
+ /// fn main() {
+ /// let code = quote! {
+ /// pub fn f() {
+ /// fn g() {}
+ /// }
+ /// };
+ ///
+ /// let syntax_tree: File = syn::parse2(code).unwrap();
+ /// let mut visitor = FnVisitor { functions: Vec::new() };
+ /// visitor.visit_file(&syntax_tree);
+ /// for f in visitor.functions {
+ /// println!("Function with name={}", f.sig.ident);
+ /// }
+ /// }
+ /// ```
+ #[cfg(feature = "visit")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "visit")))]
+ #[rustfmt::skip]
+ pub mod visit;
+
+ /// Syntax tree traversal to mutate an exclusive borrow of a syntax tree in
+ /// place.
+ ///
+ /// Each method of the [`VisitMut`] trait is a hook that can be overridden
+ /// to customize the behavior when mutating the corresponding type of node.
+ /// By default, every method recursively visits the substructure of the
+ /// input by invoking the right visitor method of each of its fields.
+ ///
+ /// [`VisitMut`]: visit_mut::VisitMut
+ ///
+ /// ```
+ /// # use syn::{Attribute, BinOp, Expr, ExprBinary};
+ /// #
+ /// pub trait VisitMut {
+ /// /* ... */
+ ///
+ /// fn visit_expr_binary_mut(&mut self, node: &mut ExprBinary) {
+ /// visit_expr_binary_mut(self, node);
+ /// }
+ ///
+ /// /* ... */
+ /// # fn visit_attribute_mut(&mut self, node: &mut Attribute);
+ /// # fn visit_expr_mut(&mut self, node: &mut Expr);
+ /// # fn visit_bin_op_mut(&mut self, node: &mut BinOp);
+ /// }
+ ///
+ /// pub fn visit_expr_binary_mut<V>(v: &mut V, node: &mut ExprBinary)
+ /// where
+ /// V: VisitMut + ?Sized,
+ /// {
+ /// for attr in &mut node.attrs {
+ /// v.visit_attribute_mut(attr);
+ /// }
+ /// v.visit_expr_mut(&mut *node.left);
+ /// v.visit_bin_op_mut(&mut node.op);
+ /// v.visit_expr_mut(&mut *node.right);
+ /// }
+ ///
+ /// /* ... */
+ /// ```
+ ///
+ /// <br>
+ ///
+ /// # Example
+ ///
+ /// This mut visitor replace occurrences of u256 suffixed integer literals
+ /// like `999u256` with a macro invocation `bigint::u256!(999)`.
+ ///
+ /// ```
+ /// // [dependencies]
+ /// // quote = "1.0"
+ /// // syn = { version = "2.0", features = ["full", "visit-mut"] }
+ ///
+ /// use quote::quote;
+ /// use syn::visit_mut::{self, VisitMut};
+ /// use syn::{parse_quote, Expr, File, Lit, LitInt};
+ ///
+ /// struct BigintReplace;
+ ///
+ /// impl VisitMut for BigintReplace {
+ /// fn visit_expr_mut(&mut self, node: &mut Expr) {
+ /// if let Expr::Lit(expr) = &node {
+ /// if let Lit::Int(int) = &expr.lit {
+ /// if int.suffix() == "u256" {
+ /// let digits = int.base10_digits();
+ /// let unsuffixed: LitInt = syn::parse_str(digits).unwrap();
+ /// *node = parse_quote!(bigint::u256!(#unsuffixed));
+ /// return;
+ /// }
+ /// }
+ /// }
+ ///
+ /// // Delegate to the default impl to visit nested expressions.
+ /// visit_mut::visit_expr_mut(self, node);
+ /// }
+ /// }
+ ///
+ /// fn main() {
+ /// let code = quote! {
+ /// fn main() {
+ /// let _ = 999u256;
+ /// }
+ /// };
+ ///
+ /// let mut syntax_tree: File = syn::parse2(code).unwrap();
+ /// BigintReplace.visit_file_mut(&mut syntax_tree);
+ /// println!("{}", quote!(#syntax_tree));
+ /// }
+ /// ```
+ #[cfg(feature = "visit-mut")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "visit-mut")))]
+ #[rustfmt::skip]
+ pub mod visit_mut;
+
+ #[cfg(feature = "clone-impls")]
+ #[rustfmt::skip]
+ mod clone;
+
+ #[cfg(feature = "extra-traits")]
+ #[rustfmt::skip]
+ mod debug;
+
+ #[cfg(feature = "extra-traits")]
+ #[rustfmt::skip]
+ mod eq;
+
+ #[cfg(feature = "extra-traits")]
+ #[rustfmt::skip]
+ mod hash;
+}
+
+#[cfg(feature = "fold")]
+#[cfg_attr(docsrs, doc(cfg(feature = "fold")))]
+pub use crate::gen::fold;
+
+#[cfg(feature = "visit")]
+#[cfg_attr(docsrs, doc(cfg(feature = "visit")))]
+pub use crate::gen::visit;
+
+#[cfg(feature = "visit-mut")]
+#[cfg_attr(docsrs, doc(cfg(feature = "visit-mut")))]
+pub use crate::gen::visit_mut;
+
+// Not public API.
+#[doc(hidden)]
+#[path = "export.rs"]
+pub mod __private;
+
+/// Parse tokens of source code into the chosen syntax tree node.
+///
+/// This is preferred over parsing a string because tokens are able to preserve
+/// information about where in the user's code they were originally written (the
+/// "span" of the token), possibly allowing the compiler to produce better error
+/// messages.
+///
+/// This function parses a `proc_macro::TokenStream` which is the type used for
+/// interop with the compiler in a procedural macro. To parse a
+/// `proc_macro2::TokenStream`, use [`syn::parse2`] instead.
+///
+/// [`syn::parse2`]: parse2
+///
+/// # Examples
+///
+/// ```
+/// # extern crate proc_macro;
+/// #
+/// use proc_macro::TokenStream;
+/// use quote::quote;
+/// use syn::DeriveInput;
+///
+/// # const IGNORE_TOKENS: &str = stringify! {
+/// #[proc_macro_derive(MyMacro)]
+/// # };
+/// pub fn my_macro(input: TokenStream) -> TokenStream {
+/// // Parse the tokens into a syntax tree
+/// let ast: DeriveInput = syn::parse(input).unwrap();
+///
+/// // Build the output, possibly using quasi-quotation
+/// let expanded = quote! {
+/// /* ... */
+/// };
+///
+/// // Convert into a token stream and return it
+/// expanded.into()
+/// }
+/// ```
+#[cfg(all(feature = "parsing", feature = "proc-macro"))]
+#[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "proc-macro"))))]
+pub fn parse<T: parse::Parse>(tokens: proc_macro::TokenStream) -> Result<T> {
+ parse::Parser::parse(T::parse, tokens)
+}
+
+/// Parse a proc-macro2 token stream into the chosen syntax tree node.
+///
+/// This function will check that the input is fully parsed. If there are
+/// any unparsed tokens at the end of the stream, an error is returned.
+///
+/// This function parses a `proc_macro2::TokenStream` which is commonly useful
+/// when the input comes from a node of the Syn syntax tree, for example the
+/// body tokens of a [`Macro`] node. When in a procedural macro parsing the
+/// `proc_macro::TokenStream` provided by the compiler, use [`syn::parse`]
+/// instead.
+///
+/// [`syn::parse`]: parse()
+#[cfg(feature = "parsing")]
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+pub fn parse2<T: parse::Parse>(tokens: proc_macro2::TokenStream) -> Result<T> {
+ parse::Parser::parse2(T::parse, tokens)
+}
+
+/// Parse a string of Rust code into the chosen syntax tree node.
+///
+/// # Hygiene
+///
+/// Every span in the resulting syntax tree will be set to resolve at the macro
+/// call site.
+///
+/// # Examples
+///
+/// ```
+/// use syn::{Expr, Result};
+///
+/// fn run() -> Result<()> {
+/// let code = "assert_eq!(u8::max_value(), 255)";
+/// let expr = syn::parse_str::<Expr>(code)?;
+/// println!("{:#?}", expr);
+/// Ok(())
+/// }
+/// #
+/// # run().unwrap();
+/// ```
+#[cfg(feature = "parsing")]
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+pub fn parse_str<T: parse::Parse>(s: &str) -> Result<T> {
+ parse::Parser::parse_str(T::parse, s)
+}
+
+/// Parse the content of a file of Rust code.
+///
+/// This is different from `syn::parse_str::<File>(content)` in two ways:
+///
+/// - It discards a leading byte order mark `\u{FEFF}` if the file has one.
+/// - It preserves the shebang line of the file, such as `#!/usr/bin/env rustx`.
+///
+/// If present, either of these would be an error using `from_str`.
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::error::Error;
+/// use std::fs::File;
+/// use std::io::Read;
+///
+/// fn run() -> Result<(), Box<dyn Error>> {
+/// let mut file = File::open("path/to/code.rs")?;
+/// let mut content = String::new();
+/// file.read_to_string(&mut content)?;
+///
+/// let ast = syn::parse_file(&content)?;
+/// if let Some(shebang) = ast.shebang {
+/// println!("{}", shebang);
+/// }
+/// println!("{} items", ast.items.len());
+///
+/// Ok(())
+/// }
+/// #
+/// # run().unwrap();
+/// ```
+#[cfg(all(feature = "parsing", feature = "full"))]
+#[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "full"))))]
+pub fn parse_file(mut content: &str) -> Result<File> {
+ // Strip the BOM if it is present
+ const BOM: &str = "\u{feff}";
+ if content.starts_with(BOM) {
+ content = &content[BOM.len()..];
+ }
+
+ let mut shebang = None;
+ if content.starts_with("#!") {
+ let rest = whitespace::skip(&content[2..]);
+ if !rest.starts_with('[') {
+ if let Some(idx) = content.find('\n') {
+ shebang = Some(content[..idx].to_string());
+ content = &content[idx..];
+ } else {
+ shebang = Some(content.to_string());
+ content = "";
+ }
+ }
+ }
+
+ let mut file: File = parse_str(content)?;
+ file.shebang = shebang;
+ Ok(file)
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/lifetime.rs b/rust/hw/char/pl011/vendor/syn/src/lifetime.rs
new file mode 100644
index 0000000000..cc189d1ac9
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/lifetime.rs
@@ -0,0 +1,156 @@
+#[cfg(feature = "parsing")]
+use crate::lookahead;
+use proc_macro2::{Ident, Span};
+use std::cmp::Ordering;
+use std::fmt::{self, Display};
+use std::hash::{Hash, Hasher};
+
+/// A Rust lifetime: `'a`.
+///
+/// Lifetime names must conform to the following rules:
+///
+/// - Must start with an apostrophe.
+/// - Must not consist of just an apostrophe: `'`.
+/// - Character after the apostrophe must be `_` or a Unicode code point with
+/// the XID_Start property.
+/// - All following characters must be Unicode code points with the XID_Continue
+/// property.
+pub struct Lifetime {
+ pub apostrophe: Span,
+ pub ident: Ident,
+}
+
+impl Lifetime {
+ /// # Panics
+ ///
+ /// Panics if the lifetime does not conform to the bulleted rules above.
+ ///
+ /// # Invocation
+ ///
+ /// ```
+ /// # use proc_macro2::Span;
+ /// # use syn::Lifetime;
+ /// #
+ /// # fn f() -> Lifetime {
+ /// Lifetime::new("'a", Span::call_site())
+ /// # }
+ /// ```
+ pub fn new(symbol: &str, span: Span) -> Self {
+ if !symbol.starts_with('\'') {
+ panic!(
+ "lifetime name must start with apostrophe as in \"'a\", got {:?}",
+ symbol
+ );
+ }
+
+ if symbol == "'" {
+ panic!("lifetime name must not be empty");
+ }
+
+ if !crate::ident::xid_ok(&symbol[1..]) {
+ panic!("{:?} is not a valid lifetime name", symbol);
+ }
+
+ Lifetime {
+ apostrophe: span,
+ ident: Ident::new(&symbol[1..], span),
+ }
+ }
+
+ pub fn span(&self) -> Span {
+ self.apostrophe
+ .join(self.ident.span())
+ .unwrap_or(self.apostrophe)
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.apostrophe = span;
+ self.ident.set_span(span);
+ }
+}
+
+impl Display for Lifetime {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ "'".fmt(formatter)?;
+ self.ident.fmt(formatter)
+ }
+}
+
+impl Clone for Lifetime {
+ fn clone(&self) -> Self {
+ Lifetime {
+ apostrophe: self.apostrophe,
+ ident: self.ident.clone(),
+ }
+ }
+}
+
+impl PartialEq for Lifetime {
+ fn eq(&self, other: &Lifetime) -> bool {
+ self.ident.eq(&other.ident)
+ }
+}
+
+impl Eq for Lifetime {}
+
+impl PartialOrd for Lifetime {
+ fn partial_cmp(&self, other: &Lifetime) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for Lifetime {
+ fn cmp(&self, other: &Lifetime) -> Ordering {
+ self.ident.cmp(&other.ident)
+ }
+}
+
+impl Hash for Lifetime {
+ fn hash<H: Hasher>(&self, h: &mut H) {
+ self.ident.hash(h);
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub_if_not_doc! {
+ #[doc(hidden)]
+ #[allow(non_snake_case)]
+ pub fn Lifetime(marker: lookahead::TokenMarker) -> Lifetime {
+ match marker {}
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::error::Result;
+ use crate::lifetime::Lifetime;
+ use crate::parse::{Parse, ParseStream};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Lifetime {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| {
+ cursor
+ .lifetime()
+ .ok_or_else(|| cursor.error("expected lifetime"))
+ })
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use crate::lifetime::Lifetime;
+ use proc_macro2::{Punct, Spacing, TokenStream};
+ use quote::{ToTokens, TokenStreamExt};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Lifetime {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let mut apostrophe = Punct::new('\'', Spacing::Joint);
+ apostrophe.set_span(self.apostrophe);
+ tokens.append(apostrophe);
+ self.ident.to_tokens(tokens);
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/lit.rs b/rust/hw/char/pl011/vendor/syn/src/lit.rs
new file mode 100644
index 0000000000..a37aa2a9e7
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/lit.rs
@@ -0,0 +1,1830 @@
+#[cfg(feature = "parsing")]
+use crate::lookahead;
+#[cfg(feature = "parsing")]
+use crate::parse::{Parse, Parser};
+use crate::{Error, Result};
+use proc_macro2::{Ident, Literal, Span};
+#[cfg(feature = "parsing")]
+use proc_macro2::{TokenStream, TokenTree};
+use std::ffi::{CStr, CString};
+use std::fmt::{self, Display};
+#[cfg(feature = "extra-traits")]
+use std::hash::{Hash, Hasher};
+use std::str::{self, FromStr};
+
+ast_enum_of_structs! {
+ /// A Rust literal such as a string or integer or boolean.
+ ///
+ /// # Syntax tree enum
+ ///
+ /// This type is a [syntax tree enum].
+ ///
+ /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums
+ #[non_exhaustive]
+ pub enum Lit {
+ /// A UTF-8 string literal: `"foo"`.
+ Str(LitStr),
+
+ /// A byte string literal: `b"foo"`.
+ ByteStr(LitByteStr),
+
+ /// A nul-terminated C-string literal: `c"foo"`.
+ CStr(LitCStr),
+
+ /// A byte literal: `b'f'`.
+ Byte(LitByte),
+
+ /// A character literal: `'a'`.
+ Char(LitChar),
+
+ /// An integer literal: `1` or `1u16`.
+ Int(LitInt),
+
+ /// A floating point literal: `1f64` or `1.0e10f64`.
+ ///
+ /// Must be finite. May not be infinite or NaN.
+ Float(LitFloat),
+
+ /// A boolean literal: `true` or `false`.
+ Bool(LitBool),
+
+ /// A raw token literal not interpreted by Syn.
+ Verbatim(Literal),
+ }
+}
+
+ast_struct! {
+ /// A UTF-8 string literal: `"foo"`.
+ pub struct LitStr {
+ repr: Box<LitRepr>,
+ }
+}
+
+ast_struct! {
+ /// A byte string literal: `b"foo"`.
+ pub struct LitByteStr {
+ repr: Box<LitRepr>,
+ }
+}
+
+ast_struct! {
+ /// A nul-terminated C-string literal: `c"foo"`.
+ pub struct LitCStr {
+ repr: Box<LitRepr>,
+ }
+}
+
+ast_struct! {
+ /// A byte literal: `b'f'`.
+ pub struct LitByte {
+ repr: Box<LitRepr>,
+ }
+}
+
+ast_struct! {
+ /// A character literal: `'a'`.
+ pub struct LitChar {
+ repr: Box<LitRepr>,
+ }
+}
+
+struct LitRepr {
+ token: Literal,
+ suffix: Box<str>,
+}
+
+ast_struct! {
+ /// An integer literal: `1` or `1u16`.
+ pub struct LitInt {
+ repr: Box<LitIntRepr>,
+ }
+}
+
+struct LitIntRepr {
+ token: Literal,
+ digits: Box<str>,
+ suffix: Box<str>,
+}
+
+ast_struct! {
+ /// A floating point literal: `1f64` or `1.0e10f64`.
+ ///
+ /// Must be finite. May not be infinite or NaN.
+ pub struct LitFloat {
+ repr: Box<LitFloatRepr>,
+ }
+}
+
+struct LitFloatRepr {
+ token: Literal,
+ digits: Box<str>,
+ suffix: Box<str>,
+}
+
+ast_struct! {
+ /// A boolean literal: `true` or `false`.
+ pub struct LitBool {
+ pub value: bool,
+ pub span: Span,
+ }
+}
+
+impl LitStr {
+ pub fn new(value: &str, span: Span) -> Self {
+ let mut token = Literal::string(value);
+ token.set_span(span);
+ LitStr {
+ repr: Box::new(LitRepr {
+ token,
+ suffix: Box::<str>::default(),
+ }),
+ }
+ }
+
+ pub fn value(&self) -> String {
+ let repr = self.repr.token.to_string();
+ let (value, _suffix) = value::parse_lit_str(&repr);
+ String::from(value)
+ }
+
+ /// Parse a syntax tree node from the content of this string literal.
+ ///
+ /// All spans in the syntax tree will point to the span of this `LitStr`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use syn::{Attribute, Error, Expr, Lit, Meta, Path, Result};
+ ///
+ /// // Parses the path from an attribute that looks like:
+ /// //
+ /// // #[path = "a::b::c"]
+ /// //
+ /// // or returns `None` if the input is some other attribute.
+ /// fn get_path(attr: &Attribute) -> Result<Option<Path>> {
+ /// if !attr.path().is_ident("path") {
+ /// return Ok(None);
+ /// }
+ ///
+ /// if let Meta::NameValue(meta) = &attr.meta {
+ /// if let Expr::Lit(expr) = &meta.value {
+ /// if let Lit::Str(lit_str) = &expr.lit {
+ /// return lit_str.parse().map(Some);
+ /// }
+ /// }
+ /// }
+ ///
+ /// let message = "expected #[path = \"...\"]";
+ /// Err(Error::new_spanned(attr, message))
+ /// }
+ /// ```
+ #[cfg(feature = "parsing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn parse<T: Parse>(&self) -> Result<T> {
+ self.parse_with(T::parse)
+ }
+
+ /// Invoke parser on the content of this string literal.
+ ///
+ /// All spans in the syntax tree will point to the span of this `LitStr`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use proc_macro2::Span;
+ /// # use syn::{LitStr, Result};
+ /// #
+ /// # fn main() -> Result<()> {
+ /// # let lit_str = LitStr::new("a::b::c", Span::call_site());
+ /// #
+ /// # const IGNORE: &str = stringify! {
+ /// let lit_str: LitStr = /* ... */;
+ /// # };
+ ///
+ /// // Parse a string literal like "a::b::c" into a Path, not allowing
+ /// // generic arguments on any of the path segments.
+ /// let basic_path = lit_str.parse_with(syn::Path::parse_mod_style)?;
+ /// #
+ /// # Ok(())
+ /// # }
+ /// ```
+ #[cfg(feature = "parsing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn parse_with<F: Parser>(&self, parser: F) -> Result<F::Output> {
+ use proc_macro2::Group;
+
+ // Token stream with every span replaced by the given one.
+ fn respan_token_stream(stream: TokenStream, span: Span) -> TokenStream {
+ stream
+ .into_iter()
+ .map(|token| respan_token_tree(token, span))
+ .collect()
+ }
+
+ // Token tree with every span replaced by the given one.
+ fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree {
+ match &mut token {
+ TokenTree::Group(g) => {
+ let stream = respan_token_stream(g.stream(), span);
+ *g = Group::new(g.delimiter(), stream);
+ g.set_span(span);
+ }
+ other => other.set_span(span),
+ }
+ token
+ }
+
+ // Parse string literal into a token stream with every span equal to the
+ // original literal's span.
+ let span = self.span();
+ let mut tokens = TokenStream::from_str(&self.value())?;
+ tokens = respan_token_stream(tokens, span);
+
+ let result = crate::parse::parse_scoped(parser, span, tokens)?;
+
+ let suffix = self.suffix();
+ if !suffix.is_empty() {
+ return Err(Error::new(
+ self.span(),
+ format!("unexpected suffix `{}` on string literal", suffix),
+ ));
+ }
+
+ Ok(result)
+ }
+
+ pub fn span(&self) -> Span {
+ self.repr.token.span()
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.repr.token.set_span(span);
+ }
+
+ pub fn suffix(&self) -> &str {
+ &self.repr.suffix
+ }
+
+ pub fn token(&self) -> Literal {
+ self.repr.token.clone()
+ }
+}
+
+impl LitByteStr {
+ pub fn new(value: &[u8], span: Span) -> Self {
+ let mut token = Literal::byte_string(value);
+ token.set_span(span);
+ LitByteStr {
+ repr: Box::new(LitRepr {
+ token,
+ suffix: Box::<str>::default(),
+ }),
+ }
+ }
+
+ pub fn value(&self) -> Vec<u8> {
+ let repr = self.repr.token.to_string();
+ let (value, _suffix) = value::parse_lit_byte_str(&repr);
+ value
+ }
+
+ pub fn span(&self) -> Span {
+ self.repr.token.span()
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.repr.token.set_span(span);
+ }
+
+ pub fn suffix(&self) -> &str {
+ &self.repr.suffix
+ }
+
+ pub fn token(&self) -> Literal {
+ self.repr.token.clone()
+ }
+}
+
+impl LitCStr {
+ pub fn new(value: &CStr, span: Span) -> Self {
+ let mut token = Literal::c_string(value);
+ token.set_span(span);
+ LitCStr {
+ repr: Box::new(LitRepr {
+ token,
+ suffix: Box::<str>::default(),
+ }),
+ }
+ }
+
+ pub fn value(&self) -> CString {
+ let repr = self.repr.token.to_string();
+ let (value, _suffix) = value::parse_lit_c_str(&repr);
+ value
+ }
+
+ pub fn span(&self) -> Span {
+ self.repr.token.span()
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.repr.token.set_span(span);
+ }
+
+ pub fn suffix(&self) -> &str {
+ &self.repr.suffix
+ }
+
+ pub fn token(&self) -> Literal {
+ self.repr.token.clone()
+ }
+}
+
+impl LitByte {
+ pub fn new(value: u8, span: Span) -> Self {
+ let mut token = Literal::u8_suffixed(value);
+ token.set_span(span);
+ LitByte {
+ repr: Box::new(LitRepr {
+ token,
+ suffix: Box::<str>::default(),
+ }),
+ }
+ }
+
+ pub fn value(&self) -> u8 {
+ let repr = self.repr.token.to_string();
+ let (value, _suffix) = value::parse_lit_byte(&repr);
+ value
+ }
+
+ pub fn span(&self) -> Span {
+ self.repr.token.span()
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.repr.token.set_span(span);
+ }
+
+ pub fn suffix(&self) -> &str {
+ &self.repr.suffix
+ }
+
+ pub fn token(&self) -> Literal {
+ self.repr.token.clone()
+ }
+}
+
+impl LitChar {
+ pub fn new(value: char, span: Span) -> Self {
+ let mut token = Literal::character(value);
+ token.set_span(span);
+ LitChar {
+ repr: Box::new(LitRepr {
+ token,
+ suffix: Box::<str>::default(),
+ }),
+ }
+ }
+
+ pub fn value(&self) -> char {
+ let repr = self.repr.token.to_string();
+ let (value, _suffix) = value::parse_lit_char(&repr);
+ value
+ }
+
+ pub fn span(&self) -> Span {
+ self.repr.token.span()
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.repr.token.set_span(span);
+ }
+
+ pub fn suffix(&self) -> &str {
+ &self.repr.suffix
+ }
+
+ pub fn token(&self) -> Literal {
+ self.repr.token.clone()
+ }
+}
+
+impl LitInt {
+ pub fn new(repr: &str, span: Span) -> Self {
+ let (digits, suffix) = match value::parse_lit_int(repr) {
+ Some(parse) => parse,
+ None => panic!("not an integer literal: `{}`", repr),
+ };
+
+ let mut token: Literal = repr.parse().unwrap();
+ token.set_span(span);
+ LitInt {
+ repr: Box::new(LitIntRepr {
+ token,
+ digits,
+ suffix,
+ }),
+ }
+ }
+
+ pub fn base10_digits(&self) -> &str {
+ &self.repr.digits
+ }
+
+ /// Parses the literal into a selected number type.
+ ///
+ /// This is equivalent to `lit.base10_digits().parse()` except that the
+ /// resulting errors will be correctly spanned to point to the literal token
+ /// in the macro input.
+ ///
+ /// ```
+ /// use syn::LitInt;
+ /// use syn::parse::{Parse, ParseStream, Result};
+ ///
+ /// struct Port {
+ /// value: u16,
+ /// }
+ ///
+ /// impl Parse for Port {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let lit: LitInt = input.parse()?;
+ /// let value = lit.base10_parse::<u16>()?;
+ /// Ok(Port { value })
+ /// }
+ /// }
+ /// ```
+ pub fn base10_parse<N>(&self) -> Result<N>
+ where
+ N: FromStr,
+ N::Err: Display,
+ {
+ self.base10_digits()
+ .parse()
+ .map_err(|err| Error::new(self.span(), err))
+ }
+
+ pub fn suffix(&self) -> &str {
+ &self.repr.suffix
+ }
+
+ pub fn span(&self) -> Span {
+ self.repr.token.span()
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.repr.token.set_span(span);
+ }
+
+ pub fn token(&self) -> Literal {
+ self.repr.token.clone()
+ }
+}
+
+impl From<Literal> for LitInt {
+ fn from(token: Literal) -> Self {
+ let repr = token.to_string();
+ if let Some((digits, suffix)) = value::parse_lit_int(&repr) {
+ LitInt {
+ repr: Box::new(LitIntRepr {
+ token,
+ digits,
+ suffix,
+ }),
+ }
+ } else {
+ panic!("not an integer literal: `{}`", repr);
+ }
+ }
+}
+
+impl Display for LitInt {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.repr.token.fmt(formatter)
+ }
+}
+
+impl LitFloat {
+ pub fn new(repr: &str, span: Span) -> Self {
+ let (digits, suffix) = match value::parse_lit_float(repr) {
+ Some(parse) => parse,
+ None => panic!("not a float literal: `{}`", repr),
+ };
+
+ let mut token: Literal = repr.parse().unwrap();
+ token.set_span(span);
+ LitFloat {
+ repr: Box::new(LitFloatRepr {
+ token,
+ digits,
+ suffix,
+ }),
+ }
+ }
+
+ pub fn base10_digits(&self) -> &str {
+ &self.repr.digits
+ }
+
+ pub fn base10_parse<N>(&self) -> Result<N>
+ where
+ N: FromStr,
+ N::Err: Display,
+ {
+ self.base10_digits()
+ .parse()
+ .map_err(|err| Error::new(self.span(), err))
+ }
+
+ pub fn suffix(&self) -> &str {
+ &self.repr.suffix
+ }
+
+ pub fn span(&self) -> Span {
+ self.repr.token.span()
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.repr.token.set_span(span);
+ }
+
+ pub fn token(&self) -> Literal {
+ self.repr.token.clone()
+ }
+}
+
+impl From<Literal> for LitFloat {
+ fn from(token: Literal) -> Self {
+ let repr = token.to_string();
+ if let Some((digits, suffix)) = value::parse_lit_float(&repr) {
+ LitFloat {
+ repr: Box::new(LitFloatRepr {
+ token,
+ digits,
+ suffix,
+ }),
+ }
+ } else {
+ panic!("not a float literal: `{}`", repr);
+ }
+ }
+}
+
+impl Display for LitFloat {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.repr.token.fmt(formatter)
+ }
+}
+
+impl LitBool {
+ pub fn new(value: bool, span: Span) -> Self {
+ LitBool { value, span }
+ }
+
+ pub fn value(&self) -> bool {
+ self.value
+ }
+
+ pub fn span(&self) -> Span {
+ self.span
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ self.span = span;
+ }
+
+ pub fn token(&self) -> Ident {
+ let s = if self.value { "true" } else { "false" };
+ Ident::new(s, self.span)
+ }
+}
+
+#[cfg(feature = "extra-traits")]
+mod debug_impls {
+ use crate::lit::{LitBool, LitByte, LitByteStr, LitCStr, LitChar, LitFloat, LitInt, LitStr};
+ use std::fmt::{self, Debug};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Debug for LitStr {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "LitStr")
+ }
+ }
+
+ impl LitStr {
+ pub(crate) fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ formatter
+ .debug_struct(name)
+ .field("token", &format_args!("{}", self.repr.token))
+ .finish()
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Debug for LitByteStr {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "LitByteStr")
+ }
+ }
+
+ impl LitByteStr {
+ pub(crate) fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ formatter
+ .debug_struct(name)
+ .field("token", &format_args!("{}", self.repr.token))
+ .finish()
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Debug for LitCStr {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "LitCStr")
+ }
+ }
+
+ impl LitCStr {
+ pub(crate) fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ formatter
+ .debug_struct(name)
+ .field("token", &format_args!("{}", self.repr.token))
+ .finish()
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Debug for LitByte {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "LitByte")
+ }
+ }
+
+ impl LitByte {
+ pub(crate) fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ formatter
+ .debug_struct(name)
+ .field("token", &format_args!("{}", self.repr.token))
+ .finish()
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Debug for LitChar {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "LitChar")
+ }
+ }
+
+ impl LitChar {
+ pub(crate) fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ formatter
+ .debug_struct(name)
+ .field("token", &format_args!("{}", self.repr.token))
+ .finish()
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Debug for LitInt {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "LitInt")
+ }
+ }
+
+ impl LitInt {
+ pub(crate) fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ formatter
+ .debug_struct(name)
+ .field("token", &format_args!("{}", self.repr.token))
+ .finish()
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Debug for LitFloat {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "LitFloat")
+ }
+ }
+
+ impl LitFloat {
+ pub(crate) fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ formatter
+ .debug_struct(name)
+ .field("token", &format_args!("{}", self.repr.token))
+ .finish()
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Debug for LitBool {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.debug(formatter, "LitBool")
+ }
+ }
+
+ impl LitBool {
+ pub(crate) fn debug(&self, formatter: &mut fmt::Formatter, name: &str) -> fmt::Result {
+ formatter
+ .debug_struct(name)
+ .field("value", &self.value)
+ .finish()
+ }
+ }
+}
+
+#[cfg(feature = "clone-impls")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for LitRepr {
+ fn clone(&self) -> Self {
+ LitRepr {
+ token: self.token.clone(),
+ suffix: self.suffix.clone(),
+ }
+ }
+}
+
+#[cfg(feature = "clone-impls")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for LitIntRepr {
+ fn clone(&self) -> Self {
+ LitIntRepr {
+ token: self.token.clone(),
+ digits: self.digits.clone(),
+ suffix: self.suffix.clone(),
+ }
+ }
+}
+
+#[cfg(feature = "clone-impls")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for LitFloatRepr {
+ fn clone(&self) -> Self {
+ LitFloatRepr {
+ token: self.token.clone(),
+ digits: self.digits.clone(),
+ suffix: self.suffix.clone(),
+ }
+ }
+}
+
+macro_rules! lit_extra_traits {
+ ($ty:ident) => {
+ #[cfg(feature = "clone-impls")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+ impl Clone for $ty {
+ fn clone(&self) -> Self {
+ $ty {
+ repr: self.repr.clone(),
+ }
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl PartialEq for $ty {
+ fn eq(&self, other: &Self) -> bool {
+ self.repr.token.to_string() == other.repr.token.to_string()
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Hash for $ty {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: Hasher,
+ {
+ self.repr.token.to_string().hash(state);
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ pub_if_not_doc! {
+ #[doc(hidden)]
+ #[allow(non_snake_case)]
+ pub fn $ty(marker: lookahead::TokenMarker) -> $ty {
+ match marker {}
+ }
+ }
+ };
+}
+
+lit_extra_traits!(LitStr);
+lit_extra_traits!(LitByteStr);
+lit_extra_traits!(LitCStr);
+lit_extra_traits!(LitByte);
+lit_extra_traits!(LitChar);
+lit_extra_traits!(LitInt);
+lit_extra_traits!(LitFloat);
+
+#[cfg(feature = "parsing")]
+pub_if_not_doc! {
+ #[doc(hidden)]
+ #[allow(non_snake_case)]
+ pub fn LitBool(marker: lookahead::TokenMarker) -> LitBool {
+ match marker {}
+ }
+}
+
+/// The style of a string literal, either plain quoted or a raw string like
+/// `r##"data"##`.
+#[doc(hidden)] // https://github.com/dtolnay/syn/issues/1566
+pub enum StrStyle {
+ /// An ordinary string like `"data"`.
+ Cooked,
+ /// A raw string like `r##"data"##`.
+ ///
+ /// The unsigned integer is the number of `#` symbols used.
+ Raw(usize),
+}
+
+#[cfg(feature = "parsing")]
+pub_if_not_doc! {
+ #[doc(hidden)]
+ #[allow(non_snake_case)]
+ pub fn Lit(marker: lookahead::TokenMarker) -> Lit {
+ match marker {}
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::buffer::Cursor;
+ use crate::error::Result;
+ use crate::lit::{
+ value, Lit, LitBool, LitByte, LitByteStr, LitCStr, LitChar, LitFloat, LitFloatRepr, LitInt,
+ LitIntRepr, LitStr,
+ };
+ use crate::parse::{Parse, ParseStream};
+ use proc_macro2::{Literal, Punct};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Lit {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| {
+ if let Some((lit, rest)) = cursor.literal() {
+ return Ok((Lit::new(lit), rest));
+ }
+
+ if let Some((ident, rest)) = cursor.ident() {
+ let value = ident == "true";
+ if value || ident == "false" {
+ let lit_bool = LitBool {
+ value,
+ span: ident.span(),
+ };
+ return Ok((Lit::Bool(lit_bool), rest));
+ }
+ }
+
+ if let Some((punct, rest)) = cursor.punct() {
+ if punct.as_char() == '-' {
+ if let Some((lit, rest)) = parse_negative_lit(punct, rest) {
+ return Ok((lit, rest));
+ }
+ }
+ }
+
+ Err(cursor.error("expected literal"))
+ })
+ }
+ }
+
+ fn parse_negative_lit(neg: Punct, cursor: Cursor) -> Option<(Lit, Cursor)> {
+ let (lit, rest) = cursor.literal()?;
+
+ let mut span = neg.span();
+ span = span.join(lit.span()).unwrap_or(span);
+
+ let mut repr = lit.to_string();
+ repr.insert(0, '-');
+
+ if let Some((digits, suffix)) = value::parse_lit_int(&repr) {
+ let mut token: Literal = repr.parse().unwrap();
+ token.set_span(span);
+ return Some((
+ Lit::Int(LitInt {
+ repr: Box::new(LitIntRepr {
+ token,
+ digits,
+ suffix,
+ }),
+ }),
+ rest,
+ ));
+ }
+
+ let (digits, suffix) = value::parse_lit_float(&repr)?;
+ let mut token: Literal = repr.parse().unwrap();
+ token.set_span(span);
+ Some((
+ Lit::Float(LitFloat {
+ repr: Box::new(LitFloatRepr {
+ token,
+ digits,
+ suffix,
+ }),
+ }),
+ rest,
+ ))
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for LitStr {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse() {
+ Ok(Lit::Str(lit)) => Ok(lit),
+ _ => Err(head.error("expected string literal")),
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for LitByteStr {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse() {
+ Ok(Lit::ByteStr(lit)) => Ok(lit),
+ _ => Err(head.error("expected byte string literal")),
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for LitCStr {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse() {
+ Ok(Lit::CStr(lit)) => Ok(lit),
+ _ => Err(head.error("expected C string literal")),
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for LitByte {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse() {
+ Ok(Lit::Byte(lit)) => Ok(lit),
+ _ => Err(head.error("expected byte literal")),
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for LitChar {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse() {
+ Ok(Lit::Char(lit)) => Ok(lit),
+ _ => Err(head.error("expected character literal")),
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for LitInt {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse() {
+ Ok(Lit::Int(lit)) => Ok(lit),
+ _ => Err(head.error("expected integer literal")),
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for LitFloat {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse() {
+ Ok(Lit::Float(lit)) => Ok(lit),
+ _ => Err(head.error("expected floating point literal")),
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for LitBool {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let head = input.fork();
+ match input.parse() {
+ Ok(Lit::Bool(lit)) => Ok(lit),
+ _ => Err(head.error("expected boolean literal")),
+ }
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use crate::lit::{LitBool, LitByte, LitByteStr, LitCStr, LitChar, LitFloat, LitInt, LitStr};
+ use proc_macro2::TokenStream;
+ use quote::{ToTokens, TokenStreamExt};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for LitStr {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.repr.token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for LitByteStr {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.repr.token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for LitCStr {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.repr.token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for LitByte {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.repr.token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for LitChar {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.repr.token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for LitInt {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.repr.token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for LitFloat {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.repr.token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for LitBool {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(self.token());
+ }
+ }
+}
+
+mod value {
+ use crate::bigint::BigInt;
+ use crate::lit::{
+ Lit, LitBool, LitByte, LitByteStr, LitCStr, LitChar, LitFloat, LitFloatRepr, LitInt,
+ LitIntRepr, LitRepr, LitStr,
+ };
+ use proc_macro2::{Literal, Span};
+ use std::ascii;
+ use std::char;
+ use std::ffi::CString;
+ use std::ops::{Index, RangeFrom};
+
+ impl Lit {
+ /// Interpret a Syn literal from a proc-macro2 literal.
+ pub fn new(token: Literal) -> Self {
+ let repr = token.to_string();
+
+ match byte(&repr, 0) {
+ // "...", r"...", r#"..."#
+ b'"' | b'r' => {
+ let (_, suffix) = parse_lit_str(&repr);
+ return Lit::Str(LitStr {
+ repr: Box::new(LitRepr { token, suffix }),
+ });
+ }
+ b'b' => match byte(&repr, 1) {
+ // b"...", br"...", br#"...#"
+ b'"' | b'r' => {
+ let (_, suffix) = parse_lit_byte_str(&repr);
+ return Lit::ByteStr(LitByteStr {
+ repr: Box::new(LitRepr { token, suffix }),
+ });
+ }
+ // b'...'
+ b'\'' => {
+ let (_, suffix) = parse_lit_byte(&repr);
+ return Lit::Byte(LitByte {
+ repr: Box::new(LitRepr { token, suffix }),
+ });
+ }
+ _ => {}
+ },
+ // c"...", cr"...", cr#"..."#
+ b'c' => {
+ let (_, suffix) = parse_lit_c_str(&repr);
+ return Lit::CStr(LitCStr {
+ repr: Box::new(LitRepr { token, suffix }),
+ });
+ }
+ // '...'
+ b'\'' => {
+ let (_, suffix) = parse_lit_char(&repr);
+ return Lit::Char(LitChar {
+ repr: Box::new(LitRepr { token, suffix }),
+ });
+ }
+ b'0'..=b'9' | b'-' => {
+ // 0, 123, 0xFF, 0o77, 0b11
+ if let Some((digits, suffix)) = parse_lit_int(&repr) {
+ return Lit::Int(LitInt {
+ repr: Box::new(LitIntRepr {
+ token,
+ digits,
+ suffix,
+ }),
+ });
+ }
+ // 1.0, 1e-1, 1e+1
+ if let Some((digits, suffix)) = parse_lit_float(&repr) {
+ return Lit::Float(LitFloat {
+ repr: Box::new(LitFloatRepr {
+ token,
+ digits,
+ suffix,
+ }),
+ });
+ }
+ }
+ // true, false
+ b't' | b'f' => {
+ if repr == "true" || repr == "false" {
+ return Lit::Bool(LitBool {
+ value: repr == "true",
+ span: token.span(),
+ });
+ }
+ }
+ b'(' if repr == "(/*ERROR*/)" => return Lit::Verbatim(token),
+ _ => {}
+ }
+
+ panic!("unrecognized literal: `{}`", repr);
+ }
+
+ pub fn suffix(&self) -> &str {
+ match self {
+ Lit::Str(lit) => lit.suffix(),
+ Lit::ByteStr(lit) => lit.suffix(),
+ Lit::CStr(lit) => lit.suffix(),
+ Lit::Byte(lit) => lit.suffix(),
+ Lit::Char(lit) => lit.suffix(),
+ Lit::Int(lit) => lit.suffix(),
+ Lit::Float(lit) => lit.suffix(),
+ Lit::Bool(_) | Lit::Verbatim(_) => "",
+ }
+ }
+
+ pub fn span(&self) -> Span {
+ match self {
+ Lit::Str(lit) => lit.span(),
+ Lit::ByteStr(lit) => lit.span(),
+ Lit::CStr(lit) => lit.span(),
+ Lit::Byte(lit) => lit.span(),
+ Lit::Char(lit) => lit.span(),
+ Lit::Int(lit) => lit.span(),
+ Lit::Float(lit) => lit.span(),
+ Lit::Bool(lit) => lit.span,
+ Lit::Verbatim(lit) => lit.span(),
+ }
+ }
+
+ pub fn set_span(&mut self, span: Span) {
+ match self {
+ Lit::Str(lit) => lit.set_span(span),
+ Lit::ByteStr(lit) => lit.set_span(span),
+ Lit::CStr(lit) => lit.set_span(span),
+ Lit::Byte(lit) => lit.set_span(span),
+ Lit::Char(lit) => lit.set_span(span),
+ Lit::Int(lit) => lit.set_span(span),
+ Lit::Float(lit) => lit.set_span(span),
+ Lit::Bool(lit) => lit.span = span,
+ Lit::Verbatim(lit) => lit.set_span(span),
+ }
+ }
+ }
+
+ /// Get the byte at offset idx, or a default of `b'\0'` if we're looking
+ /// past the end of the input buffer.
+ pub(crate) fn byte<S: AsRef<[u8]> + ?Sized>(s: &S, idx: usize) -> u8 {
+ let s = s.as_ref();
+ if idx < s.len() {
+ s[idx]
+ } else {
+ 0
+ }
+ }
+
+ fn next_chr(s: &str) -> char {
+ s.chars().next().unwrap_or('\0')
+ }
+
+ // Returns (content, suffix).
+ pub(crate) fn parse_lit_str(s: &str) -> (Box<str>, Box<str>) {
+ match byte(s, 0) {
+ b'"' => parse_lit_str_cooked(s),
+ b'r' => parse_lit_str_raw(s),
+ _ => unreachable!(),
+ }
+ }
+
+ // Clippy false positive
+ // https://github.com/rust-lang-nursery/rust-clippy/issues/2329
+ #[allow(clippy::needless_continue)]
+ fn parse_lit_str_cooked(mut s: &str) -> (Box<str>, Box<str>) {
+ assert_eq!(byte(s, 0), b'"');
+ s = &s[1..];
+
+ let mut content = String::new();
+ 'outer: loop {
+ let ch = match byte(s, 0) {
+ b'"' => break,
+ b'\\' => {
+ let b = byte(s, 1);
+ s = &s[2..];
+ match b {
+ b'x' => {
+ let (byte, rest) = backslash_x(s);
+ s = rest;
+ assert!(byte <= 0x7F, "invalid \\x byte in string literal");
+ char::from_u32(u32::from(byte)).unwrap()
+ }
+ b'u' => {
+ let (ch, rest) = backslash_u(s);
+ s = rest;
+ ch
+ }
+ b'n' => '\n',
+ b'r' => '\r',
+ b't' => '\t',
+ b'\\' => '\\',
+ b'0' => '\0',
+ b'\'' => '\'',
+ b'"' => '"',
+ b'\r' | b'\n' => loop {
+ let b = byte(s, 0);
+ match b {
+ b' ' | b'\t' | b'\n' | b'\r' => s = &s[1..],
+ _ => continue 'outer,
+ }
+ },
+ b => panic!(
+ "unexpected byte '{}' after \\ character in string literal",
+ ascii::escape_default(b),
+ ),
+ }
+ }
+ b'\r' => {
+ assert_eq!(byte(s, 1), b'\n', "bare CR not allowed in string");
+ s = &s[2..];
+ '\n'
+ }
+ _ => {
+ let ch = next_chr(s);
+ s = &s[ch.len_utf8()..];
+ ch
+ }
+ };
+ content.push(ch);
+ }
+
+ assert!(s.starts_with('"'));
+ let content = content.into_boxed_str();
+ let suffix = s[1..].to_owned().into_boxed_str();
+ (content, suffix)
+ }
+
+ fn parse_lit_str_raw(mut s: &str) -> (Box<str>, Box<str>) {
+ assert_eq!(byte(s, 0), b'r');
+ s = &s[1..];
+
+ let mut pounds = 0;
+ while byte(s, pounds) == b'#' {
+ pounds += 1;
+ }
+ assert_eq!(byte(s, pounds), b'"');
+ let close = s.rfind('"').unwrap();
+ for end in s[close + 1..close + 1 + pounds].bytes() {
+ assert_eq!(end, b'#');
+ }
+
+ let content = s[pounds + 1..close].to_owned().into_boxed_str();
+ let suffix = s[close + 1 + pounds..].to_owned().into_boxed_str();
+ (content, suffix)
+ }
+
+ // Returns (content, suffix).
+ pub(crate) fn parse_lit_byte_str(s: &str) -> (Vec<u8>, Box<str>) {
+ assert_eq!(byte(s, 0), b'b');
+ match byte(s, 1) {
+ b'"' => parse_lit_byte_str_cooked(s),
+ b'r' => parse_lit_byte_str_raw(s),
+ _ => unreachable!(),
+ }
+ }
+
+ // Clippy false positive
+ // https://github.com/rust-lang-nursery/rust-clippy/issues/2329
+ #[allow(clippy::needless_continue)]
+ fn parse_lit_byte_str_cooked(mut s: &str) -> (Vec<u8>, Box<str>) {
+ assert_eq!(byte(s, 0), b'b');
+ assert_eq!(byte(s, 1), b'"');
+ s = &s[2..];
+
+ // We're going to want to have slices which don't respect codepoint boundaries.
+ let mut v = s.as_bytes();
+
+ let mut out = Vec::new();
+ 'outer: loop {
+ let byte = match byte(v, 0) {
+ b'"' => break,
+ b'\\' => {
+ let b = byte(v, 1);
+ v = &v[2..];
+ match b {
+ b'x' => {
+ let (b, rest) = backslash_x(v);
+ v = rest;
+ b
+ }
+ b'n' => b'\n',
+ b'r' => b'\r',
+ b't' => b'\t',
+ b'\\' => b'\\',
+ b'0' => b'\0',
+ b'\'' => b'\'',
+ b'"' => b'"',
+ b'\r' | b'\n' => loop {
+ let byte = byte(v, 0);
+ if matches!(byte, b' ' | b'\t' | b'\n' | b'\r') {
+ v = &v[1..];
+ } else {
+ continue 'outer;
+ }
+ },
+ b => panic!(
+ "unexpected byte '{}' after \\ character in byte-string literal",
+ ascii::escape_default(b),
+ ),
+ }
+ }
+ b'\r' => {
+ assert_eq!(byte(v, 1), b'\n', "bare CR not allowed in string");
+ v = &v[2..];
+ b'\n'
+ }
+ b => {
+ v = &v[1..];
+ b
+ }
+ };
+ out.push(byte);
+ }
+
+ assert_eq!(byte(v, 0), b'"');
+ let suffix = s[s.len() - v.len() + 1..].to_owned().into_boxed_str();
+ (out, suffix)
+ }
+
+ fn parse_lit_byte_str_raw(s: &str) -> (Vec<u8>, Box<str>) {
+ assert_eq!(byte(s, 0), b'b');
+ let (value, suffix) = parse_lit_str_raw(&s[1..]);
+ (String::from(value).into_bytes(), suffix)
+ }
+
+ // Returns (content, suffix).
+ pub(crate) fn parse_lit_c_str(s: &str) -> (CString, Box<str>) {
+ assert_eq!(byte(s, 0), b'c');
+ match byte(s, 1) {
+ b'"' => parse_lit_c_str_cooked(s),
+ b'r' => parse_lit_c_str_raw(s),
+ _ => unreachable!(),
+ }
+ }
+
+ // Clippy false positive
+ // https://github.com/rust-lang-nursery/rust-clippy/issues/2329
+ #[allow(clippy::needless_continue)]
+ fn parse_lit_c_str_cooked(mut s: &str) -> (CString, Box<str>) {
+ assert_eq!(byte(s, 0), b'c');
+ assert_eq!(byte(s, 1), b'"');
+ s = &s[2..];
+
+ // We're going to want to have slices which don't respect codepoint boundaries.
+ let mut v = s.as_bytes();
+
+ let mut out = Vec::new();
+ 'outer: loop {
+ let byte = match byte(v, 0) {
+ b'"' => break,
+ b'\\' => {
+ let b = byte(v, 1);
+ v = &v[2..];
+ match b {
+ b'x' => {
+ let (b, rest) = backslash_x(v);
+ assert!(b != 0, "\\x00 is not allowed in C-string literal");
+ v = rest;
+ b
+ }
+ b'u' => {
+ let (ch, rest) = backslash_u(v);
+ assert!(ch != '\0', "\\u{{0}} is not allowed in C-string literal");
+ v = rest;
+ out.extend_from_slice(ch.encode_utf8(&mut [0u8; 4]).as_bytes());
+ continue 'outer;
+ }
+ b'n' => b'\n',
+ b'r' => b'\r',
+ b't' => b'\t',
+ b'\\' => b'\\',
+ b'\'' => b'\'',
+ b'"' => b'"',
+ b'\r' | b'\n' => loop {
+ let byte = byte(v, 0);
+ if matches!(byte, b' ' | b'\t' | b'\n' | b'\r') {
+ v = &v[1..];
+ } else {
+ continue 'outer;
+ }
+ },
+ b => panic!(
+ "unexpected byte '{}' after \\ character in byte literal",
+ ascii::escape_default(b),
+ ),
+ }
+ }
+ b'\r' => {
+ assert_eq!(byte(v, 1), b'\n', "bare CR not allowed in string");
+ v = &v[2..];
+ b'\n'
+ }
+ b => {
+ v = &v[1..];
+ b
+ }
+ };
+ out.push(byte);
+ }
+
+ assert_eq!(byte(v, 0), b'"');
+ let suffix = s[s.len() - v.len() + 1..].to_owned().into_boxed_str();
+ (CString::new(out).unwrap(), suffix)
+ }
+
+ fn parse_lit_c_str_raw(s: &str) -> (CString, Box<str>) {
+ assert_eq!(byte(s, 0), b'c');
+ let (value, suffix) = parse_lit_str_raw(&s[1..]);
+ (CString::new(String::from(value)).unwrap(), suffix)
+ }
+
+ // Returns (value, suffix).
+ pub(crate) fn parse_lit_byte(s: &str) -> (u8, Box<str>) {
+ assert_eq!(byte(s, 0), b'b');
+ assert_eq!(byte(s, 1), b'\'');
+
+ // We're going to want to have slices which don't respect codepoint boundaries.
+ let mut v = s[2..].as_bytes();
+
+ let b = match byte(v, 0) {
+ b'\\' => {
+ let b = byte(v, 1);
+ v = &v[2..];
+ match b {
+ b'x' => {
+ let (b, rest) = backslash_x(v);
+ v = rest;
+ b
+ }
+ b'n' => b'\n',
+ b'r' => b'\r',
+ b't' => b'\t',
+ b'\\' => b'\\',
+ b'0' => b'\0',
+ b'\'' => b'\'',
+ b'"' => b'"',
+ b => panic!(
+ "unexpected byte '{}' after \\ character in byte literal",
+ ascii::escape_default(b),
+ ),
+ }
+ }
+ b => {
+ v = &v[1..];
+ b
+ }
+ };
+
+ assert_eq!(byte(v, 0), b'\'');
+ let suffix = s[s.len() - v.len() + 1..].to_owned().into_boxed_str();
+ (b, suffix)
+ }
+
+ // Returns (value, suffix).
+ pub(crate) fn parse_lit_char(mut s: &str) -> (char, Box<str>) {
+ assert_eq!(byte(s, 0), b'\'');
+ s = &s[1..];
+
+ let ch = match byte(s, 0) {
+ b'\\' => {
+ let b = byte(s, 1);
+ s = &s[2..];
+ match b {
+ b'x' => {
+ let (byte, rest) = backslash_x(s);
+ s = rest;
+ assert!(byte <= 0x7F, "invalid \\x byte in character literal");
+ char::from_u32(u32::from(byte)).unwrap()
+ }
+ b'u' => {
+ let (ch, rest) = backslash_u(s);
+ s = rest;
+ ch
+ }
+ b'n' => '\n',
+ b'r' => '\r',
+ b't' => '\t',
+ b'\\' => '\\',
+ b'0' => '\0',
+ b'\'' => '\'',
+ b'"' => '"',
+ b => panic!(
+ "unexpected byte '{}' after \\ character in character literal",
+ ascii::escape_default(b),
+ ),
+ }
+ }
+ _ => {
+ let ch = next_chr(s);
+ s = &s[ch.len_utf8()..];
+ ch
+ }
+ };
+ assert_eq!(byte(s, 0), b'\'');
+ let suffix = s[1..].to_owned().into_boxed_str();
+ (ch, suffix)
+ }
+
+ fn backslash_x<S>(s: &S) -> (u8, &S)
+ where
+ S: Index<RangeFrom<usize>, Output = S> + AsRef<[u8]> + ?Sized,
+ {
+ let mut ch = 0;
+ let b0 = byte(s, 0);
+ let b1 = byte(s, 1);
+ ch += 0x10
+ * match b0 {
+ b'0'..=b'9' => b0 - b'0',
+ b'a'..=b'f' => 10 + (b0 - b'a'),
+ b'A'..=b'F' => 10 + (b0 - b'A'),
+ _ => panic!("unexpected non-hex character after \\x"),
+ };
+ ch += match b1 {
+ b'0'..=b'9' => b1 - b'0',
+ b'a'..=b'f' => 10 + (b1 - b'a'),
+ b'A'..=b'F' => 10 + (b1 - b'A'),
+ _ => panic!("unexpected non-hex character after \\x"),
+ };
+ (ch, &s[2..])
+ }
+
+ fn backslash_u<S>(mut s: &S) -> (char, &S)
+ where
+ S: Index<RangeFrom<usize>, Output = S> + AsRef<[u8]> + ?Sized,
+ {
+ if byte(s, 0) != b'{' {
+ panic!("{}", "expected { after \\u");
+ }
+ s = &s[1..];
+
+ let mut ch = 0;
+ let mut digits = 0;
+ loop {
+ let b = byte(s, 0);
+ let digit = match b {
+ b'0'..=b'9' => b - b'0',
+ b'a'..=b'f' => 10 + b - b'a',
+ b'A'..=b'F' => 10 + b - b'A',
+ b'_' if digits > 0 => {
+ s = &s[1..];
+ continue;
+ }
+ b'}' if digits == 0 => panic!("invalid empty unicode escape"),
+ b'}' => break,
+ _ => panic!("unexpected non-hex character after \\u"),
+ };
+ if digits == 6 {
+ panic!("overlong unicode escape (must have at most 6 hex digits)");
+ }
+ ch *= 0x10;
+ ch += u32::from(digit);
+ digits += 1;
+ s = &s[1..];
+ }
+ assert!(byte(s, 0) == b'}');
+ s = &s[1..];
+
+ if let Some(ch) = char::from_u32(ch) {
+ (ch, s)
+ } else {
+ panic!("character code {:x} is not a valid unicode character", ch);
+ }
+ }
+
+ // Returns base 10 digits and suffix.
+ pub(crate) fn parse_lit_int(mut s: &str) -> Option<(Box<str>, Box<str>)> {
+ let negative = byte(s, 0) == b'-';
+ if negative {
+ s = &s[1..];
+ }
+
+ let base = match (byte(s, 0), byte(s, 1)) {
+ (b'0', b'x') => {
+ s = &s[2..];
+ 16
+ }
+ (b'0', b'o') => {
+ s = &s[2..];
+ 8
+ }
+ (b'0', b'b') => {
+ s = &s[2..];
+ 2
+ }
+ (b'0'..=b'9', _) => 10,
+ _ => return None,
+ };
+
+ let mut value = BigInt::new();
+ let mut has_digit = false;
+ 'outer: loop {
+ let b = byte(s, 0);
+ let digit = match b {
+ b'0'..=b'9' => b - b'0',
+ b'a'..=b'f' if base > 10 => b - b'a' + 10,
+ b'A'..=b'F' if base > 10 => b - b'A' + 10,
+ b'_' => {
+ s = &s[1..];
+ continue;
+ }
+ // If looking at a floating point literal, we don't want to
+ // consider it an integer.
+ b'.' if base == 10 => return None,
+ b'e' | b'E' if base == 10 => {
+ let mut has_exp = false;
+ for (i, b) in s[1..].bytes().enumerate() {
+ match b {
+ b'_' => {}
+ b'-' | b'+' => return None,
+ b'0'..=b'9' => has_exp = true,
+ _ => {
+ let suffix = &s[1 + i..];
+ if has_exp && crate::ident::xid_ok(suffix) {
+ return None;
+ } else {
+ break 'outer;
+ }
+ }
+ }
+ }
+ if has_exp {
+ return None;
+ } else {
+ break;
+ }
+ }
+ _ => break,
+ };
+
+ if digit >= base {
+ return None;
+ }
+
+ has_digit = true;
+ value *= base;
+ value += digit;
+ s = &s[1..];
+ }
+
+ if !has_digit {
+ return None;
+ }
+
+ let suffix = s;
+ if suffix.is_empty() || crate::ident::xid_ok(suffix) {
+ let mut repr = value.to_string();
+ if negative {
+ repr.insert(0, '-');
+ }
+ Some((repr.into_boxed_str(), suffix.to_owned().into_boxed_str()))
+ } else {
+ None
+ }
+ }
+
+ // Returns base 10 digits and suffix.
+ pub(crate) fn parse_lit_float(input: &str) -> Option<(Box<str>, Box<str>)> {
+ // Rust's floating point literals are very similar to the ones parsed by
+ // the standard library, except that rust's literals can contain
+ // ignorable underscores. Let's remove those underscores.
+
+ let mut bytes = input.to_owned().into_bytes();
+
+ let start = (*bytes.first()? == b'-') as usize;
+ match bytes.get(start)? {
+ b'0'..=b'9' => {}
+ _ => return None,
+ }
+
+ let mut read = start;
+ let mut write = start;
+ let mut has_dot = false;
+ let mut has_e = false;
+ let mut has_sign = false;
+ let mut has_exponent = false;
+ while read < bytes.len() {
+ match bytes[read] {
+ b'_' => {
+ // Don't increase write
+ read += 1;
+ continue;
+ }
+ b'0'..=b'9' => {
+ if has_e {
+ has_exponent = true;
+ }
+ bytes[write] = bytes[read];
+ }
+ b'.' => {
+ if has_e || has_dot {
+ return None;
+ }
+ has_dot = true;
+ bytes[write] = b'.';
+ }
+ b'e' | b'E' => {
+ match bytes[read + 1..]
+ .iter()
+ .find(|b| **b != b'_')
+ .unwrap_or(&b'\0')
+ {
+ b'-' | b'+' | b'0'..=b'9' => {}
+ _ => break,
+ }
+ if has_e {
+ if has_exponent {
+ break;
+ } else {
+ return None;
+ }
+ }
+ has_e = true;
+ bytes[write] = b'e';
+ }
+ b'-' | b'+' => {
+ if has_sign || has_exponent || !has_e {
+ return None;
+ }
+ has_sign = true;
+ if bytes[read] == b'-' {
+ bytes[write] = bytes[read];
+ } else {
+ // Omit '+'
+ read += 1;
+ continue;
+ }
+ }
+ _ => break,
+ }
+ read += 1;
+ write += 1;
+ }
+
+ if has_e && !has_exponent {
+ return None;
+ }
+
+ let mut digits = String::from_utf8(bytes).unwrap();
+ let suffix = digits.split_off(read);
+ digits.truncate(write);
+ if suffix.is_empty() || crate::ident::xid_ok(&suffix) {
+ Some((digits.into_boxed_str(), suffix.into_boxed_str()))
+ } else {
+ None
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/lookahead.rs b/rust/hw/char/pl011/vendor/syn/src/lookahead.rs
new file mode 100644
index 0000000000..2ca1471472
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/lookahead.rs
@@ -0,0 +1,169 @@
+use crate::buffer::Cursor;
+use crate::error::{self, Error};
+use crate::sealed::lookahead::Sealed;
+use crate::span::IntoSpans;
+use crate::token::Token;
+use proc_macro2::{Delimiter, Span};
+use std::cell::RefCell;
+
+/// Support for checking the next token in a stream to decide how to parse.
+///
+/// An important advantage over [`ParseStream::peek`] is that here we
+/// automatically construct an appropriate error message based on the token
+/// alternatives that get peeked. If you are producing your own error message,
+/// go ahead and use `ParseStream::peek` instead.
+///
+/// Use [`ParseStream::lookahead1`] to construct this object.
+///
+/// [`ParseStream::peek`]: crate::parse::ParseBuffer::peek
+/// [`ParseStream::lookahead1`]: crate::parse::ParseBuffer::lookahead1
+///
+/// Consuming tokens from the source stream after constructing a lookahead
+/// object does not also advance the lookahead object.
+///
+/// # Example
+///
+/// ```
+/// use syn::{ConstParam, Ident, Lifetime, LifetimeParam, Result, Token, TypeParam};
+/// use syn::parse::{Parse, ParseStream};
+///
+/// // A generic parameter, a single one of the comma-separated elements inside
+/// // angle brackets in:
+/// //
+/// // fn f<T: Clone, 'a, 'b: 'a, const N: usize>() { ... }
+/// //
+/// // On invalid input, lookahead gives us a reasonable error message.
+/// //
+/// // error: expected one of: identifier, lifetime, `const`
+/// // |
+/// // 5 | fn f<!Sized>() {}
+/// // | ^
+/// enum GenericParam {
+/// Type(TypeParam),
+/// Lifetime(LifetimeParam),
+/// Const(ConstParam),
+/// }
+///
+/// impl Parse for GenericParam {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// let lookahead = input.lookahead1();
+/// if lookahead.peek(Ident) {
+/// input.parse().map(GenericParam::Type)
+/// } else if lookahead.peek(Lifetime) {
+/// input.parse().map(GenericParam::Lifetime)
+/// } else if lookahead.peek(Token![const]) {
+/// input.parse().map(GenericParam::Const)
+/// } else {
+/// Err(lookahead.error())
+/// }
+/// }
+/// }
+/// ```
+pub struct Lookahead1<'a> {
+ scope: Span,
+ cursor: Cursor<'a>,
+ comparisons: RefCell<Vec<&'static str>>,
+}
+
+pub(crate) fn new(scope: Span, cursor: Cursor) -> Lookahead1 {
+ Lookahead1 {
+ scope,
+ cursor,
+ comparisons: RefCell::new(Vec::new()),
+ }
+}
+
+fn peek_impl(
+ lookahead: &Lookahead1,
+ peek: fn(Cursor) -> bool,
+ display: fn() -> &'static str,
+) -> bool {
+ if peek(lookahead.cursor) {
+ return true;
+ }
+ lookahead.comparisons.borrow_mut().push(display());
+ false
+}
+
+impl<'a> Lookahead1<'a> {
+ /// Looks at the next token in the parse stream to determine whether it
+ /// matches the requested type of token.
+ ///
+ /// # Syntax
+ ///
+ /// Note that this method does not use turbofish syntax. Pass the peek type
+ /// inside of parentheses.
+ ///
+ /// - `input.peek(Token![struct])`
+ /// - `input.peek(Token![==])`
+ /// - `input.peek(Ident)` *(does not accept keywords)*
+ /// - `input.peek(Ident::peek_any)`
+ /// - `input.peek(Lifetime)`
+ /// - `input.peek(token::Brace)`
+ pub fn peek<T: Peek>(&self, token: T) -> bool {
+ let _ = token;
+ peek_impl(self, T::Token::peek, T::Token::display)
+ }
+
+ /// Triggers an error at the current position of the parse stream.
+ ///
+ /// The error message will identify all of the expected token types that
+ /// have been peeked against this lookahead instance.
+ pub fn error(self) -> Error {
+ let comparisons = self.comparisons.into_inner();
+ match comparisons.len() {
+ 0 => {
+ if self.cursor.eof() {
+ Error::new(self.scope, "unexpected end of input")
+ } else {
+ Error::new(self.cursor.span(), "unexpected token")
+ }
+ }
+ 1 => {
+ let message = format!("expected {}", comparisons[0]);
+ error::new_at(self.scope, self.cursor, message)
+ }
+ 2 => {
+ let message = format!("expected {} or {}", comparisons[0], comparisons[1]);
+ error::new_at(self.scope, self.cursor, message)
+ }
+ _ => {
+ let join = comparisons.join(", ");
+ let message = format!("expected one of: {}", join);
+ error::new_at(self.scope, self.cursor, message)
+ }
+ }
+ }
+}
+
+/// Types that can be parsed by looking at just one token.
+///
+/// Use [`ParseStream::peek`] to peek one of these types in a parse stream
+/// without consuming it from the stream.
+///
+/// This trait is sealed and cannot be implemented for types outside of Syn.
+///
+/// [`ParseStream::peek`]: crate::parse::ParseBuffer::peek
+pub trait Peek: Sealed {
+ // Not public API.
+ #[doc(hidden)]
+ type Token: Token;
+}
+
+impl<F: Copy + FnOnce(TokenMarker) -> T, T: Token> Peek for F {
+ type Token = T;
+}
+
+pub enum TokenMarker {}
+
+impl<S> IntoSpans<S> for TokenMarker {
+ fn into_spans(self) -> S {
+ match self {}
+ }
+}
+
+pub(crate) fn is_delimiter(cursor: Cursor, delimiter: Delimiter) -> bool {
+ cursor.group(delimiter).is_some()
+}
+
+impl<F: Copy + FnOnce(TokenMarker) -> T, T: Token> Sealed for F {}
diff --git a/rust/hw/char/pl011/vendor/syn/src/mac.rs b/rust/hw/char/pl011/vendor/syn/src/mac.rs
new file mode 100644
index 0000000000..7e1876c648
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/mac.rs
@@ -0,0 +1,223 @@
+#[cfg(feature = "parsing")]
+use crate::error::Result;
+#[cfg(feature = "parsing")]
+use crate::parse::{Parse, ParseStream, Parser};
+use crate::path::Path;
+use crate::token::{Brace, Bracket, Paren};
+use proc_macro2::extra::DelimSpan;
+#[cfg(feature = "parsing")]
+use proc_macro2::Delimiter;
+use proc_macro2::TokenStream;
+#[cfg(feature = "parsing")]
+use proc_macro2::TokenTree;
+
+ast_struct! {
+ /// A macro invocation: `println!("{}", mac)`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct Macro {
+ pub path: Path,
+ pub bang_token: Token![!],
+ pub delimiter: MacroDelimiter,
+ pub tokens: TokenStream,
+ }
+}
+
+ast_enum! {
+ /// A grouping token that surrounds a macro body: `m!(...)` or `m!{...}` or `m![...]`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub enum MacroDelimiter {
+ Paren(Paren),
+ Brace(Brace),
+ Bracket(Bracket),
+ }
+}
+
+impl MacroDelimiter {
+ pub fn span(&self) -> &DelimSpan {
+ match self {
+ MacroDelimiter::Paren(token) => &token.span,
+ MacroDelimiter::Brace(token) => &token.span,
+ MacroDelimiter::Bracket(token) => &token.span,
+ }
+ }
+
+ #[cfg(all(feature = "full", any(feature = "parsing", feature = "printing")))]
+ pub(crate) fn is_brace(&self) -> bool {
+ match self {
+ MacroDelimiter::Brace(_) => true,
+ MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => false,
+ }
+ }
+}
+
+impl Macro {
+ /// Parse the tokens within the macro invocation's delimiters into a syntax
+ /// tree.
+ ///
+ /// This is equivalent to `syn::parse2::<T>(mac.tokens)` except that it
+ /// produces a more useful span when `tokens` is empty.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use syn::{parse_quote, Expr, ExprLit, Ident, Lit, LitStr, Macro, Token};
+ /// use syn::ext::IdentExt;
+ /// use syn::parse::{Error, Parse, ParseStream, Result};
+ /// use syn::punctuated::Punctuated;
+ ///
+ /// // The arguments expected by libcore's format_args macro, and as a
+ /// // result most other formatting and printing macros like println.
+ /// //
+ /// // println!("{} is {number:.prec$}", "x", prec=5, number=0.01)
+ /// struct FormatArgs {
+ /// format_string: Expr,
+ /// positional_args: Vec<Expr>,
+ /// named_args: Vec<(Ident, Expr)>,
+ /// }
+ ///
+ /// impl Parse for FormatArgs {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let format_string: Expr;
+ /// let mut positional_args = Vec::new();
+ /// let mut named_args = Vec::new();
+ ///
+ /// format_string = input.parse()?;
+ /// while !input.is_empty() {
+ /// input.parse::<Token![,]>()?;
+ /// if input.is_empty() {
+ /// break;
+ /// }
+ /// if input.peek(Ident::peek_any) && input.peek2(Token![=]) {
+ /// while !input.is_empty() {
+ /// let name: Ident = input.call(Ident::parse_any)?;
+ /// input.parse::<Token![=]>()?;
+ /// let value: Expr = input.parse()?;
+ /// named_args.push((name, value));
+ /// if input.is_empty() {
+ /// break;
+ /// }
+ /// input.parse::<Token![,]>()?;
+ /// }
+ /// break;
+ /// }
+ /// positional_args.push(input.parse()?);
+ /// }
+ ///
+ /// Ok(FormatArgs {
+ /// format_string,
+ /// positional_args,
+ /// named_args,
+ /// })
+ /// }
+ /// }
+ ///
+ /// // Extract the first argument, the format string literal, from an
+ /// // invocation of a formatting or printing macro.
+ /// fn get_format_string(m: &Macro) -> Result<LitStr> {
+ /// let args: FormatArgs = m.parse_body()?;
+ /// match args.format_string {
+ /// Expr::Lit(ExprLit { lit: Lit::Str(lit), .. }) => Ok(lit),
+ /// other => {
+ /// // First argument was not a string literal expression.
+ /// // Maybe something like: println!(concat!(...), ...)
+ /// Err(Error::new_spanned(other, "format string must be a string literal"))
+ /// }
+ /// }
+ /// }
+ ///
+ /// fn main() {
+ /// let invocation = parse_quote! {
+ /// println!("{:?}", Instant::now())
+ /// };
+ /// let lit = get_format_string(&invocation).unwrap();
+ /// assert_eq!(lit.value(), "{:?}");
+ /// }
+ /// ```
+ #[cfg(feature = "parsing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn parse_body<T: Parse>(&self) -> Result<T> {
+ self.parse_body_with(T::parse)
+ }
+
+ /// Parse the tokens within the macro invocation's delimiters using the
+ /// given parser.
+ #[cfg(feature = "parsing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn parse_body_with<F: Parser>(&self, parser: F) -> Result<F::Output> {
+ let scope = self.delimiter.span().close();
+ crate::parse::parse_scoped(parser, scope, self.tokens.clone())
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) fn parse_delimiter(input: ParseStream) -> Result<(MacroDelimiter, TokenStream)> {
+ input.step(|cursor| {
+ if let Some((TokenTree::Group(g), rest)) = cursor.token_tree() {
+ let span = g.delim_span();
+ let delimiter = match g.delimiter() {
+ Delimiter::Parenthesis => MacroDelimiter::Paren(Paren(span)),
+ Delimiter::Brace => MacroDelimiter::Brace(Brace(span)),
+ Delimiter::Bracket => MacroDelimiter::Bracket(Bracket(span)),
+ Delimiter::None => {
+ return Err(cursor.error("expected delimiter"));
+ }
+ };
+ Ok(((delimiter, g.stream()), rest))
+ } else {
+ Err(cursor.error("expected delimiter"))
+ }
+ })
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::error::Result;
+ use crate::mac::{parse_delimiter, Macro};
+ use crate::parse::{Parse, ParseStream};
+ use crate::path::Path;
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Macro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let tokens;
+ Ok(Macro {
+ path: input.call(Path::parse_mod_style)?,
+ bang_token: input.parse()?,
+ delimiter: {
+ let (delimiter, content) = parse_delimiter(input)?;
+ tokens = content;
+ delimiter
+ },
+ tokens,
+ })
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use crate::mac::{Macro, MacroDelimiter};
+ use crate::token;
+ use proc_macro2::{Delimiter, TokenStream};
+ use quote::ToTokens;
+
+ impl MacroDelimiter {
+ pub(crate) fn surround(&self, tokens: &mut TokenStream, inner: TokenStream) {
+ let (delim, span) = match self {
+ MacroDelimiter::Paren(paren) => (Delimiter::Parenthesis, paren.span),
+ MacroDelimiter::Brace(brace) => (Delimiter::Brace, brace.span),
+ MacroDelimiter::Bracket(bracket) => (Delimiter::Bracket, bracket.span),
+ };
+ token::printing::delim(delim, span.join(), tokens, inner);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Macro {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.path.to_tokens(tokens);
+ self.bang_token.to_tokens(tokens);
+ self.delimiter.surround(tokens, self.tokens.clone());
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/macros.rs b/rust/hw/char/pl011/vendor/syn/src/macros.rs
new file mode 100644
index 0000000000..2b6708d495
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/macros.rs
@@ -0,0 +1,166 @@
+#[cfg_attr(
+ not(any(feature = "full", feature = "derive")),
+ allow(unknown_lints, unused_macro_rules)
+)]
+macro_rules! ast_struct {
+ (
+ $(#[$attr:meta])*
+ $pub:ident $struct:ident $name:ident #full $body:tt
+ ) => {
+ check_keyword_matches!(pub $pub);
+ check_keyword_matches!(struct $struct);
+
+ #[cfg(feature = "full")]
+ $(#[$attr])* $pub $struct $name $body
+
+ #[cfg(not(feature = "full"))]
+ $(#[$attr])* $pub $struct $name {
+ _noconstruct: ::std::marker::PhantomData<::proc_macro2::Span>,
+ }
+
+ #[cfg(all(not(feature = "full"), feature = "printing"))]
+ impl ::quote::ToTokens for $name {
+ fn to_tokens(&self, _: &mut ::proc_macro2::TokenStream) {
+ unreachable!()
+ }
+ }
+ };
+
+ (
+ $(#[$attr:meta])*
+ $pub:ident $struct:ident $name:ident $body:tt
+ ) => {
+ check_keyword_matches!(pub $pub);
+ check_keyword_matches!(struct $struct);
+
+ $(#[$attr])* $pub $struct $name $body
+ };
+}
+
+#[cfg(any(feature = "full", feature = "derive"))]
+macro_rules! ast_enum {
+ (
+ $(#[$enum_attr:meta])*
+ $pub:ident $enum:ident $name:ident $body:tt
+ ) => {
+ check_keyword_matches!(pub $pub);
+ check_keyword_matches!(enum $enum);
+
+ $(#[$enum_attr])* $pub $enum $name $body
+ };
+}
+
+macro_rules! ast_enum_of_structs {
+ (
+ $(#[$enum_attr:meta])*
+ $pub:ident $enum:ident $name:ident $body:tt
+ ) => {
+ check_keyword_matches!(pub $pub);
+ check_keyword_matches!(enum $enum);
+
+ $(#[$enum_attr])* $pub $enum $name $body
+
+ ast_enum_of_structs_impl!($name $body);
+
+ #[cfg(feature = "printing")]
+ generate_to_tokens!(() tokens $name $body);
+ };
+}
+
+macro_rules! ast_enum_of_structs_impl {
+ (
+ $name:ident {
+ $(
+ $(#[cfg $cfg_attr:tt])*
+ $(#[doc $($doc_attr:tt)*])*
+ $variant:ident $( ($member:ident) )*,
+ )*
+ }
+ ) => {
+ $($(
+ ast_enum_from_struct!($name::$variant, $member);
+ )*)*
+ };
+}
+
+macro_rules! ast_enum_from_struct {
+ // No From<TokenStream> for verbatim variants.
+ ($name:ident::Verbatim, $member:ident) => {};
+
+ ($name:ident::$variant:ident, $member:ident) => {
+ impl From<$member> for $name {
+ fn from(e: $member) -> $name {
+ $name::$variant(e)
+ }
+ }
+ };
+}
+
+#[cfg(feature = "printing")]
+macro_rules! generate_to_tokens {
+ (
+ ($($arms:tt)*) $tokens:ident $name:ident {
+ $(#[cfg $cfg_attr:tt])*
+ $(#[doc $($doc_attr:tt)*])*
+ $variant:ident,
+ $($next:tt)*
+ }
+ ) => {
+ generate_to_tokens!(
+ ($($arms)* $(#[cfg $cfg_attr])* $name::$variant => {})
+ $tokens $name { $($next)* }
+ );
+ };
+
+ (
+ ($($arms:tt)*) $tokens:ident $name:ident {
+ $(#[cfg $cfg_attr:tt])*
+ $(#[doc $($doc_attr:tt)*])*
+ $variant:ident($member:ident),
+ $($next:tt)*
+ }
+ ) => {
+ generate_to_tokens!(
+ ($($arms)* $(#[cfg $cfg_attr])* $name::$variant(_e) => _e.to_tokens($tokens),)
+ $tokens $name { $($next)* }
+ );
+ };
+
+ (($($arms:tt)*) $tokens:ident $name:ident {}) => {
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ::quote::ToTokens for $name {
+ fn to_tokens(&self, $tokens: &mut ::proc_macro2::TokenStream) {
+ match self {
+ $($arms)*
+ }
+ }
+ }
+ };
+}
+
+// Rustdoc bug: does not respect the doc(hidden) on some items.
+#[cfg(all(doc, feature = "parsing"))]
+macro_rules! pub_if_not_doc {
+ ($(#[$m:meta])* $pub:ident $($item:tt)*) => {
+ check_keyword_matches!(pub $pub);
+
+ $(#[$m])*
+ $pub(crate) $($item)*
+ };
+}
+
+#[cfg(all(not(doc), feature = "parsing"))]
+macro_rules! pub_if_not_doc {
+ ($(#[$m:meta])* $pub:ident $($item:tt)*) => {
+ check_keyword_matches!(pub $pub);
+
+ $(#[$m])*
+ $pub $($item)*
+ };
+}
+
+macro_rules! check_keyword_matches {
+ (enum enum) => {};
+ (pub pub) => {};
+ (struct struct) => {};
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/meta.rs b/rust/hw/char/pl011/vendor/syn/src/meta.rs
new file mode 100644
index 0000000000..ffeeb2629f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/meta.rs
@@ -0,0 +1,427 @@
+//! Facility for interpreting structured content inside of an `Attribute`.
+
+use crate::error::{Error, Result};
+use crate::ext::IdentExt as _;
+use crate::lit::Lit;
+use crate::parse::{ParseStream, Parser};
+use crate::path::{Path, PathSegment};
+use crate::punctuated::Punctuated;
+use proc_macro2::Ident;
+use std::fmt::Display;
+
+/// Make a parser that is usable with `parse_macro_input!` in a
+/// `#[proc_macro_attribute]` macro.
+///
+/// *Warning:* When parsing attribute args **other than** the
+/// `proc_macro::TokenStream` input of a `proc_macro_attribute`, you do **not**
+/// need this function. In several cases your callers will get worse error
+/// messages if you use this function, because the surrounding delimiter's span
+/// is concealed from attribute macros by rustc. Use
+/// [`Attribute::parse_nested_meta`] instead.
+///
+/// [`Attribute::parse_nested_meta`]: crate::Attribute::parse_nested_meta
+///
+/// # Example
+///
+/// This example implements an attribute macro whose invocations look like this:
+///
+/// ```
+/// # const IGNORE: &str = stringify! {
+/// #[tea(kind = "EarlGrey", hot)]
+/// struct Picard {...}
+/// # };
+/// ```
+///
+/// The "parameters" supported by the attribute are:
+///
+/// - `kind = "..."`
+/// - `hot`
+/// - `with(sugar, milk, ...)`, a comma-separated list of ingredients
+///
+/// ```
+/// # extern crate proc_macro;
+/// #
+/// use proc_macro::TokenStream;
+/// use syn::{parse_macro_input, LitStr, Path};
+///
+/// # const IGNORE: &str = stringify! {
+/// #[proc_macro_attribute]
+/// # };
+/// pub fn tea(args: TokenStream, input: TokenStream) -> TokenStream {
+/// let mut kind: Option<LitStr> = None;
+/// let mut hot: bool = false;
+/// let mut with: Vec<Path> = Vec::new();
+/// let tea_parser = syn::meta::parser(|meta| {
+/// if meta.path.is_ident("kind") {
+/// kind = Some(meta.value()?.parse()?);
+/// Ok(())
+/// } else if meta.path.is_ident("hot") {
+/// hot = true;
+/// Ok(())
+/// } else if meta.path.is_ident("with") {
+/// meta.parse_nested_meta(|meta| {
+/// with.push(meta.path);
+/// Ok(())
+/// })
+/// } else {
+/// Err(meta.error("unsupported tea property"))
+/// }
+/// });
+///
+/// parse_macro_input!(args with tea_parser);
+/// eprintln!("kind={kind:?} hot={hot} with={with:?}");
+///
+/// /* ... */
+/// # TokenStream::new()
+/// }
+/// ```
+///
+/// The `syn::meta` library will take care of dealing with the commas including
+/// trailing commas, and producing sensible error messages on unexpected input.
+///
+/// ```console
+/// error: expected `,`
+/// --> src/main.rs:3:37
+/// |
+/// 3 | #[tea(kind = "EarlGrey", with(sugar = "lol", milk))]
+/// | ^
+/// ```
+///
+/// # Example
+///
+/// Same as above but we factor out most of the logic into a separate function.
+///
+/// ```
+/// # extern crate proc_macro;
+/// #
+/// use proc_macro::TokenStream;
+/// use syn::meta::ParseNestedMeta;
+/// use syn::parse::{Parser, Result};
+/// use syn::{parse_macro_input, LitStr, Path};
+///
+/// # const IGNORE: &str = stringify! {
+/// #[proc_macro_attribute]
+/// # };
+/// pub fn tea(args: TokenStream, input: TokenStream) -> TokenStream {
+/// let mut attrs = TeaAttributes::default();
+/// let tea_parser = syn::meta::parser(|meta| attrs.parse(meta));
+/// parse_macro_input!(args with tea_parser);
+///
+/// /* ... */
+/// # TokenStream::new()
+/// }
+///
+/// #[derive(Default)]
+/// struct TeaAttributes {
+/// kind: Option<LitStr>,
+/// hot: bool,
+/// with: Vec<Path>,
+/// }
+///
+/// impl TeaAttributes {
+/// fn parse(&mut self, meta: ParseNestedMeta) -> Result<()> {
+/// if meta.path.is_ident("kind") {
+/// self.kind = Some(meta.value()?.parse()?);
+/// Ok(())
+/// } else /* just like in last example */
+/// # { unimplemented!() }
+///
+/// }
+/// }
+/// ```
+pub fn parser(logic: impl FnMut(ParseNestedMeta) -> Result<()>) -> impl Parser<Output = ()> {
+ |input: ParseStream| {
+ if input.is_empty() {
+ Ok(())
+ } else {
+ parse_nested_meta(input, logic)
+ }
+ }
+}
+
+/// Context for parsing a single property in the conventional syntax for
+/// structured attributes.
+///
+/// # Examples
+///
+/// Refer to usage examples on the following two entry-points:
+///
+/// - [`Attribute::parse_nested_meta`] if you have an entire `Attribute` to
+/// parse. Always use this if possible. Generally this is able to produce
+/// better error messages because `Attribute` holds span information for all
+/// of the delimiters therein.
+///
+/// - [`syn::meta::parser`] if you are implementing a `proc_macro_attribute`
+/// macro and parsing the arguments to the attribute macro, i.e. the ones
+/// written in the same attribute that dispatched the macro invocation. Rustc
+/// does not pass span information for the surrounding delimiters into the
+/// attribute macro invocation in this situation, so error messages might be
+/// less precise.
+///
+/// [`Attribute::parse_nested_meta`]: crate::Attribute::parse_nested_meta
+/// [`syn::meta::parser`]: crate::meta::parser
+#[non_exhaustive]
+pub struct ParseNestedMeta<'a> {
+ pub path: Path,
+ pub input: ParseStream<'a>,
+}
+
+impl<'a> ParseNestedMeta<'a> {
+ /// Used when parsing `key = "value"` syntax.
+ ///
+ /// All it does is advance `meta.input` past the `=` sign in the input. You
+ /// could accomplish the same effect by writing
+ /// `meta.parse::<Token![=]>()?`, so at most it is a minor convenience to
+ /// use `meta.value()?`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use syn::{parse_quote, Attribute, LitStr};
+ ///
+ /// let attr: Attribute = parse_quote! {
+ /// #[tea(kind = "EarlGrey")]
+ /// };
+ /// // conceptually:
+ /// if attr.path().is_ident("tea") { // this parses the `tea`
+ /// attr.parse_nested_meta(|meta| { // this parses the `(`
+ /// if meta.path.is_ident("kind") { // this parses the `kind`
+ /// let value = meta.value()?; // this parses the `=`
+ /// let s: LitStr = value.parse()?; // this parses `"EarlGrey"`
+ /// if s.value() == "EarlGrey" {
+ /// // ...
+ /// }
+ /// Ok(())
+ /// } else {
+ /// Err(meta.error("unsupported attribute"))
+ /// }
+ /// })?;
+ /// }
+ /// # anyhow::Ok(())
+ /// ```
+ pub fn value(&self) -> Result<ParseStream<'a>> {
+ self.input.parse::<Token![=]>()?;
+ Ok(self.input)
+ }
+
+ /// Used when parsing `list(...)` syntax **if** the content inside the
+ /// nested parentheses is also expected to conform to Rust's structured
+ /// attribute convention.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use syn::{parse_quote, Attribute};
+ ///
+ /// let attr: Attribute = parse_quote! {
+ /// #[tea(with(sugar, milk))]
+ /// };
+ ///
+ /// if attr.path().is_ident("tea") {
+ /// attr.parse_nested_meta(|meta| {
+ /// if meta.path.is_ident("with") {
+ /// meta.parse_nested_meta(|meta| { // <---
+ /// if meta.path.is_ident("sugar") {
+ /// // Here we can go even deeper if needed.
+ /// Ok(())
+ /// } else if meta.path.is_ident("milk") {
+ /// Ok(())
+ /// } else {
+ /// Err(meta.error("unsupported ingredient"))
+ /// }
+ /// })
+ /// } else {
+ /// Err(meta.error("unsupported tea property"))
+ /// }
+ /// })?;
+ /// }
+ /// # anyhow::Ok(())
+ /// ```
+ ///
+ /// # Counterexample
+ ///
+ /// If you don't need `parse_nested_meta`'s help in parsing the content
+ /// written within the nested parentheses, keep in mind that you can always
+ /// just parse it yourself from the exposed ParseStream. Rust syntax permits
+ /// arbitrary tokens within those parentheses so for the crazier stuff,
+ /// `parse_nested_meta` is not what you want.
+ ///
+ /// ```
+ /// use syn::{parenthesized, parse_quote, Attribute, LitInt};
+ ///
+ /// let attr: Attribute = parse_quote! {
+ /// #[repr(align(32))]
+ /// };
+ ///
+ /// let mut align: Option<LitInt> = None;
+ /// if attr.path().is_ident("repr") {
+ /// attr.parse_nested_meta(|meta| {
+ /// if meta.path.is_ident("align") {
+ /// let content;
+ /// parenthesized!(content in meta.input);
+ /// align = Some(content.parse()?);
+ /// Ok(())
+ /// } else {
+ /// Err(meta.error("unsupported repr"))
+ /// }
+ /// })?;
+ /// }
+ /// # anyhow::Ok(())
+ /// ```
+ pub fn parse_nested_meta(
+ &self,
+ logic: impl FnMut(ParseNestedMeta) -> Result<()>,
+ ) -> Result<()> {
+ let content;
+ parenthesized!(content in self.input);
+ parse_nested_meta(&content, logic)
+ }
+
+ /// Report that the attribute's content did not conform to expectations.
+ ///
+ /// The span of the resulting error will cover `meta.path` *and* everything
+ /// that has been parsed so far since it.
+ ///
+ /// There are 2 ways you might call this. First, if `meta.path` is not
+ /// something you recognize:
+ ///
+ /// ```
+ /// # use syn::Attribute;
+ /// #
+ /// # fn example(attr: &Attribute) -> syn::Result<()> {
+ /// attr.parse_nested_meta(|meta| {
+ /// if meta.path.is_ident("kind") {
+ /// // ...
+ /// Ok(())
+ /// } else {
+ /// Err(meta.error("unsupported tea property"))
+ /// }
+ /// })?;
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// In this case, it behaves exactly like
+ /// `syn::Error::new_spanned(&meta.path, "message...")`.
+ ///
+ /// ```console
+ /// error: unsupported tea property
+ /// --> src/main.rs:3:26
+ /// |
+ /// 3 | #[tea(kind = "EarlGrey", wat = "foo")]
+ /// | ^^^
+ /// ```
+ ///
+ /// More usefully, the second place is if you've already parsed a value but
+ /// have decided not to accept the value:
+ ///
+ /// ```
+ /// # use syn::Attribute;
+ /// #
+ /// # fn example(attr: &Attribute) -> syn::Result<()> {
+ /// use syn::Expr;
+ ///
+ /// attr.parse_nested_meta(|meta| {
+ /// if meta.path.is_ident("kind") {
+ /// let expr: Expr = meta.value()?.parse()?;
+ /// match expr {
+ /// Expr::Lit(expr) => /* ... */
+ /// # unimplemented!(),
+ /// Expr::Path(expr) => /* ... */
+ /// # unimplemented!(),
+ /// Expr::Macro(expr) => /* ... */
+ /// # unimplemented!(),
+ /// _ => Err(meta.error("tea kind must be a string literal, path, or macro")),
+ /// }
+ /// } else /* as above */
+ /// # { unimplemented!() }
+ ///
+ /// })?;
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// ```console
+ /// error: tea kind must be a string literal, path, or macro
+ /// --> src/main.rs:3:7
+ /// |
+ /// 3 | #[tea(kind = async { replicator.await })]
+ /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ /// ```
+ ///
+ /// Often you may want to use `syn::Error::new_spanned` even in this
+ /// situation. In the above code, that would be:
+ ///
+ /// ```
+ /// # use syn::{Error, Expr};
+ /// #
+ /// # fn example(expr: Expr) -> syn::Result<()> {
+ /// match expr {
+ /// Expr::Lit(expr) => /* ... */
+ /// # unimplemented!(),
+ /// Expr::Path(expr) => /* ... */
+ /// # unimplemented!(),
+ /// Expr::Macro(expr) => /* ... */
+ /// # unimplemented!(),
+ /// _ => Err(Error::new_spanned(expr, "unsupported expression type for `kind`")),
+ /// }
+ /// # }
+ /// ```
+ ///
+ /// ```console
+ /// error: unsupported expression type for `kind`
+ /// --> src/main.rs:3:14
+ /// |
+ /// 3 | #[tea(kind = async { replicator.await })]
+ /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ /// ```
+ pub fn error(&self, msg: impl Display) -> Error {
+ let start_span = self.path.segments[0].ident.span();
+ let end_span = self.input.cursor().prev_span();
+ crate::error::new2(start_span, end_span, msg)
+ }
+}
+
+pub(crate) fn parse_nested_meta(
+ input: ParseStream,
+ mut logic: impl FnMut(ParseNestedMeta) -> Result<()>,
+) -> Result<()> {
+ loop {
+ let path = input.call(parse_meta_path)?;
+ logic(ParseNestedMeta { path, input })?;
+ if input.is_empty() {
+ return Ok(());
+ }
+ input.parse::<Token![,]>()?;
+ if input.is_empty() {
+ return Ok(());
+ }
+ }
+}
+
+// Like Path::parse_mod_style, but accepts keywords in the path.
+fn parse_meta_path(input: ParseStream) -> Result<Path> {
+ Ok(Path {
+ leading_colon: input.parse()?,
+ segments: {
+ let mut segments = Punctuated::new();
+ if input.peek(Ident::peek_any) {
+ let ident = Ident::parse_any(input)?;
+ segments.push_value(PathSegment::from(ident));
+ } else if input.is_empty() {
+ return Err(input.error("expected nested attribute"));
+ } else if input.peek(Lit) {
+ return Err(input.error("unexpected literal in nested attribute, expected ident"));
+ } else {
+ return Err(input.error("unexpected token in nested attribute, expected ident"));
+ }
+ while input.peek(Token![::]) {
+ let punct = input.parse()?;
+ segments.push_punct(punct);
+ let ident = Ident::parse_any(input)?;
+ segments.push_value(PathSegment::from(ident));
+ }
+ segments
+ },
+ })
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/op.rs b/rust/hw/char/pl011/vendor/syn/src/op.rs
new file mode 100644
index 0000000000..575d9faa12
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/op.rs
@@ -0,0 +1,219 @@
+ast_enum! {
+ /// A binary operator: `+`, `+=`, `&`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ #[non_exhaustive]
+ pub enum BinOp {
+ /// The `+` operator (addition)
+ Add(Token![+]),
+ /// The `-` operator (subtraction)
+ Sub(Token![-]),
+ /// The `*` operator (multiplication)
+ Mul(Token![*]),
+ /// The `/` operator (division)
+ Div(Token![/]),
+ /// The `%` operator (modulus)
+ Rem(Token![%]),
+ /// The `&&` operator (logical and)
+ And(Token![&&]),
+ /// The `||` operator (logical or)
+ Or(Token![||]),
+ /// The `^` operator (bitwise xor)
+ BitXor(Token![^]),
+ /// The `&` operator (bitwise and)
+ BitAnd(Token![&]),
+ /// The `|` operator (bitwise or)
+ BitOr(Token![|]),
+ /// The `<<` operator (shift left)
+ Shl(Token![<<]),
+ /// The `>>` operator (shift right)
+ Shr(Token![>>]),
+ /// The `==` operator (equality)
+ Eq(Token![==]),
+ /// The `<` operator (less than)
+ Lt(Token![<]),
+ /// The `<=` operator (less than or equal to)
+ Le(Token![<=]),
+ /// The `!=` operator (not equal to)
+ Ne(Token![!=]),
+ /// The `>=` operator (greater than or equal to)
+ Ge(Token![>=]),
+ /// The `>` operator (greater than)
+ Gt(Token![>]),
+ /// The `+=` operator
+ AddAssign(Token![+=]),
+ /// The `-=` operator
+ SubAssign(Token![-=]),
+ /// The `*=` operator
+ MulAssign(Token![*=]),
+ /// The `/=` operator
+ DivAssign(Token![/=]),
+ /// The `%=` operator
+ RemAssign(Token![%=]),
+ /// The `^=` operator
+ BitXorAssign(Token![^=]),
+ /// The `&=` operator
+ BitAndAssign(Token![&=]),
+ /// The `|=` operator
+ BitOrAssign(Token![|=]),
+ /// The `<<=` operator
+ ShlAssign(Token![<<=]),
+ /// The `>>=` operator
+ ShrAssign(Token![>>=]),
+ }
+}
+
+ast_enum! {
+ /// A unary operator: `*`, `!`, `-`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ #[non_exhaustive]
+ pub enum UnOp {
+ /// The `*` operator for dereferencing
+ Deref(Token![*]),
+ /// The `!` operator for logical inversion
+ Not(Token![!]),
+ /// The `-` operator for negation
+ Neg(Token![-]),
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::error::Result;
+ use crate::op::{BinOp, UnOp};
+ use crate::parse::{Parse, ParseStream};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for BinOp {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![+=]) {
+ input.parse().map(BinOp::AddAssign)
+ } else if input.peek(Token![-=]) {
+ input.parse().map(BinOp::SubAssign)
+ } else if input.peek(Token![*=]) {
+ input.parse().map(BinOp::MulAssign)
+ } else if input.peek(Token![/=]) {
+ input.parse().map(BinOp::DivAssign)
+ } else if input.peek(Token![%=]) {
+ input.parse().map(BinOp::RemAssign)
+ } else if input.peek(Token![^=]) {
+ input.parse().map(BinOp::BitXorAssign)
+ } else if input.peek(Token![&=]) {
+ input.parse().map(BinOp::BitAndAssign)
+ } else if input.peek(Token![|=]) {
+ input.parse().map(BinOp::BitOrAssign)
+ } else if input.peek(Token![<<=]) {
+ input.parse().map(BinOp::ShlAssign)
+ } else if input.peek(Token![>>=]) {
+ input.parse().map(BinOp::ShrAssign)
+ } else if input.peek(Token![&&]) {
+ input.parse().map(BinOp::And)
+ } else if input.peek(Token![||]) {
+ input.parse().map(BinOp::Or)
+ } else if input.peek(Token![<<]) {
+ input.parse().map(BinOp::Shl)
+ } else if input.peek(Token![>>]) {
+ input.parse().map(BinOp::Shr)
+ } else if input.peek(Token![==]) {
+ input.parse().map(BinOp::Eq)
+ } else if input.peek(Token![<=]) {
+ input.parse().map(BinOp::Le)
+ } else if input.peek(Token![!=]) {
+ input.parse().map(BinOp::Ne)
+ } else if input.peek(Token![>=]) {
+ input.parse().map(BinOp::Ge)
+ } else if input.peek(Token![+]) {
+ input.parse().map(BinOp::Add)
+ } else if input.peek(Token![-]) {
+ input.parse().map(BinOp::Sub)
+ } else if input.peek(Token![*]) {
+ input.parse().map(BinOp::Mul)
+ } else if input.peek(Token![/]) {
+ input.parse().map(BinOp::Div)
+ } else if input.peek(Token![%]) {
+ input.parse().map(BinOp::Rem)
+ } else if input.peek(Token![^]) {
+ input.parse().map(BinOp::BitXor)
+ } else if input.peek(Token![&]) {
+ input.parse().map(BinOp::BitAnd)
+ } else if input.peek(Token![|]) {
+ input.parse().map(BinOp::BitOr)
+ } else if input.peek(Token![<]) {
+ input.parse().map(BinOp::Lt)
+ } else if input.peek(Token![>]) {
+ input.parse().map(BinOp::Gt)
+ } else {
+ Err(input.error("expected binary operator"))
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for UnOp {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Token![*]) {
+ input.parse().map(UnOp::Deref)
+ } else if lookahead.peek(Token![!]) {
+ input.parse().map(UnOp::Not)
+ } else if lookahead.peek(Token![-]) {
+ input.parse().map(UnOp::Neg)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use crate::op::{BinOp, UnOp};
+ use proc_macro2::TokenStream;
+ use quote::ToTokens;
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for BinOp {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ BinOp::Add(t) => t.to_tokens(tokens),
+ BinOp::Sub(t) => t.to_tokens(tokens),
+ BinOp::Mul(t) => t.to_tokens(tokens),
+ BinOp::Div(t) => t.to_tokens(tokens),
+ BinOp::Rem(t) => t.to_tokens(tokens),
+ BinOp::And(t) => t.to_tokens(tokens),
+ BinOp::Or(t) => t.to_tokens(tokens),
+ BinOp::BitXor(t) => t.to_tokens(tokens),
+ BinOp::BitAnd(t) => t.to_tokens(tokens),
+ BinOp::BitOr(t) => t.to_tokens(tokens),
+ BinOp::Shl(t) => t.to_tokens(tokens),
+ BinOp::Shr(t) => t.to_tokens(tokens),
+ BinOp::Eq(t) => t.to_tokens(tokens),
+ BinOp::Lt(t) => t.to_tokens(tokens),
+ BinOp::Le(t) => t.to_tokens(tokens),
+ BinOp::Ne(t) => t.to_tokens(tokens),
+ BinOp::Ge(t) => t.to_tokens(tokens),
+ BinOp::Gt(t) => t.to_tokens(tokens),
+ BinOp::AddAssign(t) => t.to_tokens(tokens),
+ BinOp::SubAssign(t) => t.to_tokens(tokens),
+ BinOp::MulAssign(t) => t.to_tokens(tokens),
+ BinOp::DivAssign(t) => t.to_tokens(tokens),
+ BinOp::RemAssign(t) => t.to_tokens(tokens),
+ BinOp::BitXorAssign(t) => t.to_tokens(tokens),
+ BinOp::BitAndAssign(t) => t.to_tokens(tokens),
+ BinOp::BitOrAssign(t) => t.to_tokens(tokens),
+ BinOp::ShlAssign(t) => t.to_tokens(tokens),
+ BinOp::ShrAssign(t) => t.to_tokens(tokens),
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for UnOp {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ UnOp::Deref(t) => t.to_tokens(tokens),
+ UnOp::Not(t) => t.to_tokens(tokens),
+ UnOp::Neg(t) => t.to_tokens(tokens),
+ }
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/parse.rs b/rust/hw/char/pl011/vendor/syn/src/parse.rs
new file mode 100644
index 0000000000..a80a914760
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/parse.rs
@@ -0,0 +1,1397 @@
+//! Parsing interface for parsing a token stream into a syntax tree node.
+//!
+//! Parsing in Syn is built on parser functions that take in a [`ParseStream`]
+//! and produce a [`Result<T>`] where `T` is some syntax tree node. Underlying
+//! these parser functions is a lower level mechanism built around the
+//! [`Cursor`] type. `Cursor` is a cheaply copyable cursor over a range of
+//! tokens in a token stream.
+//!
+//! [`Result<T>`]: Result
+//! [`Cursor`]: crate::buffer::Cursor
+//!
+//! # Example
+//!
+//! Here is a snippet of parsing code to get a feel for the style of the
+//! library. We define data structures for a subset of Rust syntax including
+//! enums (not shown) and structs, then provide implementations of the [`Parse`]
+//! trait to parse these syntax tree data structures from a token stream.
+//!
+//! Once `Parse` impls have been defined, they can be called conveniently from a
+//! procedural macro through [`parse_macro_input!`] as shown at the bottom of
+//! the snippet. If the caller provides syntactically invalid input to the
+//! procedural macro, they will receive a helpful compiler error message
+//! pointing out the exact token that triggered the failure to parse.
+//!
+//! [`parse_macro_input!`]: crate::parse_macro_input!
+//!
+//! ```
+//! # extern crate proc_macro;
+//! #
+//! use proc_macro::TokenStream;
+//! use syn::{braced, parse_macro_input, token, Field, Ident, Result, Token};
+//! use syn::parse::{Parse, ParseStream};
+//! use syn::punctuated::Punctuated;
+//!
+//! enum Item {
+//! Struct(ItemStruct),
+//! Enum(ItemEnum),
+//! }
+//!
+//! struct ItemStruct {
+//! struct_token: Token![struct],
+//! ident: Ident,
+//! brace_token: token::Brace,
+//! fields: Punctuated<Field, Token![,]>,
+//! }
+//! #
+//! # enum ItemEnum {}
+//!
+//! impl Parse for Item {
+//! fn parse(input: ParseStream) -> Result<Self> {
+//! let lookahead = input.lookahead1();
+//! if lookahead.peek(Token![struct]) {
+//! input.parse().map(Item::Struct)
+//! } else if lookahead.peek(Token![enum]) {
+//! input.parse().map(Item::Enum)
+//! } else {
+//! Err(lookahead.error())
+//! }
+//! }
+//! }
+//!
+//! impl Parse for ItemStruct {
+//! fn parse(input: ParseStream) -> Result<Self> {
+//! let content;
+//! Ok(ItemStruct {
+//! struct_token: input.parse()?,
+//! ident: input.parse()?,
+//! brace_token: braced!(content in input),
+//! fields: content.parse_terminated(Field::parse_named, Token![,])?,
+//! })
+//! }
+//! }
+//! #
+//! # impl Parse for ItemEnum {
+//! # fn parse(input: ParseStream) -> Result<Self> {
+//! # unimplemented!()
+//! # }
+//! # }
+//!
+//! # const IGNORE: &str = stringify! {
+//! #[proc_macro]
+//! # };
+//! pub fn my_macro(tokens: TokenStream) -> TokenStream {
+//! let input = parse_macro_input!(tokens as Item);
+//!
+//! /* ... */
+//! # TokenStream::new()
+//! }
+//! ```
+//!
+//! # The `syn::parse*` functions
+//!
+//! The [`syn::parse`], [`syn::parse2`], and [`syn::parse_str`] functions serve
+//! as an entry point for parsing syntax tree nodes that can be parsed in an
+//! obvious default way. These functions can return any syntax tree node that
+//! implements the [`Parse`] trait, which includes most types in Syn.
+//!
+//! [`syn::parse`]: crate::parse()
+//! [`syn::parse2`]: crate::parse2()
+//! [`syn::parse_str`]: crate::parse_str()
+//!
+//! ```
+//! use syn::Type;
+//!
+//! # fn run_parser() -> syn::Result<()> {
+//! let t: Type = syn::parse_str("std::collections::HashMap<String, Value>")?;
+//! # Ok(())
+//! # }
+//! #
+//! # run_parser().unwrap();
+//! ```
+//!
+//! The [`parse_quote!`] macro also uses this approach.
+//!
+//! [`parse_quote!`]: crate::parse_quote!
+//!
+//! # The `Parser` trait
+//!
+//! Some types can be parsed in several ways depending on context. For example
+//! an [`Attribute`] can be either "outer" like `#[...]` or "inner" like
+//! `#![...]` and parsing the wrong one would be a bug. Similarly [`Punctuated`]
+//! may or may not allow trailing punctuation, and parsing it the wrong way
+//! would either reject valid input or accept invalid input.
+//!
+//! [`Attribute`]: crate::Attribute
+//! [`Punctuated`]: crate::punctuated
+//!
+//! The `Parse` trait is not implemented in these cases because there is no good
+//! behavior to consider the default.
+//!
+//! ```compile_fail
+//! # extern crate proc_macro;
+//! #
+//! # use syn::punctuated::Punctuated;
+//! # use syn::{PathSegment, Result, Token};
+//! #
+//! # fn f(tokens: proc_macro::TokenStream) -> Result<()> {
+//! #
+//! // Can't parse `Punctuated` without knowing whether trailing punctuation
+//! // should be allowed in this context.
+//! let path: Punctuated<PathSegment, Token![::]> = syn::parse(tokens)?;
+//! #
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! In these cases the types provide a choice of parser functions rather than a
+//! single `Parse` implementation, and those parser functions can be invoked
+//! through the [`Parser`] trait.
+//!
+//!
+//! ```
+//! # extern crate proc_macro;
+//! #
+//! use proc_macro::TokenStream;
+//! use syn::parse::Parser;
+//! use syn::punctuated::Punctuated;
+//! use syn::{Attribute, Expr, PathSegment, Result, Token};
+//!
+//! fn call_some_parser_methods(input: TokenStream) -> Result<()> {
+//! // Parse a nonempty sequence of path segments separated by `::` punctuation
+//! // with no trailing punctuation.
+//! let tokens = input.clone();
+//! let parser = Punctuated::<PathSegment, Token![::]>::parse_separated_nonempty;
+//! let _path = parser.parse(tokens)?;
+//!
+//! // Parse a possibly empty sequence of expressions terminated by commas with
+//! // an optional trailing punctuation.
+//! let tokens = input.clone();
+//! let parser = Punctuated::<Expr, Token![,]>::parse_terminated;
+//! let _args = parser.parse(tokens)?;
+//!
+//! // Parse zero or more outer attributes but not inner attributes.
+//! let tokens = input.clone();
+//! let parser = Attribute::parse_outer;
+//! let _attrs = parser.parse(tokens)?;
+//!
+//! Ok(())
+//! }
+//! ```
+
+#[path = "discouraged.rs"]
+pub mod discouraged;
+
+use crate::buffer::{Cursor, TokenBuffer};
+use crate::error;
+use crate::lookahead;
+use crate::punctuated::Punctuated;
+use crate::token::Token;
+use proc_macro2::{Delimiter, Group, Literal, Punct, Span, TokenStream, TokenTree};
+#[cfg(feature = "printing")]
+use quote::ToTokens;
+use std::cell::Cell;
+use std::fmt::{self, Debug, Display};
+#[cfg(feature = "extra-traits")]
+use std::hash::{Hash, Hasher};
+use std::marker::PhantomData;
+use std::mem;
+use std::ops::Deref;
+use std::panic::{RefUnwindSafe, UnwindSafe};
+use std::rc::Rc;
+use std::str::FromStr;
+
+pub use crate::error::{Error, Result};
+pub use crate::lookahead::{Lookahead1, Peek};
+
+/// Parsing interface implemented by all types that can be parsed in a default
+/// way from a token stream.
+///
+/// Refer to the [module documentation] for details about implementing and using
+/// the `Parse` trait.
+///
+/// [module documentation]: self
+pub trait Parse: Sized {
+ fn parse(input: ParseStream) -> Result<Self>;
+}
+
+/// Input to a Syn parser function.
+///
+/// See the methods of this type under the documentation of [`ParseBuffer`]. For
+/// an overview of parsing in Syn, refer to the [module documentation].
+///
+/// [module documentation]: self
+pub type ParseStream<'a> = &'a ParseBuffer<'a>;
+
+/// Cursor position within a buffered token stream.
+///
+/// This type is more commonly used through the type alias [`ParseStream`] which
+/// is an alias for `&ParseBuffer`.
+///
+/// `ParseStream` is the input type for all parser functions in Syn. They have
+/// the signature `fn(ParseStream) -> Result<T>`.
+///
+/// ## Calling a parser function
+///
+/// There is no public way to construct a `ParseBuffer`. Instead, if you are
+/// looking to invoke a parser function that requires `ParseStream` as input,
+/// you will need to go through one of the public parsing entry points.
+///
+/// - The [`parse_macro_input!`] macro if parsing input of a procedural macro;
+/// - One of [the `syn::parse*` functions][syn-parse]; or
+/// - A method of the [`Parser`] trait.
+///
+/// [`parse_macro_input!`]: crate::parse_macro_input!
+/// [syn-parse]: self#the-synparse-functions
+pub struct ParseBuffer<'a> {
+ scope: Span,
+ // Instead of Cell<Cursor<'a>> so that ParseBuffer<'a> is covariant in 'a.
+ // The rest of the code in this module needs to be careful that only a
+ // cursor derived from this `cell` is ever assigned to this `cell`.
+ //
+ // Cell<Cursor<'a>> cannot be covariant in 'a because then we could take a
+ // ParseBuffer<'a>, upcast to ParseBuffer<'short> for some lifetime shorter
+ // than 'a, and then assign a Cursor<'short> into the Cell.
+ //
+ // By extension, it would not be safe to expose an API that accepts a
+ // Cursor<'a> and trusts that it lives as long as the cursor currently in
+ // the cell.
+ cell: Cell<Cursor<'static>>,
+ marker: PhantomData<Cursor<'a>>,
+ unexpected: Cell<Option<Rc<Cell<Unexpected>>>>,
+}
+
+impl<'a> Drop for ParseBuffer<'a> {
+ fn drop(&mut self) {
+ if let Some(unexpected_span) = span_of_unexpected_ignoring_nones(self.cursor()) {
+ let (inner, old_span) = inner_unexpected(self);
+ if old_span.is_none() {
+ inner.set(Unexpected::Some(unexpected_span));
+ }
+ }
+ }
+}
+
+impl<'a> Display for ParseBuffer<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.cursor().token_stream(), f)
+ }
+}
+
+impl<'a> Debug for ParseBuffer<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.cursor().token_stream(), f)
+ }
+}
+
+impl<'a> UnwindSafe for ParseBuffer<'a> {}
+impl<'a> RefUnwindSafe for ParseBuffer<'a> {}
+
+/// Cursor state associated with speculative parsing.
+///
+/// This type is the input of the closure provided to [`ParseStream::step`].
+///
+/// [`ParseStream::step`]: ParseBuffer::step
+///
+/// # Example
+///
+/// ```
+/// use proc_macro2::TokenTree;
+/// use syn::Result;
+/// use syn::parse::ParseStream;
+///
+/// // This function advances the stream past the next occurrence of `@`. If
+/// // no `@` is present in the stream, the stream position is unchanged and
+/// // an error is returned.
+/// fn skip_past_next_at(input: ParseStream) -> Result<()> {
+/// input.step(|cursor| {
+/// let mut rest = *cursor;
+/// while let Some((tt, next)) = rest.token_tree() {
+/// match &tt {
+/// TokenTree::Punct(punct) if punct.as_char() == '@' => {
+/// return Ok(((), next));
+/// }
+/// _ => rest = next,
+/// }
+/// }
+/// Err(cursor.error("no `@` was found after this point"))
+/// })
+/// }
+/// #
+/// # fn remainder_after_skipping_past_next_at(
+/// # input: ParseStream,
+/// # ) -> Result<proc_macro2::TokenStream> {
+/// # skip_past_next_at(input)?;
+/// # input.parse()
+/// # }
+/// #
+/// # use syn::parse::Parser;
+/// # let remainder = remainder_after_skipping_past_next_at
+/// # .parse_str("a @ b c")
+/// # .unwrap();
+/// # assert_eq!(remainder.to_string(), "b c");
+/// ```
+pub struct StepCursor<'c, 'a> {
+ scope: Span,
+ // This field is covariant in 'c.
+ cursor: Cursor<'c>,
+ // This field is contravariant in 'c. Together these make StepCursor
+ // invariant in 'c. Also covariant in 'a. The user cannot cast 'c to a
+ // different lifetime but can upcast into a StepCursor with a shorter
+ // lifetime 'a.
+ //
+ // As long as we only ever construct a StepCursor for which 'c outlives 'a,
+ // this means if ever a StepCursor<'c, 'a> exists we are guaranteed that 'c
+ // outlives 'a.
+ marker: PhantomData<fn(Cursor<'c>) -> Cursor<'a>>,
+}
+
+impl<'c, 'a> Deref for StepCursor<'c, 'a> {
+ type Target = Cursor<'c>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.cursor
+ }
+}
+
+impl<'c, 'a> Copy for StepCursor<'c, 'a> {}
+
+impl<'c, 'a> Clone for StepCursor<'c, 'a> {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl<'c, 'a> StepCursor<'c, 'a> {
+ /// Triggers an error at the current position of the parse stream.
+ ///
+ /// The `ParseStream::step` invocation will return this same error without
+ /// advancing the stream state.
+ pub fn error<T: Display>(self, message: T) -> Error {
+ error::new_at(self.scope, self.cursor, message)
+ }
+}
+
+pub(crate) fn advance_step_cursor<'c, 'a>(proof: StepCursor<'c, 'a>, to: Cursor<'c>) -> Cursor<'a> {
+ // Refer to the comments within the StepCursor definition. We use the
+ // fact that a StepCursor<'c, 'a> exists as proof that 'c outlives 'a.
+ // Cursor is covariant in its lifetime parameter so we can cast a
+ // Cursor<'c> to one with the shorter lifetime Cursor<'a>.
+ let _ = proof;
+ unsafe { mem::transmute::<Cursor<'c>, Cursor<'a>>(to) }
+}
+
+pub(crate) fn new_parse_buffer(
+ scope: Span,
+ cursor: Cursor,
+ unexpected: Rc<Cell<Unexpected>>,
+) -> ParseBuffer {
+ ParseBuffer {
+ scope,
+ // See comment on `cell` in the struct definition.
+ cell: Cell::new(unsafe { mem::transmute::<Cursor, Cursor<'static>>(cursor) }),
+ marker: PhantomData,
+ unexpected: Cell::new(Some(unexpected)),
+ }
+}
+
+pub(crate) enum Unexpected {
+ None,
+ Some(Span),
+ Chain(Rc<Cell<Unexpected>>),
+}
+
+impl Default for Unexpected {
+ fn default() -> Self {
+ Unexpected::None
+ }
+}
+
+impl Clone for Unexpected {
+ fn clone(&self) -> Self {
+ match self {
+ Unexpected::None => Unexpected::None,
+ Unexpected::Some(span) => Unexpected::Some(*span),
+ Unexpected::Chain(next) => Unexpected::Chain(next.clone()),
+ }
+ }
+}
+
+// We call this on Cell<Unexpected> and Cell<Option<T>> where temporarily
+// swapping in a None is cheap.
+fn cell_clone<T: Default + Clone>(cell: &Cell<T>) -> T {
+ let prev = cell.take();
+ let ret = prev.clone();
+ cell.set(prev);
+ ret
+}
+
+fn inner_unexpected(buffer: &ParseBuffer) -> (Rc<Cell<Unexpected>>, Option<Span>) {
+ let mut unexpected = get_unexpected(buffer);
+ loop {
+ match cell_clone(&unexpected) {
+ Unexpected::None => return (unexpected, None),
+ Unexpected::Some(span) => return (unexpected, Some(span)),
+ Unexpected::Chain(next) => unexpected = next,
+ }
+ }
+}
+
+pub(crate) fn get_unexpected(buffer: &ParseBuffer) -> Rc<Cell<Unexpected>> {
+ cell_clone(&buffer.unexpected).unwrap()
+}
+
+fn span_of_unexpected_ignoring_nones(mut cursor: Cursor) -> Option<Span> {
+ if cursor.eof() {
+ return None;
+ }
+ while let Some((inner, _span, rest)) = cursor.group(Delimiter::None) {
+ if let Some(unexpected) = span_of_unexpected_ignoring_nones(inner) {
+ return Some(unexpected);
+ }
+ cursor = rest;
+ }
+ if cursor.eof() {
+ None
+ } else {
+ Some(cursor.span())
+ }
+}
+
+impl<'a> ParseBuffer<'a> {
+ /// Parses a syntax tree node of type `T`, advancing the position of our
+ /// parse stream past it.
+ pub fn parse<T: Parse>(&self) -> Result<T> {
+ T::parse(self)
+ }
+
+ /// Calls the given parser function to parse a syntax tree node of type `T`
+ /// from this stream.
+ ///
+ /// # Example
+ ///
+ /// The parser below invokes [`Attribute::parse_outer`] to parse a vector of
+ /// zero or more outer attributes.
+ ///
+ /// [`Attribute::parse_outer`]: crate::Attribute::parse_outer
+ ///
+ /// ```
+ /// 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<Attribute>,
+ /// struct_token: Token![struct],
+ /// name: Ident,
+ /// semi_token: Token![;],
+ /// }
+ ///
+ /// impl Parse for UnitStruct {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// Ok(UnitStruct {
+ /// attrs: input.call(Attribute::parse_outer)?,
+ /// struct_token: input.parse()?,
+ /// name: input.parse()?,
+ /// semi_token: input.parse()?,
+ /// })
+ /// }
+ /// }
+ /// ```
+ pub fn call<T>(&self, function: fn(ParseStream) -> Result<T>) -> Result<T> {
+ function(self)
+ }
+
+ /// Looks at the next token in the parse stream to determine whether it
+ /// matches the requested type of token.
+ ///
+ /// Does not advance the position of the parse stream.
+ ///
+ /// # Syntax
+ ///
+ /// Note that this method does not use turbofish syntax. Pass the peek type
+ /// inside of parentheses.
+ ///
+ /// - `input.peek(Token![struct])`
+ /// - `input.peek(Token![==])`
+ /// - `input.peek(syn::Ident)` *(does not accept keywords)*
+ /// - `input.peek(syn::Ident::peek_any)`
+ /// - `input.peek(Lifetime)`
+ /// - `input.peek(token::Brace)`
+ ///
+ /// # Example
+ ///
+ /// In this example we finish parsing the list of supertraits when the next
+ /// token in the input is either `where` or an opening curly brace.
+ ///
+ /// ```
+ /// use syn::{braced, token, Generics, Ident, Result, Token, TypeParamBound};
+ /// use syn::parse::{Parse, ParseStream};
+ /// use syn::punctuated::Punctuated;
+ ///
+ /// // Parses a trait definition containing no associated items.
+ /// //
+ /// // trait Marker<'de, T>: A + B<'de> where Box<T>: Clone {}
+ /// struct MarkerTrait {
+ /// trait_token: Token![trait],
+ /// ident: Ident,
+ /// generics: Generics,
+ /// colon_token: Option<Token![:]>,
+ /// supertraits: Punctuated<TypeParamBound, Token![+]>,
+ /// brace_token: token::Brace,
+ /// }
+ ///
+ /// impl Parse for MarkerTrait {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let trait_token: Token![trait] = input.parse()?;
+ /// let ident: Ident = input.parse()?;
+ /// let mut generics: Generics = input.parse()?;
+ /// let colon_token: Option<Token![:]> = input.parse()?;
+ ///
+ /// let mut supertraits = Punctuated::new();
+ /// if colon_token.is_some() {
+ /// loop {
+ /// supertraits.push_value(input.parse()?);
+ /// if input.peek(Token![where]) || input.peek(token::Brace) {
+ /// break;
+ /// }
+ /// supertraits.push_punct(input.parse()?);
+ /// }
+ /// }
+ ///
+ /// generics.where_clause = input.parse()?;
+ /// let content;
+ /// let empty_brace_token = braced!(content in input);
+ ///
+ /// Ok(MarkerTrait {
+ /// trait_token,
+ /// ident,
+ /// generics,
+ /// colon_token,
+ /// supertraits,
+ /// brace_token: empty_brace_token,
+ /// })
+ /// }
+ /// }
+ /// ```
+ pub fn peek<T: Peek>(&self, token: T) -> bool {
+ let _ = token;
+ T::Token::peek(self.cursor())
+ }
+
+ /// Looks at the second-next token in the parse stream.
+ ///
+ /// This is commonly useful as a way to implement contextual keywords.
+ ///
+ /// # Example
+ ///
+ /// This example needs to use `peek2` because the symbol `union` is not a
+ /// keyword in Rust. We can't use just `peek` and decide to parse a union if
+ /// the very next token is `union`, because someone is free to write a `mod
+ /// union` and a macro invocation that looks like `union::some_macro! { ...
+ /// }`. In other words `union` is a contextual keyword.
+ ///
+ /// ```
+ /// use syn::{Ident, ItemUnion, Macro, Result, Token};
+ /// use syn::parse::{Parse, ParseStream};
+ ///
+ /// // Parses either a union or a macro invocation.
+ /// enum UnionOrMacro {
+ /// // union MaybeUninit<T> { uninit: (), value: T }
+ /// Union(ItemUnion),
+ /// // lazy_static! { ... }
+ /// Macro(Macro),
+ /// }
+ ///
+ /// impl Parse for UnionOrMacro {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// if input.peek(Token![union]) && input.peek2(Ident) {
+ /// input.parse().map(UnionOrMacro::Union)
+ /// } else {
+ /// input.parse().map(UnionOrMacro::Macro)
+ /// }
+ /// }
+ /// }
+ /// ```
+ pub fn peek2<T: Peek>(&self, token: T) -> bool {
+ fn peek2(buffer: &ParseBuffer, peek: fn(Cursor) -> bool) -> bool {
+ buffer.cursor().skip().map_or(false, peek)
+ }
+
+ let _ = token;
+ peek2(self, T::Token::peek)
+ }
+
+ /// Looks at the third-next token in the parse stream.
+ pub fn peek3<T: Peek>(&self, token: T) -> bool {
+ fn peek3(buffer: &ParseBuffer, peek: fn(Cursor) -> bool) -> bool {
+ buffer
+ .cursor()
+ .skip()
+ .and_then(Cursor::skip)
+ .map_or(false, peek)
+ }
+
+ let _ = token;
+ peek3(self, T::Token::peek)
+ }
+
+ /// Parses zero or more occurrences of `T` separated by punctuation of type
+ /// `P`, with optional trailing punctuation.
+ ///
+ /// Parsing continues until the end of this parse stream. The entire content
+ /// of this parse stream must consist of `T` and `P`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use quote::quote;
+ /// #
+ /// use syn::{parenthesized, token, Ident, Result, Token, Type};
+ /// use syn::parse::{Parse, ParseStream};
+ /// use syn::punctuated::Punctuated;
+ ///
+ /// // Parse a simplified tuple struct syntax like:
+ /// //
+ /// // struct S(A, B);
+ /// struct TupleStruct {
+ /// struct_token: Token![struct],
+ /// ident: Ident,
+ /// paren_token: token::Paren,
+ /// fields: Punctuated<Type, Token![,]>,
+ /// semi_token: Token![;],
+ /// }
+ ///
+ /// impl Parse for TupleStruct {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let content;
+ /// Ok(TupleStruct {
+ /// struct_token: input.parse()?,
+ /// ident: input.parse()?,
+ /// paren_token: parenthesized!(content in input),
+ /// fields: content.parse_terminated(Type::parse, Token![,])?,
+ /// semi_token: input.parse()?,
+ /// })
+ /// }
+ /// }
+ /// #
+ /// # let input = quote! {
+ /// # struct S(A, B);
+ /// # };
+ /// # syn::parse2::<TupleStruct>(input).unwrap();
+ /// ```
+ ///
+ /// # See also
+ ///
+ /// If your separator is anything more complicated than an invocation of the
+ /// `Token!` macro, this method won't be applicable and you can instead
+ /// directly use `Punctuated`'s parser functions: [`parse_terminated`],
+ /// [`parse_separated_nonempty`] etc.
+ ///
+ /// [`parse_terminated`]: Punctuated::parse_terminated
+ /// [`parse_separated_nonempty`]: Punctuated::parse_separated_nonempty
+ ///
+ /// ```
+ /// use syn::{custom_keyword, Expr, Result, Token};
+ /// use syn::parse::{Parse, ParseStream};
+ /// use syn::punctuated::Punctuated;
+ ///
+ /// mod kw {
+ /// syn::custom_keyword!(fin);
+ /// }
+ ///
+ /// struct Fin(kw::fin, Token![;]);
+ ///
+ /// impl Parse for Fin {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// Ok(Self(input.parse()?, input.parse()?))
+ /// }
+ /// }
+ ///
+ /// struct Thing {
+ /// steps: Punctuated<Expr, Fin>,
+ /// }
+ ///
+ /// impl Parse for Thing {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// # if true {
+ /// Ok(Thing {
+ /// steps: Punctuated::parse_terminated(input)?,
+ /// })
+ /// # } else {
+ /// // or equivalently, this means the same thing:
+ /// # Ok(Thing {
+ /// steps: input.call(Punctuated::parse_terminated)?,
+ /// # })
+ /// # }
+ /// }
+ /// }
+ /// ```
+ pub fn parse_terminated<T, P>(
+ &self,
+ parser: fn(ParseStream) -> Result<T>,
+ separator: P,
+ ) -> Result<Punctuated<T, P::Token>>
+ where
+ P: Peek,
+ P::Token: Parse,
+ {
+ let _ = separator;
+ Punctuated::parse_terminated_with(self, parser)
+ }
+
+ /// Returns whether there are tokens remaining in this stream.
+ ///
+ /// This method returns true at the end of the content of a set of
+ /// delimiters, as well as at the very end of the complete macro input.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use syn::{braced, token, Ident, Item, Result, Token};
+ /// use syn::parse::{Parse, ParseStream};
+ ///
+ /// // Parses a Rust `mod m { ... }` containing zero or more items.
+ /// struct Mod {
+ /// mod_token: Token![mod],
+ /// name: Ident,
+ /// brace_token: token::Brace,
+ /// items: Vec<Item>,
+ /// }
+ ///
+ /// impl Parse for Mod {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let content;
+ /// Ok(Mod {
+ /// mod_token: input.parse()?,
+ /// name: input.parse()?,
+ /// brace_token: braced!(content in input),
+ /// items: {
+ /// let mut items = Vec::new();
+ /// while !content.is_empty() {
+ /// items.push(content.parse()?);
+ /// }
+ /// items
+ /// },
+ /// })
+ /// }
+ /// }
+ /// ```
+ pub fn is_empty(&self) -> bool {
+ self.cursor().eof()
+ }
+
+ /// Constructs a helper for peeking at the next token in this stream and
+ /// building an error message if it is not one of a set of expected tokens.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use syn::{ConstParam, Ident, Lifetime, LifetimeParam, Result, Token, TypeParam};
+ /// use syn::parse::{Parse, ParseStream};
+ ///
+ /// // A generic parameter, a single one of the comma-separated elements inside
+ /// // angle brackets in:
+ /// //
+ /// // fn f<T: Clone, 'a, 'b: 'a, const N: usize>() { ... }
+ /// //
+ /// // On invalid input, lookahead gives us a reasonable error message.
+ /// //
+ /// // error: expected one of: identifier, lifetime, `const`
+ /// // |
+ /// // 5 | fn f<!Sized>() {}
+ /// // | ^
+ /// enum GenericParam {
+ /// Type(TypeParam),
+ /// Lifetime(LifetimeParam),
+ /// Const(ConstParam),
+ /// }
+ ///
+ /// impl Parse for GenericParam {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let lookahead = input.lookahead1();
+ /// if lookahead.peek(Ident) {
+ /// input.parse().map(GenericParam::Type)
+ /// } else if lookahead.peek(Lifetime) {
+ /// input.parse().map(GenericParam::Lifetime)
+ /// } else if lookahead.peek(Token![const]) {
+ /// input.parse().map(GenericParam::Const)
+ /// } else {
+ /// Err(lookahead.error())
+ /// }
+ /// }
+ /// }
+ /// ```
+ pub fn lookahead1(&self) -> Lookahead1<'a> {
+ lookahead::new(self.scope, self.cursor())
+ }
+
+ /// Forks a parse stream so that parsing tokens out of either the original
+ /// or the fork does not advance the position of the other.
+ ///
+ /// # Performance
+ ///
+ /// Forking a parse stream is a cheap fixed amount of work and does not
+ /// involve copying token buffers. Where you might hit performance problems
+ /// is if your macro ends up parsing a large amount of content more than
+ /// once.
+ ///
+ /// ```
+ /// # use syn::{Expr, Result};
+ /// # use syn::parse::ParseStream;
+ /// #
+ /// # fn bad(input: ParseStream) -> Result<Expr> {
+ /// // Do not do this.
+ /// if input.fork().parse::<Expr>().is_ok() {
+ /// return input.parse::<Expr>();
+ /// }
+ /// # unimplemented!()
+ /// # }
+ /// ```
+ ///
+ /// As a rule, avoid parsing an unbounded amount of tokens out of a forked
+ /// parse stream. Only use a fork when the amount of work performed against
+ /// the fork is small and bounded.
+ ///
+ /// When complex speculative parsing against the forked stream is
+ /// unavoidable, use [`parse::discouraged::Speculative`] to advance the
+ /// original stream once the fork's parse is determined to have been
+ /// successful.
+ ///
+ /// For a lower level way to perform speculative parsing at the token level,
+ /// consider using [`ParseStream::step`] instead.
+ ///
+ /// [`parse::discouraged::Speculative`]: discouraged::Speculative
+ /// [`ParseStream::step`]: ParseBuffer::step
+ ///
+ /// # Example
+ ///
+ /// The parse implementation shown here parses possibly restricted `pub`
+ /// visibilities.
+ ///
+ /// - `pub`
+ /// - `pub(crate)`
+ /// - `pub(self)`
+ /// - `pub(super)`
+ /// - `pub(in some::path)`
+ ///
+ /// To handle the case of visibilities inside of tuple structs, the parser
+ /// needs to distinguish parentheses that specify visibility restrictions
+ /// from parentheses that form part of a tuple type.
+ ///
+ /// ```
+ /// # struct A;
+ /// # struct B;
+ /// # struct C;
+ /// #
+ /// struct S(pub(crate) A, pub (B, C));
+ /// ```
+ ///
+ /// In this example input the first tuple struct element of `S` has
+ /// `pub(crate)` visibility while the second tuple struct element has `pub`
+ /// visibility; the parentheses around `(B, C)` are part of the type rather
+ /// than part of a visibility restriction.
+ ///
+ /// The parser uses a forked parse stream to check the first token inside of
+ /// parentheses after the `pub` keyword. This is a small bounded amount of
+ /// work performed against the forked parse stream.
+ ///
+ /// ```
+ /// use syn::{parenthesized, token, Ident, Path, Result, Token};
+ /// use syn::ext::IdentExt;
+ /// use syn::parse::{Parse, ParseStream};
+ ///
+ /// struct PubVisibility {
+ /// pub_token: Token![pub],
+ /// restricted: Option<Restricted>,
+ /// }
+ ///
+ /// struct Restricted {
+ /// paren_token: token::Paren,
+ /// in_token: Option<Token![in]>,
+ /// path: Path,
+ /// }
+ ///
+ /// impl Parse for PubVisibility {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let pub_token: Token![pub] = input.parse()?;
+ ///
+ /// if input.peek(token::Paren) {
+ /// let ahead = input.fork();
+ /// let mut content;
+ /// parenthesized!(content in ahead);
+ ///
+ /// if content.peek(Token![crate])
+ /// || content.peek(Token![self])
+ /// || content.peek(Token![super])
+ /// {
+ /// return Ok(PubVisibility {
+ /// pub_token,
+ /// restricted: Some(Restricted {
+ /// paren_token: parenthesized!(content in input),
+ /// in_token: None,
+ /// path: Path::from(content.call(Ident::parse_any)?),
+ /// }),
+ /// });
+ /// } else if content.peek(Token![in]) {
+ /// return Ok(PubVisibility {
+ /// pub_token,
+ /// restricted: Some(Restricted {
+ /// paren_token: parenthesized!(content in input),
+ /// in_token: Some(content.parse()?),
+ /// path: content.call(Path::parse_mod_style)?,
+ /// }),
+ /// });
+ /// }
+ /// }
+ ///
+ /// Ok(PubVisibility {
+ /// pub_token,
+ /// restricted: None,
+ /// })
+ /// }
+ /// }
+ /// ```
+ pub fn fork(&self) -> Self {
+ ParseBuffer {
+ scope: self.scope,
+ cell: self.cell.clone(),
+ marker: PhantomData,
+ // Not the parent's unexpected. Nothing cares whether the clone
+ // parses all the way unless we `advance_to`.
+ unexpected: Cell::new(Some(Rc::new(Cell::new(Unexpected::None)))),
+ }
+ }
+
+ /// Triggers an error at the current position of the parse stream.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use syn::{Expr, Result, Token};
+ /// use syn::parse::{Parse, ParseStream};
+ ///
+ /// // Some kind of loop: `while` or `for` or `loop`.
+ /// struct Loop {
+ /// expr: Expr,
+ /// }
+ ///
+ /// impl Parse for Loop {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// if input.peek(Token![while])
+ /// || input.peek(Token![for])
+ /// || input.peek(Token![loop])
+ /// {
+ /// Ok(Loop {
+ /// expr: input.parse()?,
+ /// })
+ /// } else {
+ /// Err(input.error("expected some kind of loop"))
+ /// }
+ /// }
+ /// }
+ /// ```
+ pub fn error<T: Display>(&self, message: T) -> Error {
+ error::new_at(self.scope, self.cursor(), message)
+ }
+
+ /// Speculatively parses tokens from this parse stream, advancing the
+ /// position of this stream only if parsing succeeds.
+ ///
+ /// This is a powerful low-level API used for defining the `Parse` impls of
+ /// the basic built-in token types. It is not something that will be used
+ /// widely outside of the Syn codebase.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use proc_macro2::TokenTree;
+ /// use syn::Result;
+ /// use syn::parse::ParseStream;
+ ///
+ /// // This function advances the stream past the next occurrence of `@`. If
+ /// // no `@` is present in the stream, the stream position is unchanged and
+ /// // an error is returned.
+ /// fn skip_past_next_at(input: ParseStream) -> Result<()> {
+ /// input.step(|cursor| {
+ /// let mut rest = *cursor;
+ /// while let Some((tt, next)) = rest.token_tree() {
+ /// match &tt {
+ /// TokenTree::Punct(punct) if punct.as_char() == '@' => {
+ /// return Ok(((), next));
+ /// }
+ /// _ => rest = next,
+ /// }
+ /// }
+ /// Err(cursor.error("no `@` was found after this point"))
+ /// })
+ /// }
+ /// #
+ /// # fn remainder_after_skipping_past_next_at(
+ /// # input: ParseStream,
+ /// # ) -> Result<proc_macro2::TokenStream> {
+ /// # skip_past_next_at(input)?;
+ /// # input.parse()
+ /// # }
+ /// #
+ /// # use syn::parse::Parser;
+ /// # let remainder = remainder_after_skipping_past_next_at
+ /// # .parse_str("a @ b c")
+ /// # .unwrap();
+ /// # assert_eq!(remainder.to_string(), "b c");
+ /// ```
+ pub fn step<F, R>(&self, function: F) -> Result<R>
+ where
+ F: for<'c> FnOnce(StepCursor<'c, 'a>) -> Result<(R, Cursor<'c>)>,
+ {
+ // Since the user's function is required to work for any 'c, we know
+ // that the Cursor<'c> they return is either derived from the input
+ // StepCursor<'c, 'a> or from a Cursor<'static>.
+ //
+ // It would not be legal to write this function without the invariant
+ // lifetime 'c in StepCursor<'c, 'a>. If this function were written only
+ // in terms of 'a, the user could take our ParseBuffer<'a>, upcast it to
+ // a ParseBuffer<'short> which some shorter lifetime than 'a, invoke
+ // `step` on their ParseBuffer<'short> with a closure that returns
+ // Cursor<'short>, and we would wrongly write that Cursor<'short> into
+ // the Cell intended to hold Cursor<'a>.
+ //
+ // In some cases it may be necessary for R to contain a Cursor<'a>.
+ // Within Syn we solve this using `advance_step_cursor` which uses the
+ // existence of a StepCursor<'c, 'a> as proof that it is safe to cast
+ // from Cursor<'c> to Cursor<'a>. If needed outside of Syn, it would be
+ // safe to expose that API as a method on StepCursor.
+ let (node, rest) = function(StepCursor {
+ scope: self.scope,
+ cursor: self.cell.get(),
+ marker: PhantomData,
+ })?;
+ self.cell.set(rest);
+ Ok(node)
+ }
+
+ /// Returns the `Span` of the next token in the parse stream, or
+ /// `Span::call_site()` if this parse stream has completely exhausted its
+ /// input `TokenStream`.
+ pub fn span(&self) -> Span {
+ let cursor = self.cursor();
+ if cursor.eof() {
+ self.scope
+ } else {
+ crate::buffer::open_span_of_group(cursor)
+ }
+ }
+
+ /// Provides low-level access to the token representation underlying this
+ /// parse stream.
+ ///
+ /// Cursors are immutable so no operations you perform against the cursor
+ /// will affect the state of this parse stream.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use proc_macro2::TokenStream;
+ /// use syn::buffer::Cursor;
+ /// use syn::parse::{ParseStream, Result};
+ ///
+ /// // Run a parser that returns T, but get its output as TokenStream instead of T.
+ /// // This works without T needing to implement ToTokens.
+ /// fn recognize_token_stream<T>(
+ /// recognizer: fn(ParseStream) -> Result<T>,
+ /// ) -> impl Fn(ParseStream) -> Result<TokenStream> {
+ /// move |input| {
+ /// let begin = input.cursor();
+ /// recognizer(input)?;
+ /// let end = input.cursor();
+ /// Ok(tokens_between(begin, end))
+ /// }
+ /// }
+ ///
+ /// // Collect tokens between two cursors as a TokenStream.
+ /// fn tokens_between(begin: Cursor, end: Cursor) -> TokenStream {
+ /// assert!(begin <= end);
+ ///
+ /// let mut cursor = begin;
+ /// let mut tokens = TokenStream::new();
+ /// while cursor < end {
+ /// let (token, next) = cursor.token_tree().unwrap();
+ /// tokens.extend(std::iter::once(token));
+ /// cursor = next;
+ /// }
+ /// tokens
+ /// }
+ ///
+ /// fn main() {
+ /// use quote::quote;
+ /// use syn::parse::{Parse, Parser};
+ /// use syn::Token;
+ ///
+ /// // Parse syn::Type as a TokenStream, surrounded by angle brackets.
+ /// fn example(input: ParseStream) -> Result<TokenStream> {
+ /// let _langle: Token![<] = input.parse()?;
+ /// let ty = recognize_token_stream(syn::Type::parse)(input)?;
+ /// let _rangle: Token![>] = input.parse()?;
+ /// Ok(ty)
+ /// }
+ ///
+ /// let tokens = quote! { <fn() -> u8> };
+ /// println!("{}", example.parse2(tokens).unwrap());
+ /// }
+ /// ```
+ pub fn cursor(&self) -> Cursor<'a> {
+ self.cell.get()
+ }
+
+ fn check_unexpected(&self) -> Result<()> {
+ match inner_unexpected(self).1 {
+ Some(span) => Err(Error::new(span, "unexpected token")),
+ None => Ok(()),
+ }
+ }
+}
+
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+impl<T: Parse> Parse for Box<T> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.parse().map(Box::new)
+ }
+}
+
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+impl<T: Parse + Token> Parse for Option<T> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if T::peek(input.cursor()) {
+ Ok(Some(input.parse()?))
+ } else {
+ Ok(None)
+ }
+ }
+}
+
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+impl Parse for TokenStream {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| Ok((cursor.token_stream(), Cursor::empty())))
+ }
+}
+
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+impl Parse for TokenTree {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| match cursor.token_tree() {
+ Some((tt, rest)) => Ok((tt, rest)),
+ None => Err(cursor.error("expected token tree")),
+ })
+ }
+}
+
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+impl Parse for Group {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| {
+ if let Some((group, rest)) = cursor.any_group_token() {
+ if group.delimiter() != Delimiter::None {
+ return Ok((group, rest));
+ }
+ }
+ Err(cursor.error("expected group token"))
+ })
+ }
+}
+
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+impl Parse for Punct {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| match cursor.punct() {
+ Some((punct, rest)) => Ok((punct, rest)),
+ None => Err(cursor.error("expected punctuation token")),
+ })
+ }
+}
+
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+impl Parse for Literal {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| match cursor.literal() {
+ Some((literal, rest)) => Ok((literal, rest)),
+ None => Err(cursor.error("expected literal token")),
+ })
+ }
+}
+
+/// Parser that can parse Rust tokens into a particular syntax tree node.
+///
+/// Refer to the [module documentation] for details about parsing in Syn.
+///
+/// [module documentation]: self
+pub trait Parser: Sized {
+ type Output;
+
+ /// Parse a proc-macro2 token stream into the chosen syntax tree node.
+ ///
+ /// This function will check that the input is fully parsed. If there are
+ /// any unparsed tokens at the end of the stream, an error is returned.
+ fn parse2(self, tokens: TokenStream) -> Result<Self::Output>;
+
+ /// Parse tokens of source code into the chosen syntax tree node.
+ ///
+ /// This function will check that the input is fully parsed. If there are
+ /// any unparsed tokens at the end of the stream, an error is returned.
+ #[cfg(feature = "proc-macro")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "proc-macro")))]
+ fn parse(self, tokens: proc_macro::TokenStream) -> Result<Self::Output> {
+ self.parse2(proc_macro2::TokenStream::from(tokens))
+ }
+
+ /// Parse a string of Rust code into the chosen syntax tree node.
+ ///
+ /// This function will check that the input is fully parsed. If there are
+ /// any unparsed tokens at the end of the string, an error is returned.
+ ///
+ /// # Hygiene
+ ///
+ /// Every span in the resulting syntax tree will be set to resolve at the
+ /// macro call site.
+ fn parse_str(self, s: &str) -> Result<Self::Output> {
+ self.parse2(proc_macro2::TokenStream::from_str(s)?)
+ }
+
+ // Not public API.
+ #[doc(hidden)]
+ fn __parse_scoped(self, scope: Span, tokens: TokenStream) -> Result<Self::Output> {
+ let _ = scope;
+ self.parse2(tokens)
+ }
+}
+
+fn tokens_to_parse_buffer(tokens: &TokenBuffer) -> ParseBuffer {
+ let scope = Span::call_site();
+ let cursor = tokens.begin();
+ let unexpected = Rc::new(Cell::new(Unexpected::None));
+ new_parse_buffer(scope, cursor, unexpected)
+}
+
+impl<F, T> Parser for F
+where
+ F: FnOnce(ParseStream) -> Result<T>,
+{
+ type Output = T;
+
+ fn parse2(self, tokens: TokenStream) -> Result<T> {
+ let buf = TokenBuffer::new2(tokens);
+ let state = tokens_to_parse_buffer(&buf);
+ let node = self(&state)?;
+ state.check_unexpected()?;
+ if let Some(unexpected_span) = span_of_unexpected_ignoring_nones(state.cursor()) {
+ Err(Error::new(unexpected_span, "unexpected token"))
+ } else {
+ Ok(node)
+ }
+ }
+
+ fn __parse_scoped(self, scope: Span, tokens: TokenStream) -> Result<Self::Output> {
+ let buf = TokenBuffer::new2(tokens);
+ let cursor = buf.begin();
+ let unexpected = Rc::new(Cell::new(Unexpected::None));
+ let state = new_parse_buffer(scope, cursor, unexpected);
+ let node = self(&state)?;
+ state.check_unexpected()?;
+ if let Some(unexpected_span) = span_of_unexpected_ignoring_nones(state.cursor()) {
+ Err(Error::new(unexpected_span, "unexpected token"))
+ } else {
+ Ok(node)
+ }
+ }
+}
+
+pub(crate) fn parse_scoped<F: Parser>(f: F, scope: Span, tokens: TokenStream) -> Result<F::Output> {
+ f.__parse_scoped(scope, tokens)
+}
+
+/// An empty syntax tree node that consumes no tokens when parsed.
+///
+/// This is useful for attribute macros that want to ensure they are not
+/// provided any attribute args.
+///
+/// ```
+/// # extern crate proc_macro;
+/// #
+/// use proc_macro::TokenStream;
+/// use syn::parse_macro_input;
+/// use syn::parse::Nothing;
+///
+/// # const IGNORE: &str = stringify! {
+/// #[proc_macro_attribute]
+/// # };
+/// pub fn my_attr(args: TokenStream, input: TokenStream) -> TokenStream {
+/// parse_macro_input!(args as Nothing);
+///
+/// /* ... */
+/// # TokenStream::new()
+/// }
+/// ```
+///
+/// ```text
+/// error: unexpected token
+/// --> src/main.rs:3:19
+/// |
+/// 3 | #[my_attr(asdf)]
+/// | ^^^^
+/// ```
+pub struct Nothing;
+
+impl Parse for Nothing {
+ fn parse(_input: ParseStream) -> Result<Self> {
+ Ok(Nothing)
+ }
+}
+
+#[cfg(feature = "printing")]
+#[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+impl ToTokens for Nothing {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let _ = tokens;
+ }
+}
+
+#[cfg(feature = "clone-impls")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for Nothing {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+#[cfg(feature = "clone-impls")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Copy for Nothing {}
+
+#[cfg(feature = "extra-traits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for Nothing {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("Nothing")
+ }
+}
+
+#[cfg(feature = "extra-traits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Eq for Nothing {}
+
+#[cfg(feature = "extra-traits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for Nothing {
+ fn eq(&self, _other: &Self) -> bool {
+ true
+ }
+}
+
+#[cfg(feature = "extra-traits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for Nothing {
+ fn hash<H: Hasher>(&self, _state: &mut H) {}
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/parse_macro_input.rs b/rust/hw/char/pl011/vendor/syn/src/parse_macro_input.rs
new file mode 100644
index 0000000000..f0660aedd7
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/parse_macro_input.rs
@@ -0,0 +1,128 @@
+/// Parse the input TokenStream of a macro, triggering a compile error if the
+/// tokens fail to parse.
+///
+/// Refer to the [`parse` module] documentation for more details about parsing
+/// in Syn.
+///
+/// [`parse` module]: mod@crate::parse
+///
+/// <br>
+///
+/// # Intended usage
+///
+/// This macro must be called from a function that returns
+/// `proc_macro::TokenStream`. Usually this will be your proc macro entry point,
+/// the function that has the #\[proc_macro\] / #\[proc_macro_derive\] /
+/// #\[proc_macro_attribute\] attribute.
+///
+/// ```
+/// # extern crate proc_macro;
+/// #
+/// use proc_macro::TokenStream;
+/// use syn::{parse_macro_input, Result};
+/// use syn::parse::{Parse, ParseStream};
+///
+/// struct MyMacroInput {
+/// /* ... */
+/// }
+///
+/// impl Parse for MyMacroInput {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// /* ... */
+/// # Ok(MyMacroInput {})
+/// }
+/// }
+///
+/// # const IGNORE: &str = stringify! {
+/// #[proc_macro]
+/// # };
+/// pub fn my_macro(tokens: TokenStream) -> TokenStream {
+/// let input = parse_macro_input!(tokens as MyMacroInput);
+///
+/// /* ... */
+/// # TokenStream::new()
+/// }
+/// ```
+///
+/// <br>
+///
+/// # Usage with Parser
+///
+/// This macro can also be used with the [`Parser` trait] for types that have
+/// multiple ways that they can be parsed.
+///
+/// [`Parser` trait]: crate::parse::Parser
+///
+/// ```
+/// # extern crate proc_macro;
+/// #
+/// # use proc_macro::TokenStream;
+/// # use syn::{parse_macro_input, Result};
+/// # use syn::parse::ParseStream;
+/// #
+/// # struct MyMacroInput {}
+/// #
+/// impl MyMacroInput {
+/// fn parse_alternate(input: ParseStream) -> Result<Self> {
+/// /* ... */
+/// # Ok(MyMacroInput {})
+/// }
+/// }
+///
+/// # const IGNORE: &str = stringify! {
+/// #[proc_macro]
+/// # };
+/// pub fn my_macro(tokens: TokenStream) -> TokenStream {
+/// let input = parse_macro_input!(tokens with MyMacroInput::parse_alternate);
+///
+/// /* ... */
+/// # TokenStream::new()
+/// }
+/// ```
+///
+/// <br>
+///
+/// # Expansion
+///
+/// `parse_macro_input!($variable as $Type)` expands to something like:
+///
+/// ```no_run
+/// # extern crate proc_macro;
+/// #
+/// # macro_rules! doc_test {
+/// # ($variable:ident as $Type:ty) => {
+/// match syn::parse::<$Type>($variable) {
+/// Ok(syntax_tree) => syntax_tree,
+/// Err(err) => return proc_macro::TokenStream::from(err.to_compile_error()),
+/// }
+/// # };
+/// # }
+/// #
+/// # fn test(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+/// # let _ = doc_test!(input as syn::Ident);
+/// # proc_macro::TokenStream::new()
+/// # }
+/// ```
+#[macro_export]
+#[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "proc-macro"))))]
+macro_rules! parse_macro_input {
+ ($tokenstream:ident as $ty:ty) => {
+ match $crate::parse::<$ty>($tokenstream) {
+ $crate::__private::Ok(data) => data,
+ $crate::__private::Err(err) => {
+ return $crate::__private::TokenStream::from(err.to_compile_error());
+ }
+ }
+ };
+ ($tokenstream:ident with $parser:path) => {
+ match $crate::parse::Parser::parse($parser, $tokenstream) {
+ $crate::__private::Ok(data) => data,
+ $crate::__private::Err(err) => {
+ return $crate::__private::TokenStream::from(err.to_compile_error());
+ }
+ }
+ };
+ ($tokenstream:ident) => {
+ $crate::parse_macro_input!($tokenstream as _)
+ };
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/parse_quote.rs b/rust/hw/char/pl011/vendor/syn/src/parse_quote.rs
new file mode 100644
index 0000000000..c4f47e16d1
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/parse_quote.rs
@@ -0,0 +1,210 @@
+/// Quasi-quotation macro that accepts input like the [`quote!`] macro but uses
+/// type inference to figure out a return type for those tokens.
+///
+/// [`quote!`]: https://docs.rs/quote/1.0/quote/index.html
+///
+/// The return type can be any syntax tree node that implements the [`Parse`]
+/// trait.
+///
+/// [`Parse`]: crate::parse::Parse
+///
+/// ```
+/// use quote::quote;
+/// use syn::{parse_quote, Stmt};
+///
+/// fn main() {
+/// let name = quote!(v);
+/// let ty = quote!(u8);
+///
+/// let stmt: Stmt = parse_quote! {
+/// let #name: #ty = Default::default();
+/// };
+///
+/// println!("{:#?}", stmt);
+/// }
+/// ```
+///
+/// *This macro is available only if Syn is built with both the `"parsing"` and
+/// `"printing"` features.*
+///
+/// # Example
+///
+/// The following helper function adds a bound `T: HeapSize` to every type
+/// parameter `T` in the input generics.
+///
+/// ```
+/// use syn::{parse_quote, Generics, GenericParam};
+///
+/// // Add a bound `T: HeapSize` to every type parameter T.
+/// fn add_trait_bounds(mut generics: Generics) -> Generics {
+/// for param in &mut generics.params {
+/// if let GenericParam::Type(type_param) = param {
+/// type_param.bounds.push(parse_quote!(HeapSize));
+/// }
+/// }
+/// generics
+/// }
+/// ```
+///
+/// # Special cases
+///
+/// This macro can parse the following additional types as a special case even
+/// though they do not implement the `Parse` trait.
+///
+/// - [`Attribute`] — parses one attribute, allowing either outer like `#[...]`
+/// or inner like `#![...]`
+/// - [`Punctuated<T, P>`] — parses zero or more `T` separated by punctuation
+/// `P` with optional trailing punctuation
+/// - [`Vec<Stmt>`] — parses the same as `Block::parse_within`
+///
+/// [`Vec<Stmt>`]: Block::parse_within
+///
+/// # Panics
+///
+/// Panics if the tokens fail to parse as the expected syntax tree type. The
+/// caller is responsible for ensuring that the input tokens are syntactically
+/// valid.
+#[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "printing"))))]
+#[macro_export]
+macro_rules! parse_quote {
+ ($($tt:tt)*) => {
+ $crate::__private::parse_quote($crate::__private::quote::quote!($($tt)*))
+ };
+}
+
+/// This macro is [`parse_quote!`] + [`quote_spanned!`][quote::quote_spanned].
+///
+/// Please refer to each of their documentation.
+///
+/// # Example
+///
+/// ```
+/// use quote::{quote, quote_spanned};
+/// use syn::spanned::Spanned;
+/// use syn::{parse_quote_spanned, ReturnType, Signature};
+///
+/// // Changes `fn()` to `fn() -> Pin<Box<dyn Future<Output = ()>>>`,
+/// // and `fn() -> T` to `fn() -> Pin<Box<dyn Future<Output = T>>>`,
+/// // without introducing any call_site() spans.
+/// fn make_ret_pinned_future(sig: &mut Signature) {
+/// let ret = match &sig.output {
+/// ReturnType::Default => quote_spanned!(sig.paren_token.span=> ()),
+/// ReturnType::Type(_, ret) => quote!(#ret),
+/// };
+/// sig.output = parse_quote_spanned! {ret.span()=>
+/// -> ::std::pin::Pin<::std::boxed::Box<dyn ::std::future::Future<Output = #ret>>>
+/// };
+/// }
+/// ```
+#[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "printing"))))]
+#[macro_export]
+macro_rules! parse_quote_spanned {
+ ($span:expr=> $($tt:tt)*) => {
+ $crate::__private::parse_quote($crate::__private::quote::quote_spanned!($span=> $($tt)*))
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Can parse any type that implements Parse.
+
+use crate::error::Result;
+use crate::parse::{Parse, ParseStream, Parser};
+use proc_macro2::TokenStream;
+
+// Not public API.
+#[doc(hidden)]
+pub fn parse<T: ParseQuote>(token_stream: TokenStream) -> T {
+ let parser = T::parse;
+ match parser.parse2(token_stream) {
+ Ok(t) => t,
+ Err(err) => panic!("{}", err),
+ }
+}
+
+#[doc(hidden)]
+pub trait ParseQuote: Sized {
+ fn parse(input: ParseStream) -> Result<Self>;
+}
+
+impl<T: Parse> ParseQuote for T {
+ fn parse(input: ParseStream) -> Result<Self> {
+ <T as Parse>::parse(input)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Any other types that we want `parse_quote!` to be able to parse.
+
+use crate::punctuated::Punctuated;
+#[cfg(any(feature = "full", feature = "derive"))]
+use crate::{attr, Attribute, Field, FieldMutability, Ident, Type, Visibility};
+#[cfg(feature = "full")]
+use crate::{Block, Pat, Stmt};
+
+#[cfg(any(feature = "full", feature = "derive"))]
+impl ParseQuote for Attribute {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![#]) && input.peek2(Token![!]) {
+ attr::parsing::single_parse_inner(input)
+ } else {
+ attr::parsing::single_parse_outer(input)
+ }
+ }
+}
+
+#[cfg(any(feature = "full", feature = "derive"))]
+impl ParseQuote for Field {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+
+ let ident: Option<Ident>;
+ let colon_token: Option<Token![:]>;
+ let is_named = input.peek(Ident) && input.peek2(Token![:]) && !input.peek2(Token![::]);
+ if is_named {
+ ident = Some(input.parse()?);
+ colon_token = Some(input.parse()?);
+ } else {
+ ident = None;
+ colon_token = None;
+ }
+
+ let ty: Type = input.parse()?;
+
+ Ok(Field {
+ attrs,
+ vis,
+ mutability: FieldMutability::None,
+ ident,
+ colon_token,
+ ty,
+ })
+ }
+}
+
+#[cfg(feature = "full")]
+impl ParseQuote for Pat {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Pat::parse_multi_with_leading_vert(input)
+ }
+}
+
+#[cfg(feature = "full")]
+impl ParseQuote for Box<Pat> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ <Pat as ParseQuote>::parse(input).map(Box::new)
+ }
+}
+
+impl<T: Parse, P: Parse> ParseQuote for Punctuated<T, P> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Self::parse_terminated(input)
+ }
+}
+
+#[cfg(feature = "full")]
+impl ParseQuote for Vec<Stmt> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Block::parse_within(input)
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/pat.rs b/rust/hw/char/pl011/vendor/syn/src/pat.rs
new file mode 100644
index 0000000000..e647f2f4d0
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/pat.rs
@@ -0,0 +1,953 @@
+use crate::attr::Attribute;
+use crate::expr::Member;
+use crate::ident::Ident;
+use crate::path::{Path, QSelf};
+use crate::punctuated::Punctuated;
+use crate::token;
+use crate::ty::Type;
+use proc_macro2::TokenStream;
+
+pub use crate::expr::{
+ ExprConst as PatConst, ExprLit as PatLit, ExprMacro as PatMacro, ExprPath as PatPath,
+ ExprRange as PatRange,
+};
+
+ast_enum_of_structs! {
+ /// A pattern in a local binding, function signature, match expression, or
+ /// various other places.
+ ///
+ /// # 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 = "full")))]
+ #[non_exhaustive]
+ pub enum Pat {
+ /// A const block: `const { ... }`.
+ Const(PatConst),
+
+ /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
+ Ident(PatIdent),
+
+ /// A literal pattern: `0`.
+ Lit(PatLit),
+
+ /// A macro in pattern position.
+ Macro(PatMacro),
+
+ /// A pattern that matches any one of a set of cases.
+ Or(PatOr),
+
+ /// A parenthesized pattern: `(A | B)`.
+ Paren(PatParen),
+
+ /// A path pattern like `Color::Red`, optionally qualified with a
+ /// self-type.
+ ///
+ /// Unqualified path patterns can legally refer to variants, structs,
+ /// constants or associated constants. Qualified path patterns like
+ /// `<A>::B::C` and `<A as Trait>::B::C` can only legally refer to
+ /// associated constants.
+ Path(PatPath),
+
+ /// A range pattern: `1..=2`.
+ Range(PatRange),
+
+ /// A reference pattern: `&mut var`.
+ Reference(PatReference),
+
+ /// The dots in a tuple or slice pattern: `[0, 1, ..]`.
+ Rest(PatRest),
+
+ /// A dynamically sized slice pattern: `[a, b, ref i @ .., y, z]`.
+ Slice(PatSlice),
+
+ /// A struct or struct variant pattern: `Variant { x, y, .. }`.
+ Struct(PatStruct),
+
+ /// A tuple pattern: `(a, b)`.
+ Tuple(PatTuple),
+
+ /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
+ TupleStruct(PatTupleStruct),
+
+ /// A type ascription pattern: `foo: f64`.
+ Type(PatType),
+
+ /// Tokens in pattern position not interpreted by Syn.
+ Verbatim(TokenStream),
+
+ /// A pattern that matches any value: `_`.
+ Wild(PatWild),
+
+ // For testing exhaustiveness in downstream code, use the following idiom:
+ //
+ // match pat {
+ // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
+ //
+ // Pat::Box(pat) => {...}
+ // Pat::Ident(pat) => {...}
+ // ...
+ // Pat::Wild(pat) => {...}
+ //
+ // _ => { /* 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.
+ }
+}
+
+ast_struct! {
+ /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
+ ///
+ /// It may also be a unit struct or struct variant (e.g. `None`), or a
+ /// constant; these cannot be distinguished syntactically.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct PatIdent {
+ pub attrs: Vec<Attribute>,
+ pub by_ref: Option<Token![ref]>,
+ pub mutability: Option<Token![mut]>,
+ pub ident: Ident,
+ pub subpat: Option<(Token![@], Box<Pat>)>,
+ }
+}
+
+ast_struct! {
+ /// A pattern that matches any one of a set of cases.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct PatOr {
+ pub attrs: Vec<Attribute>,
+ pub leading_vert: Option<Token![|]>,
+ pub cases: Punctuated<Pat, Token![|]>,
+ }
+}
+
+ast_struct! {
+ /// A parenthesized pattern: `(A | B)`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct PatParen {
+ pub attrs: Vec<Attribute>,
+ pub paren_token: token::Paren,
+ pub pat: Box<Pat>,
+ }
+}
+
+ast_struct! {
+ /// A reference pattern: `&mut var`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct PatReference {
+ pub attrs: Vec<Attribute>,
+ pub and_token: Token![&],
+ pub mutability: Option<Token![mut]>,
+ pub pat: Box<Pat>,
+ }
+}
+
+ast_struct! {
+ /// The dots in a tuple or slice pattern: `[0, 1, ..]`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct PatRest {
+ pub attrs: Vec<Attribute>,
+ pub dot2_token: Token![..],
+ }
+}
+
+ast_struct! {
+ /// A dynamically sized slice pattern: `[a, b, ref i @ .., y, z]`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct PatSlice {
+ pub attrs: Vec<Attribute>,
+ pub bracket_token: token::Bracket,
+ pub elems: Punctuated<Pat, Token![,]>,
+ }
+}
+
+ast_struct! {
+ /// A struct or struct variant pattern: `Variant { x, y, .. }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct PatStruct {
+ pub attrs: Vec<Attribute>,
+ pub qself: Option<QSelf>,
+ pub path: Path,
+ pub brace_token: token::Brace,
+ pub fields: Punctuated<FieldPat, Token![,]>,
+ pub rest: Option<PatRest>,
+ }
+}
+
+ast_struct! {
+ /// A tuple pattern: `(a, b)`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct PatTuple {
+ pub attrs: Vec<Attribute>,
+ pub paren_token: token::Paren,
+ pub elems: Punctuated<Pat, Token![,]>,
+ }
+}
+
+ast_struct! {
+ /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct PatTupleStruct {
+ pub attrs: Vec<Attribute>,
+ pub qself: Option<QSelf>,
+ pub path: Path,
+ pub paren_token: token::Paren,
+ pub elems: Punctuated<Pat, Token![,]>,
+ }
+}
+
+ast_struct! {
+ /// A type ascription pattern: `foo: f64`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct PatType {
+ pub attrs: Vec<Attribute>,
+ pub pat: Box<Pat>,
+ pub colon_token: Token![:],
+ pub ty: Box<Type>,
+ }
+}
+
+ast_struct! {
+ /// A pattern that matches any value: `_`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct PatWild {
+ pub attrs: Vec<Attribute>,
+ pub underscore_token: Token![_],
+ }
+}
+
+ast_struct! {
+ /// A single field in a struct pattern.
+ ///
+ /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated
+ /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct FieldPat {
+ pub attrs: Vec<Attribute>,
+ pub member: Member,
+ pub colon_token: Option<Token![:]>,
+ pub pat: Box<Pat>,
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::attr::Attribute;
+ use crate::error::{self, Result};
+ use crate::expr::{
+ Expr, ExprConst, ExprLit, ExprMacro, ExprPath, ExprRange, Member, RangeLimits,
+ };
+ use crate::ext::IdentExt as _;
+ use crate::ident::Ident;
+ use crate::lit::Lit;
+ use crate::mac::{self, Macro};
+ use crate::parse::{Parse, ParseBuffer, ParseStream};
+ use crate::pat::{
+ FieldPat, Pat, PatIdent, PatOr, PatParen, PatReference, PatRest, PatSlice, PatStruct,
+ PatTuple, PatTupleStruct, PatType, PatWild,
+ };
+ use crate::path::{self, Path, QSelf};
+ use crate::punctuated::Punctuated;
+ use crate::stmt::Block;
+ use crate::token;
+ use crate::verbatim;
+ use proc_macro2::TokenStream;
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Pat {
+ /// Parse a pattern that does _not_ involve `|` at the top level.
+ ///
+ /// This parser matches the behavior of the `$:pat_param` macro_rules
+ /// matcher, and on editions prior to Rust 2021, the behavior of
+ /// `$:pat`.
+ ///
+ /// In Rust syntax, some examples of where this syntax would occur are
+ /// in the argument pattern of functions and closures. Patterns using
+ /// `|` are not allowed to occur in these positions.
+ ///
+ /// ```compile_fail
+ /// fn f(Some(_) | None: Option<T>) {
+ /// let _ = |Some(_) | None: Option<T>| {};
+ /// // ^^^^^^^^^^^^^^^^^^^^^^^^^??? :(
+ /// }
+ /// ```
+ ///
+ /// ```console
+ /// error: top-level or-patterns are not allowed in function parameters
+ /// --> src/main.rs:1:6
+ /// |
+ /// 1 | fn f(Some(_) | None: Option<T>) {
+ /// | ^^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(Some(_) | None)`
+ /// ```
+ pub fn parse_single(input: ParseStream) -> Result<Self> {
+ let begin = input.fork();
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Ident)
+ && (input.peek2(Token![::])
+ || input.peek2(Token![!])
+ || input.peek2(token::Brace)
+ || input.peek2(token::Paren)
+ || input.peek2(Token![..]))
+ || input.peek(Token![self]) && input.peek2(Token![::])
+ || lookahead.peek(Token![::])
+ || lookahead.peek(Token![<])
+ || input.peek(Token![Self])
+ || input.peek(Token![super])
+ || input.peek(Token![crate])
+ {
+ pat_path_or_macro_or_struct_or_range(input)
+ } else if lookahead.peek(Token![_]) {
+ input.call(pat_wild).map(Pat::Wild)
+ } else if input.peek(Token![box]) {
+ pat_box(begin, input)
+ } else if input.peek(Token![-]) || lookahead.peek(Lit) || lookahead.peek(Token![const])
+ {
+ pat_lit_or_range(input)
+ } else if lookahead.peek(Token![ref])
+ || lookahead.peek(Token![mut])
+ || input.peek(Token![self])
+ || input.peek(Ident)
+ {
+ input.call(pat_ident).map(Pat::Ident)
+ } else if lookahead.peek(Token![&]) {
+ input.call(pat_reference).map(Pat::Reference)
+ } else if lookahead.peek(token::Paren) {
+ input.call(pat_paren_or_tuple)
+ } else if lookahead.peek(token::Bracket) {
+ input.call(pat_slice).map(Pat::Slice)
+ } else if lookahead.peek(Token![..]) && !input.peek(Token![...]) {
+ pat_range_half_open(input)
+ } else if lookahead.peek(Token![const]) {
+ input.call(pat_const).map(Pat::Verbatim)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+
+ /// Parse a pattern, possibly involving `|`, but not a leading `|`.
+ pub fn parse_multi(input: ParseStream) -> Result<Self> {
+ multi_pat_impl(input, None)
+ }
+
+ /// Parse a pattern, possibly involving `|`, possibly including a
+ /// leading `|`.
+ ///
+ /// This parser matches the behavior of the Rust 2021 edition's `$:pat`
+ /// macro_rules matcher.
+ ///
+ /// In Rust syntax, an example of where this syntax would occur is in
+ /// the pattern of a `match` arm, where the language permits an optional
+ /// leading `|`, although it is not idiomatic to write one there in
+ /// handwritten code.
+ ///
+ /// ```
+ /// # let wat = None;
+ /// match wat {
+ /// | None | Some(false) => {}
+ /// | Some(true) => {}
+ /// }
+ /// ```
+ ///
+ /// The compiler accepts it only to facilitate some situations in
+ /// macro-generated code where a macro author might need to write:
+ ///
+ /// ```
+ /// # macro_rules! doc {
+ /// # ($value:expr, ($($conditions1:pat),*), ($($conditions2:pat),*), $then:expr) => {
+ /// match $value {
+ /// $(| $conditions1)* $(| $conditions2)* => $then
+ /// }
+ /// # };
+ /// # }
+ /// #
+ /// # doc!(true, (true), (false), {});
+ /// # doc!(true, (), (true, false), {});
+ /// # doc!(true, (true, false), (), {});
+ /// ```
+ ///
+ /// Expressing the same thing correctly in the case that either one (but
+ /// not both) of `$conditions1` and `$conditions2` might be empty,
+ /// without leading `|`, is complex.
+ ///
+ /// Use [`Pat::parse_multi`] instead if you are not intending to support
+ /// macro-generated macro input.
+ pub fn parse_multi_with_leading_vert(input: ParseStream) -> Result<Self> {
+ let leading_vert: Option<Token![|]> = input.parse()?;
+ multi_pat_impl(input, leading_vert)
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for PatType {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(PatType {
+ attrs: Vec::new(),
+ pat: Box::new(Pat::parse_single(input)?),
+ colon_token: input.parse()?,
+ ty: input.parse()?,
+ })
+ }
+ }
+
+ fn multi_pat_impl(input: ParseStream, leading_vert: Option<Token![|]>) -> Result<Pat> {
+ let mut pat = Pat::parse_single(input)?;
+ if leading_vert.is_some()
+ || input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=])
+ {
+ let mut cases = Punctuated::new();
+ cases.push_value(pat);
+ while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
+ let punct = input.parse()?;
+ cases.push_punct(punct);
+ let pat = Pat::parse_single(input)?;
+ cases.push_value(pat);
+ }
+ pat = Pat::Or(PatOr {
+ attrs: Vec::new(),
+ leading_vert,
+ cases,
+ });
+ }
+ Ok(pat)
+ }
+
+ fn pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat> {
+ let (qself, path) = path::parsing::qpath(input, true)?;
+
+ if qself.is_none()
+ && input.peek(Token![!])
+ && !input.peek(Token![!=])
+ && path.is_mod_style()
+ {
+ let bang_token: Token![!] = input.parse()?;
+ let (delimiter, tokens) = mac::parse_delimiter(input)?;
+ return Ok(Pat::Macro(ExprMacro {
+ attrs: Vec::new(),
+ mac: Macro {
+ path,
+ bang_token,
+ delimiter,
+ tokens,
+ },
+ }));
+ }
+
+ if input.peek(token::Brace) {
+ pat_struct(input, qself, path).map(Pat::Struct)
+ } else if input.peek(token::Paren) {
+ pat_tuple_struct(input, qself, path).map(Pat::TupleStruct)
+ } else if input.peek(Token![..]) {
+ pat_range(input, qself, path)
+ } else {
+ Ok(Pat::Path(ExprPath {
+ attrs: Vec::new(),
+ qself,
+ path,
+ }))
+ }
+ }
+
+ fn pat_wild(input: ParseStream) -> Result<PatWild> {
+ Ok(PatWild {
+ attrs: Vec::new(),
+ underscore_token: input.parse()?,
+ })
+ }
+
+ fn pat_box(begin: ParseBuffer, input: ParseStream) -> Result<Pat> {
+ input.parse::<Token![box]>()?;
+ Pat::parse_single(input)?;
+ Ok(Pat::Verbatim(verbatim::between(&begin, input)))
+ }
+
+ fn pat_ident(input: ParseStream) -> Result<PatIdent> {
+ Ok(PatIdent {
+ attrs: Vec::new(),
+ by_ref: input.parse()?,
+ mutability: input.parse()?,
+ ident: {
+ if input.peek(Token![self]) {
+ input.call(Ident::parse_any)?
+ } else {
+ input.parse()?
+ }
+ },
+ subpat: {
+ if input.peek(Token![@]) {
+ let at_token: Token![@] = input.parse()?;
+ let subpat = Pat::parse_single(input)?;
+ Some((at_token, Box::new(subpat)))
+ } else {
+ None
+ }
+ },
+ })
+ }
+
+ fn pat_tuple_struct(
+ input: ParseStream,
+ qself: Option<QSelf>,
+ path: Path,
+ ) -> Result<PatTupleStruct> {
+ let content;
+ let paren_token = parenthesized!(content in input);
+
+ let mut elems = Punctuated::new();
+ while !content.is_empty() {
+ let value = Pat::parse_multi_with_leading_vert(&content)?;
+ elems.push_value(value);
+ if content.is_empty() {
+ break;
+ }
+ let punct = content.parse()?;
+ elems.push_punct(punct);
+ }
+
+ Ok(PatTupleStruct {
+ attrs: Vec::new(),
+ qself,
+ path,
+ paren_token,
+ elems,
+ })
+ }
+
+ fn pat_struct(input: ParseStream, qself: Option<QSelf>, path: Path) -> Result<PatStruct> {
+ let content;
+ let brace_token = braced!(content in input);
+
+ let mut fields = Punctuated::new();
+ let mut rest = None;
+ while !content.is_empty() {
+ let attrs = content.call(Attribute::parse_outer)?;
+ if content.peek(Token![..]) {
+ rest = Some(PatRest {
+ attrs,
+ dot2_token: content.parse()?,
+ });
+ break;
+ }
+ let mut value = content.call(field_pat)?;
+ value.attrs = attrs;
+ fields.push_value(value);
+ if content.is_empty() {
+ break;
+ }
+ let punct: Token![,] = content.parse()?;
+ fields.push_punct(punct);
+ }
+
+ Ok(PatStruct {
+ attrs: Vec::new(),
+ qself,
+ path,
+ brace_token,
+ fields,
+ rest,
+ })
+ }
+
+ fn field_pat(input: ParseStream) -> Result<FieldPat> {
+ let begin = input.fork();
+ let boxed: Option<Token![box]> = input.parse()?;
+ let by_ref: Option<Token![ref]> = input.parse()?;
+ let mutability: Option<Token![mut]> = input.parse()?;
+
+ let member = if boxed.is_some() || by_ref.is_some() || mutability.is_some() {
+ input.parse().map(Member::Named)
+ } else {
+ input.parse()
+ }?;
+
+ if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
+ || !member.is_named()
+ {
+ return Ok(FieldPat {
+ attrs: Vec::new(),
+ member,
+ colon_token: Some(input.parse()?),
+ pat: Box::new(Pat::parse_multi_with_leading_vert(input)?),
+ });
+ }
+
+ let ident = match member {
+ Member::Named(ident) => ident,
+ Member::Unnamed(_) => unreachable!(),
+ };
+
+ let pat = if boxed.is_some() {
+ Pat::Verbatim(verbatim::between(&begin, input))
+ } else {
+ Pat::Ident(PatIdent {
+ attrs: Vec::new(),
+ by_ref,
+ mutability,
+ ident: ident.clone(),
+ subpat: None,
+ })
+ };
+
+ Ok(FieldPat {
+ attrs: Vec::new(),
+ member: Member::Named(ident),
+ colon_token: None,
+ pat: Box::new(pat),
+ })
+ }
+
+ fn pat_range(input: ParseStream, qself: Option<QSelf>, path: Path) -> Result<Pat> {
+ let limits = RangeLimits::parse_obsolete(input)?;
+ let end = input.call(pat_range_bound)?;
+ if let (RangeLimits::Closed(_), None) = (&limits, &end) {
+ return Err(input.error("expected range upper bound"));
+ }
+ Ok(Pat::Range(ExprRange {
+ attrs: Vec::new(),
+ start: Some(Box::new(Expr::Path(ExprPath {
+ attrs: Vec::new(),
+ qself,
+ path,
+ }))),
+ limits,
+ end: end.map(PatRangeBound::into_expr),
+ }))
+ }
+
+ fn pat_range_half_open(input: ParseStream) -> Result<Pat> {
+ let limits: RangeLimits = input.parse()?;
+ let end = input.call(pat_range_bound)?;
+ if end.is_some() {
+ Ok(Pat::Range(ExprRange {
+ attrs: Vec::new(),
+ start: None,
+ limits,
+ end: end.map(PatRangeBound::into_expr),
+ }))
+ } else {
+ match limits {
+ RangeLimits::HalfOpen(dot2_token) => Ok(Pat::Rest(PatRest {
+ attrs: Vec::new(),
+ dot2_token,
+ })),
+ RangeLimits::Closed(_) => Err(input.error("expected range upper bound")),
+ }
+ }
+ }
+
+ fn pat_paren_or_tuple(input: ParseStream) -> Result<Pat> {
+ let content;
+ let paren_token = parenthesized!(content in input);
+
+ let mut elems = Punctuated::new();
+ while !content.is_empty() {
+ let value = Pat::parse_multi_with_leading_vert(&content)?;
+ if content.is_empty() {
+ if elems.is_empty() && !matches!(value, Pat::Rest(_)) {
+ return Ok(Pat::Paren(PatParen {
+ attrs: Vec::new(),
+ paren_token,
+ pat: Box::new(value),
+ }));
+ }
+ elems.push_value(value);
+ break;
+ }
+ elems.push_value(value);
+ let punct = content.parse()?;
+ elems.push_punct(punct);
+ }
+
+ Ok(Pat::Tuple(PatTuple {
+ attrs: Vec::new(),
+ paren_token,
+ elems,
+ }))
+ }
+
+ fn pat_reference(input: ParseStream) -> Result<PatReference> {
+ Ok(PatReference {
+ attrs: Vec::new(),
+ and_token: input.parse()?,
+ mutability: input.parse()?,
+ pat: Box::new(Pat::parse_single(input)?),
+ })
+ }
+
+ fn pat_lit_or_range(input: ParseStream) -> Result<Pat> {
+ let start = input.call(pat_range_bound)?.unwrap();
+ if input.peek(Token![..]) {
+ let limits = RangeLimits::parse_obsolete(input)?;
+ let end = input.call(pat_range_bound)?;
+ if let (RangeLimits::Closed(_), None) = (&limits, &end) {
+ return Err(input.error("expected range upper bound"));
+ }
+ Ok(Pat::Range(ExprRange {
+ attrs: Vec::new(),
+ start: Some(start.into_expr()),
+ limits,
+ end: end.map(PatRangeBound::into_expr),
+ }))
+ } else {
+ Ok(start.into_pat())
+ }
+ }
+
+ // Patterns that can appear on either side of a range pattern.
+ enum PatRangeBound {
+ Const(ExprConst),
+ Lit(ExprLit),
+ Path(ExprPath),
+ }
+
+ impl PatRangeBound {
+ fn into_expr(self) -> Box<Expr> {
+ Box::new(match self {
+ PatRangeBound::Const(pat) => Expr::Const(pat),
+ PatRangeBound::Lit(pat) => Expr::Lit(pat),
+ PatRangeBound::Path(pat) => Expr::Path(pat),
+ })
+ }
+
+ fn into_pat(self) -> Pat {
+ match self {
+ PatRangeBound::Const(pat) => Pat::Const(pat),
+ PatRangeBound::Lit(pat) => Pat::Lit(pat),
+ PatRangeBound::Path(pat) => Pat::Path(pat),
+ }
+ }
+ }
+
+ fn pat_range_bound(input: ParseStream) -> Result<Option<PatRangeBound>> {
+ if input.is_empty()
+ || input.peek(Token![|])
+ || input.peek(Token![=])
+ || input.peek(Token![:]) && !input.peek(Token![::])
+ || input.peek(Token![,])
+ || input.peek(Token![;])
+ || input.peek(Token![if])
+ {
+ return Ok(None);
+ }
+
+ let lookahead = input.lookahead1();
+ let expr = if lookahead.peek(Lit) {
+ PatRangeBound::Lit(input.parse()?)
+ } else if lookahead.peek(Ident)
+ || lookahead.peek(Token![::])
+ || lookahead.peek(Token![<])
+ || lookahead.peek(Token![self])
+ || lookahead.peek(Token![Self])
+ || lookahead.peek(Token![super])
+ || lookahead.peek(Token![crate])
+ {
+ PatRangeBound::Path(input.parse()?)
+ } else if lookahead.peek(Token![const]) {
+ PatRangeBound::Const(input.parse()?)
+ } else {
+ return Err(lookahead.error());
+ };
+
+ Ok(Some(expr))
+ }
+
+ fn pat_slice(input: ParseStream) -> Result<PatSlice> {
+ let content;
+ let bracket_token = bracketed!(content in input);
+
+ let mut elems = Punctuated::new();
+ while !content.is_empty() {
+ let value = Pat::parse_multi_with_leading_vert(&content)?;
+ match value {
+ Pat::Range(pat) if pat.start.is_none() || pat.end.is_none() => {
+ let (start, end) = match pat.limits {
+ RangeLimits::HalfOpen(dot_dot) => (dot_dot.spans[0], dot_dot.spans[1]),
+ RangeLimits::Closed(dot_dot_eq) => {
+ (dot_dot_eq.spans[0], dot_dot_eq.spans[2])
+ }
+ };
+ let msg = "range pattern is not allowed unparenthesized inside slice pattern";
+ return Err(error::new2(start, end, msg));
+ }
+ _ => {}
+ }
+ elems.push_value(value);
+ if content.is_empty() {
+ break;
+ }
+ let punct = content.parse()?;
+ elems.push_punct(punct);
+ }
+
+ Ok(PatSlice {
+ attrs: Vec::new(),
+ bracket_token,
+ elems,
+ })
+ }
+
+ fn pat_const(input: ParseStream) -> Result<TokenStream> {
+ let begin = input.fork();
+ input.parse::<Token![const]>()?;
+
+ let content;
+ braced!(content in input);
+ content.call(Attribute::parse_inner)?;
+ content.call(Block::parse_within)?;
+
+ Ok(verbatim::between(&begin, input))
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use crate::attr::FilterAttrs;
+ use crate::pat::{
+ FieldPat, Pat, PatIdent, PatOr, PatParen, PatReference, PatRest, PatSlice, PatStruct,
+ PatTuple, PatTupleStruct, PatType, PatWild,
+ };
+ use crate::path;
+ use proc_macro2::TokenStream;
+ use quote::{ToTokens, TokenStreamExt};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PatIdent {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.by_ref.to_tokens(tokens);
+ self.mutability.to_tokens(tokens);
+ self.ident.to_tokens(tokens);
+ if let Some((at_token, subpat)) = &self.subpat {
+ at_token.to_tokens(tokens);
+ subpat.to_tokens(tokens);
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PatOr {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.leading_vert.to_tokens(tokens);
+ self.cases.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PatParen {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.paren_token.surround(tokens, |tokens| {
+ self.pat.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PatReference {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.and_token.to_tokens(tokens);
+ self.mutability.to_tokens(tokens);
+ self.pat.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PatRest {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.dot2_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PatSlice {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.bracket_token.surround(tokens, |tokens| {
+ self.elems.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PatStruct {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ path::printing::print_path(tokens, &self.qself, &self.path);
+ self.brace_token.surround(tokens, |tokens| {
+ self.fields.to_tokens(tokens);
+ // NOTE: We need a comma before the dot2 token if it is present.
+ if !self.fields.empty_or_trailing() && self.rest.is_some() {
+ <Token![,]>::default().to_tokens(tokens);
+ }
+ self.rest.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PatTuple {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.paren_token.surround(tokens, |tokens| {
+ self.elems.to_tokens(tokens);
+ // If there is only one element, a trailing comma is needed to
+ // distinguish PatTuple from PatParen, unless this is `(..)`
+ // which is a tuple pattern even without comma.
+ if self.elems.len() == 1
+ && !self.elems.trailing_punct()
+ && !matches!(self.elems[0], Pat::Rest { .. })
+ {
+ <Token![,]>::default().to_tokens(tokens);
+ }
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PatTupleStruct {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ path::printing::print_path(tokens, &self.qself, &self.path);
+ self.paren_token.surround(tokens, |tokens| {
+ self.elems.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PatType {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.pat.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PatWild {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ self.underscore_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for FieldPat {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ if let Some(colon_token) = &self.colon_token {
+ self.member.to_tokens(tokens);
+ colon_token.to_tokens(tokens);
+ }
+ self.pat.to_tokens(tokens);
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/path.rs b/rust/hw/char/pl011/vendor/syn/src/path.rs
new file mode 100644
index 0000000000..636d5d5e8f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/path.rs
@@ -0,0 +1,886 @@
+#[cfg(feature = "parsing")]
+use crate::error::Result;
+use crate::expr::Expr;
+use crate::generics::TypeParamBound;
+use crate::ident::Ident;
+use crate::lifetime::Lifetime;
+use crate::punctuated::Punctuated;
+use crate::token;
+use crate::ty::{ReturnType, Type};
+
+ast_struct! {
+ /// A path at which a named item is exported (e.g. `std::collections::HashMap`).
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct Path {
+ pub leading_colon: Option<Token![::]>,
+ pub segments: Punctuated<PathSegment, Token![::]>,
+ }
+}
+
+impl<T> From<T> for Path
+where
+ T: Into<PathSegment>,
+{
+ fn from(segment: T) -> Self {
+ let mut path = Path {
+ leading_colon: None,
+ segments: Punctuated::new(),
+ };
+ path.segments.push_value(segment.into());
+ path
+ }
+}
+
+impl Path {
+ /// Determines whether this is a path of length 1 equal to the given
+ /// ident.
+ ///
+ /// For them to compare equal, it must be the case that:
+ ///
+ /// - the path has no leading colon,
+ /// - the number of path segments is 1,
+ /// - the first path segment has no angle bracketed or parenthesized
+ /// path arguments, and
+ /// - the ident of the first path segment is equal to the given one.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use proc_macro2::TokenStream;
+ /// use syn::{Attribute, Error, Meta, Result};
+ ///
+ /// fn get_serde_meta_item(attr: &Attribute) -> Result<Option<&TokenStream>> {
+ /// if attr.path().is_ident("serde") {
+ /// match &attr.meta {
+ /// Meta::List(meta) => Ok(Some(&meta.tokens)),
+ /// bad => Err(Error::new_spanned(bad, "unrecognized attribute")),
+ /// }
+ /// } else {
+ /// Ok(None)
+ /// }
+ /// }
+ /// ```
+ pub fn is_ident<I>(&self, ident: &I) -> bool
+ where
+ I: ?Sized,
+ Ident: PartialEq<I>,
+ {
+ match self.get_ident() {
+ Some(id) => id == ident,
+ None => false,
+ }
+ }
+
+ /// If this path consists of a single ident, returns the ident.
+ ///
+ /// A path is considered an ident if:
+ ///
+ /// - the path has no leading colon,
+ /// - the number of path segments is 1, and
+ /// - the first path segment has no angle bracketed or parenthesized
+ /// path arguments.
+ pub fn get_ident(&self) -> Option<&Ident> {
+ if self.leading_colon.is_none()
+ && self.segments.len() == 1
+ && self.segments[0].arguments.is_none()
+ {
+ Some(&self.segments[0].ident)
+ } else {
+ None
+ }
+ }
+
+ /// An error if this path is not a single ident, as defined in `get_ident`.
+ #[cfg(feature = "parsing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn require_ident(&self) -> Result<&Ident> {
+ self.get_ident().ok_or_else(|| {
+ crate::error::new2(
+ self.segments.first().unwrap().ident.span(),
+ self.segments.last().unwrap().ident.span(),
+ "expected this path to be an identifier",
+ )
+ })
+ }
+}
+
+ast_struct! {
+ /// A segment of a path together with any path arguments on that segment.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct PathSegment {
+ pub ident: Ident,
+ pub arguments: PathArguments,
+ }
+}
+
+impl<T> From<T> for PathSegment
+where
+ T: Into<Ident>,
+{
+ fn from(ident: T) -> Self {
+ PathSegment {
+ ident: ident.into(),
+ arguments: PathArguments::None,
+ }
+ }
+}
+
+ast_enum! {
+ /// Angle bracketed or parenthesized arguments of a path segment.
+ ///
+ /// ## Angle bracketed
+ ///
+ /// The `<'a, T>` in `std::slice::iter<'a, T>`.
+ ///
+ /// ## Parenthesized
+ ///
+ /// The `(A, B) -> C` in `Fn(A, B) -> C`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub enum PathArguments {
+ None,
+ /// The `<'a, T>` in `std::slice::iter<'a, T>`.
+ AngleBracketed(AngleBracketedGenericArguments),
+ /// The `(A, B) -> C` in `Fn(A, B) -> C`.
+ Parenthesized(ParenthesizedGenericArguments),
+ }
+}
+
+impl Default for PathArguments {
+ fn default() -> Self {
+ PathArguments::None
+ }
+}
+
+impl PathArguments {
+ pub fn is_empty(&self) -> bool {
+ match self {
+ PathArguments::None => true,
+ PathArguments::AngleBracketed(bracketed) => bracketed.args.is_empty(),
+ PathArguments::Parenthesized(_) => false,
+ }
+ }
+
+ pub fn is_none(&self) -> bool {
+ match self {
+ PathArguments::None => true,
+ PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => false,
+ }
+ }
+}
+
+ast_enum! {
+ /// An individual generic argument, like `'a`, `T`, or `Item = T`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ #[non_exhaustive]
+ pub enum GenericArgument {
+ /// A lifetime argument.
+ Lifetime(Lifetime),
+ /// A type argument.
+ Type(Type),
+ /// A const expression. Must be inside of a block.
+ ///
+ /// NOTE: Identity expressions are represented as Type arguments, as
+ /// they are indistinguishable syntactically.
+ Const(Expr),
+ /// A binding (equality constraint) on an associated type: the `Item =
+ /// u8` in `Iterator<Item = u8>`.
+ AssocType(AssocType),
+ /// An equality constraint on an associated constant: the `PANIC =
+ /// false` in `Trait<PANIC = false>`.
+ AssocConst(AssocConst),
+ /// An associated type bound: `Iterator<Item: Display>`.
+ Constraint(Constraint),
+ }
+}
+
+ast_struct! {
+ /// Angle bracketed arguments of a path segment: the `<K, V>` in `HashMap<K,
+ /// V>`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct AngleBracketedGenericArguments {
+ pub colon2_token: Option<Token![::]>,
+ pub lt_token: Token![<],
+ pub args: Punctuated<GenericArgument, Token![,]>,
+ pub gt_token: Token![>],
+ }
+}
+
+ast_struct! {
+ /// A binding (equality constraint) on an associated type: the `Item = u8`
+ /// in `Iterator<Item = u8>`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct AssocType {
+ pub ident: Ident,
+ pub generics: Option<AngleBracketedGenericArguments>,
+ pub eq_token: Token![=],
+ pub ty: Type,
+ }
+}
+
+ast_struct! {
+ /// An equality constraint on an associated constant: the `PANIC = false` in
+ /// `Trait<PANIC = false>`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct AssocConst {
+ pub ident: Ident,
+ pub generics: Option<AngleBracketedGenericArguments>,
+ pub eq_token: Token![=],
+ pub value: Expr,
+ }
+}
+
+ast_struct! {
+ /// An associated type bound: `Iterator<Item: Display>`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct Constraint {
+ pub ident: Ident,
+ pub generics: Option<AngleBracketedGenericArguments>,
+ pub colon_token: Token![:],
+ pub bounds: Punctuated<TypeParamBound, Token![+]>,
+ }
+}
+
+ast_struct! {
+ /// Arguments of a function path segment: the `(A, B) -> C` in `Fn(A,B) ->
+ /// C`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct ParenthesizedGenericArguments {
+ pub paren_token: token::Paren,
+ /// `(A, B)`
+ pub inputs: Punctuated<Type, Token![,]>,
+ /// `C`
+ pub output: ReturnType,
+ }
+}
+
+ast_struct! {
+ /// The explicit Self type in a qualified path: the `T` in `<T as
+ /// Display>::fmt`.
+ ///
+ /// The actual path, including the trait and the associated item, is stored
+ /// separately. The `position` field represents the index of the associated
+ /// item qualified with this Self type.
+ ///
+ /// ```text
+ /// <Vec<T> as a::b::Trait>::AssociatedItem
+ /// ^~~~~~ ~~~~~~~~~~~~~~^
+ /// ty position = 3
+ ///
+ /// <Vec<T>>::AssociatedItem
+ /// ^~~~~~ ^
+ /// ty position = 0
+ /// ```
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct QSelf {
+ pub lt_token: Token![<],
+ pub ty: Box<Type>,
+ pub position: usize,
+ pub as_token: Option<Token![as]>,
+ pub gt_token: Token![>],
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::error::Result;
+ #[cfg(feature = "full")]
+ use crate::expr::ExprBlock;
+ use crate::expr::{Expr, ExprPath};
+ use crate::ext::IdentExt as _;
+ #[cfg(feature = "full")]
+ use crate::generics::TypeParamBound;
+ use crate::ident::Ident;
+ use crate::lifetime::Lifetime;
+ use crate::lit::Lit;
+ use crate::parse::{Parse, ParseStream};
+ #[cfg(feature = "full")]
+ use crate::path::Constraint;
+ use crate::path::{
+ AngleBracketedGenericArguments, AssocConst, AssocType, GenericArgument,
+ ParenthesizedGenericArguments, Path, PathArguments, PathSegment, QSelf,
+ };
+ use crate::punctuated::Punctuated;
+ use crate::token;
+ use crate::ty::{ReturnType, Type};
+ #[cfg(not(feature = "full"))]
+ use crate::verbatim;
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Path {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Self::parse_helper(input, false)
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for GenericArgument {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Lifetime) && !input.peek2(Token![+]) {
+ return Ok(GenericArgument::Lifetime(input.parse()?));
+ }
+
+ if input.peek(Lit) || input.peek(token::Brace) {
+ return const_argument(input).map(GenericArgument::Const);
+ }
+
+ let mut argument: Type = input.parse()?;
+
+ match argument {
+ Type::Path(mut ty)
+ if ty.qself.is_none()
+ && ty.path.leading_colon.is_none()
+ && ty.path.segments.len() == 1
+ && match &ty.path.segments[0].arguments {
+ PathArguments::None | PathArguments::AngleBracketed(_) => true,
+ PathArguments::Parenthesized(_) => false,
+ } =>
+ {
+ if let Some(eq_token) = input.parse::<Option<Token![=]>>()? {
+ let segment = ty.path.segments.pop().unwrap().into_value();
+ let ident = segment.ident;
+ let generics = match segment.arguments {
+ PathArguments::None => None,
+ PathArguments::AngleBracketed(arguments) => Some(arguments),
+ PathArguments::Parenthesized(_) => unreachable!(),
+ };
+ return if input.peek(Lit) || input.peek(token::Brace) {
+ Ok(GenericArgument::AssocConst(AssocConst {
+ ident,
+ generics,
+ eq_token,
+ value: const_argument(input)?,
+ }))
+ } else {
+ Ok(GenericArgument::AssocType(AssocType {
+ ident,
+ generics,
+ eq_token,
+ ty: input.parse()?,
+ }))
+ };
+ }
+
+ #[cfg(feature = "full")]
+ if let Some(colon_token) = input.parse::<Option<Token![:]>>()? {
+ let segment = ty.path.segments.pop().unwrap().into_value();
+ return Ok(GenericArgument::Constraint(Constraint {
+ ident: segment.ident,
+ generics: match segment.arguments {
+ PathArguments::None => None,
+ PathArguments::AngleBracketed(arguments) => Some(arguments),
+ PathArguments::Parenthesized(_) => unreachable!(),
+ },
+ colon_token,
+ bounds: {
+ let mut bounds = Punctuated::new();
+ loop {
+ if input.peek(Token![,]) || input.peek(Token![>]) {
+ break;
+ }
+ let value: TypeParamBound = input.parse()?;
+ bounds.push_value(value);
+ if !input.peek(Token![+]) {
+ break;
+ }
+ let punct: Token![+] = input.parse()?;
+ bounds.push_punct(punct);
+ }
+ bounds
+ },
+ }));
+ }
+
+ argument = Type::Path(ty);
+ }
+ _ => {}
+ }
+
+ Ok(GenericArgument::Type(argument))
+ }
+ }
+
+ pub(crate) fn const_argument(input: ParseStream) -> Result<Expr> {
+ let lookahead = input.lookahead1();
+
+ if input.peek(Lit) {
+ let lit = input.parse()?;
+ return Ok(Expr::Lit(lit));
+ }
+
+ if input.peek(Ident) {
+ let ident: Ident = input.parse()?;
+ return Ok(Expr::Path(ExprPath {
+ attrs: Vec::new(),
+ qself: None,
+ path: Path::from(ident),
+ }));
+ }
+
+ if input.peek(token::Brace) {
+ #[cfg(feature = "full")]
+ {
+ let block: ExprBlock = input.parse()?;
+ return Ok(Expr::Block(block));
+ }
+
+ #[cfg(not(feature = "full"))]
+ {
+ let begin = input.fork();
+ let content;
+ braced!(content in input);
+ content.parse::<Expr>()?;
+ let verbatim = verbatim::between(&begin, input);
+ return Ok(Expr::Verbatim(verbatim));
+ }
+ }
+
+ Err(lookahead.error())
+ }
+
+ impl AngleBracketedGenericArguments {
+ /// Parse `::<…>` with mandatory leading `::`.
+ ///
+ /// The ordinary [`Parse`] impl for `AngleBracketedGenericArguments`
+ /// parses optional leading `::`.
+ #[cfg(feature = "full")]
+ #[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "full"))))]
+ pub fn parse_turbofish(input: ParseStream) -> Result<Self> {
+ let colon2_token: Token![::] = input.parse()?;
+ Self::do_parse(Some(colon2_token), input)
+ }
+
+ pub(crate) fn do_parse(
+ colon2_token: Option<Token![::]>,
+ input: ParseStream,
+ ) -> Result<Self> {
+ Ok(AngleBracketedGenericArguments {
+ colon2_token,
+ lt_token: input.parse()?,
+ args: {
+ let mut args = Punctuated::new();
+ loop {
+ if input.peek(Token![>]) {
+ break;
+ }
+ let value: GenericArgument = input.parse()?;
+ args.push_value(value);
+ if input.peek(Token![>]) {
+ break;
+ }
+ let punct: Token![,] = input.parse()?;
+ args.push_punct(punct);
+ }
+ args
+ },
+ gt_token: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for AngleBracketedGenericArguments {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let colon2_token: Option<Token![::]> = input.parse()?;
+ Self::do_parse(colon2_token, input)
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ParenthesizedGenericArguments {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(ParenthesizedGenericArguments {
+ paren_token: parenthesized!(content in input),
+ inputs: content.parse_terminated(Type::parse, Token![,])?,
+ output: input.call(ReturnType::without_plus)?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for PathSegment {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Self::parse_helper(input, false)
+ }
+ }
+
+ impl PathSegment {
+ fn parse_helper(input: ParseStream, expr_style: bool) -> Result<Self> {
+ if input.peek(Token![super])
+ || input.peek(Token![self])
+ || input.peek(Token![crate])
+ || cfg!(feature = "full") && input.peek(Token![try])
+ {
+ let ident = input.call(Ident::parse_any)?;
+ return Ok(PathSegment::from(ident));
+ }
+
+ let ident = if input.peek(Token![Self]) {
+ input.call(Ident::parse_any)?
+ } else {
+ input.parse()?
+ };
+
+ if !expr_style && input.peek(Token![<]) && !input.peek(Token![<=])
+ || input.peek(Token![::]) && input.peek3(Token![<])
+ {
+ Ok(PathSegment {
+ ident,
+ arguments: PathArguments::AngleBracketed(input.parse()?),
+ })
+ } else {
+ Ok(PathSegment::from(ident))
+ }
+ }
+ }
+
+ impl Path {
+ /// Parse a `Path` containing no path arguments on any of its segments.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use syn::{Path, Result, Token};
+ /// use syn::parse::{Parse, ParseStream};
+ ///
+ /// // A simplified single `use` statement like:
+ /// //
+ /// // use std::collections::HashMap;
+ /// //
+ /// // Note that generic parameters are not allowed in a `use` statement
+ /// // so the following must not be accepted.
+ /// //
+ /// // use a::<b>::c;
+ /// struct SingleUse {
+ /// use_token: Token![use],
+ /// path: Path,
+ /// }
+ ///
+ /// impl Parse for SingleUse {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// Ok(SingleUse {
+ /// use_token: input.parse()?,
+ /// path: input.call(Path::parse_mod_style)?,
+ /// })
+ /// }
+ /// }
+ /// ```
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn parse_mod_style(input: ParseStream) -> Result<Self> {
+ Ok(Path {
+ leading_colon: input.parse()?,
+ segments: {
+ let mut segments = Punctuated::new();
+ loop {
+ if !input.peek(Ident)
+ && !input.peek(Token![super])
+ && !input.peek(Token![self])
+ && !input.peek(Token![Self])
+ && !input.peek(Token![crate])
+ {
+ break;
+ }
+ let ident = Ident::parse_any(input)?;
+ segments.push_value(PathSegment::from(ident));
+ if !input.peek(Token![::]) {
+ break;
+ }
+ let punct = input.parse()?;
+ segments.push_punct(punct);
+ }
+ if segments.is_empty() {
+ return Err(input.parse::<Ident>().unwrap_err());
+ } else if segments.trailing_punct() {
+ return Err(input.error("expected path segment after `::`"));
+ }
+ segments
+ },
+ })
+ }
+
+ pub(crate) fn parse_helper(input: ParseStream, expr_style: bool) -> Result<Self> {
+ let mut path = Path {
+ leading_colon: input.parse()?,
+ segments: {
+ let mut segments = Punctuated::new();
+ let value = PathSegment::parse_helper(input, expr_style)?;
+ segments.push_value(value);
+ segments
+ },
+ };
+ Path::parse_rest(input, &mut path, expr_style)?;
+ Ok(path)
+ }
+
+ pub(crate) fn parse_rest(
+ input: ParseStream,
+ path: &mut Self,
+ expr_style: bool,
+ ) -> Result<()> {
+ while input.peek(Token![::]) && !input.peek3(token::Paren) {
+ let punct: Token![::] = input.parse()?;
+ path.segments.push_punct(punct);
+ let value = PathSegment::parse_helper(input, expr_style)?;
+ path.segments.push_value(value);
+ }
+ Ok(())
+ }
+
+ pub(crate) fn is_mod_style(&self) -> bool {
+ self.segments
+ .iter()
+ .all(|segment| segment.arguments.is_none())
+ }
+ }
+
+ pub(crate) fn qpath(input: ParseStream, expr_style: bool) -> Result<(Option<QSelf>, Path)> {
+ if input.peek(Token![<]) {
+ let lt_token: Token![<] = input.parse()?;
+ let this: Type = input.parse()?;
+ let path = if input.peek(Token![as]) {
+ let as_token: Token![as] = input.parse()?;
+ let path: Path = input.parse()?;
+ Some((as_token, path))
+ } else {
+ None
+ };
+ let gt_token: Token![>] = input.parse()?;
+ let colon2_token: Token![::] = input.parse()?;
+ let mut rest = Punctuated::new();
+ loop {
+ let path = PathSegment::parse_helper(input, expr_style)?;
+ rest.push_value(path);
+ if !input.peek(Token![::]) {
+ break;
+ }
+ let punct: Token![::] = input.parse()?;
+ rest.push_punct(punct);
+ }
+ let (position, as_token, path) = match path {
+ Some((as_token, mut path)) => {
+ let pos = path.segments.len();
+ path.segments.push_punct(colon2_token);
+ path.segments.extend(rest.into_pairs());
+ (pos, Some(as_token), path)
+ }
+ None => {
+ let path = Path {
+ leading_colon: Some(colon2_token),
+ segments: rest,
+ };
+ (0, None, path)
+ }
+ };
+ let qself = QSelf {
+ lt_token,
+ ty: Box::new(this),
+ position,
+ as_token,
+ gt_token,
+ };
+ Ok((Some(qself), path))
+ } else {
+ let path = Path::parse_helper(input, expr_style)?;
+ Ok((None, path))
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+pub(crate) mod printing {
+ use crate::generics;
+ use crate::path::{
+ AngleBracketedGenericArguments, AssocConst, AssocType, Constraint, GenericArgument,
+ ParenthesizedGenericArguments, Path, PathArguments, PathSegment, QSelf,
+ };
+ use crate::print::TokensOrDefault;
+ #[cfg(feature = "parsing")]
+ use crate::spanned::Spanned;
+ #[cfg(feature = "parsing")]
+ use proc_macro2::Span;
+ use proc_macro2::TokenStream;
+ use quote::ToTokens;
+ use std::cmp;
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Path {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.leading_colon.to_tokens(tokens);
+ self.segments.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PathSegment {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.ident.to_tokens(tokens);
+ self.arguments.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for PathArguments {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ PathArguments::None => {}
+ PathArguments::AngleBracketed(arguments) => {
+ arguments.to_tokens(tokens);
+ }
+ PathArguments::Parenthesized(arguments) => {
+ arguments.to_tokens(tokens);
+ }
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for GenericArgument {
+ #[allow(clippy::match_same_arms)]
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ GenericArgument::Lifetime(lt) => lt.to_tokens(tokens),
+ GenericArgument::Type(ty) => ty.to_tokens(tokens),
+ GenericArgument::Const(expr) => {
+ generics::printing::print_const_argument(expr, tokens);
+ }
+ GenericArgument::AssocType(assoc) => assoc.to_tokens(tokens),
+ GenericArgument::AssocConst(assoc) => assoc.to_tokens(tokens),
+ GenericArgument::Constraint(constraint) => constraint.to_tokens(tokens),
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for AngleBracketedGenericArguments {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.colon2_token.to_tokens(tokens);
+ self.lt_token.to_tokens(tokens);
+
+ // Print lifetimes before types/consts/bindings, regardless of their
+ // order in self.args.
+ let mut trailing_or_empty = true;
+ for param in self.args.pairs() {
+ match param.value() {
+ GenericArgument::Lifetime(_) => {
+ param.to_tokens(tokens);
+ trailing_or_empty = param.punct().is_some();
+ }
+ GenericArgument::Type(_)
+ | GenericArgument::Const(_)
+ | GenericArgument::AssocType(_)
+ | GenericArgument::AssocConst(_)
+ | GenericArgument::Constraint(_) => {}
+ }
+ }
+ for param in self.args.pairs() {
+ match param.value() {
+ GenericArgument::Type(_)
+ | GenericArgument::Const(_)
+ | GenericArgument::AssocType(_)
+ | GenericArgument::AssocConst(_)
+ | GenericArgument::Constraint(_) => {
+ if !trailing_or_empty {
+ <Token![,]>::default().to_tokens(tokens);
+ }
+ param.to_tokens(tokens);
+ trailing_or_empty = param.punct().is_some();
+ }
+ GenericArgument::Lifetime(_) => {}
+ }
+ }
+
+ self.gt_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for AssocType {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.eq_token.to_tokens(tokens);
+ self.ty.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for AssocConst {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.eq_token.to_tokens(tokens);
+ generics::printing::print_const_argument(&self.value, tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Constraint {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.ident.to_tokens(tokens);
+ self.generics.to_tokens(tokens);
+ self.colon_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ParenthesizedGenericArguments {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.paren_token.surround(tokens, |tokens| {
+ self.inputs.to_tokens(tokens);
+ });
+ self.output.to_tokens(tokens);
+ }
+ }
+
+ pub(crate) fn print_path(tokens: &mut TokenStream, qself: &Option<QSelf>, path: &Path) {
+ let qself = match qself {
+ Some(qself) => qself,
+ None => {
+ path.to_tokens(tokens);
+ return;
+ }
+ };
+ qself.lt_token.to_tokens(tokens);
+ qself.ty.to_tokens(tokens);
+
+ let pos = cmp::min(qself.position, path.segments.len());
+ let mut segments = path.segments.pairs();
+ if pos > 0 {
+ TokensOrDefault(&qself.as_token).to_tokens(tokens);
+ path.leading_colon.to_tokens(tokens);
+ for (i, segment) in segments.by_ref().take(pos).enumerate() {
+ if i + 1 == pos {
+ segment.value().to_tokens(tokens);
+ qself.gt_token.to_tokens(tokens);
+ segment.punct().to_tokens(tokens);
+ } else {
+ segment.to_tokens(tokens);
+ }
+ }
+ } else {
+ qself.gt_token.to_tokens(tokens);
+ path.leading_colon.to_tokens(tokens);
+ }
+ for segment in segments {
+ segment.to_tokens(tokens);
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ #[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "printing"))))]
+ impl Spanned for QSelf {
+ fn span(&self) -> Span {
+ struct QSelfDelimiters<'a>(&'a QSelf);
+
+ impl<'a> ToTokens for QSelfDelimiters<'a> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.0.lt_token.to_tokens(tokens);
+ self.0.gt_token.to_tokens(tokens);
+ }
+ }
+
+ QSelfDelimiters(self).span()
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/precedence.rs b/rust/hw/char/pl011/vendor/syn/src/precedence.rs
new file mode 100644
index 0000000000..450958ad34
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/precedence.rs
@@ -0,0 +1,163 @@
+#[cfg(feature = "printing")]
+use crate::expr::Expr;
+use crate::op::BinOp;
+#[cfg(all(feature = "printing", feature = "full"))]
+use crate::ty::ReturnType;
+use std::cmp::Ordering;
+
+// Reference: https://doc.rust-lang.org/reference/expressions.html#expression-precedence
+pub(crate) enum Precedence {
+ // return, break, closures
+ Any,
+ // = += -= *= /= %= &= |= ^= <<= >>=
+ Assign,
+ // .. ..=
+ Range,
+ // ||
+ Or,
+ // &&
+ And,
+ // == != < > <= >=
+ Compare,
+ // |
+ BitOr,
+ // ^
+ BitXor,
+ // &
+ BitAnd,
+ // << >>
+ Shift,
+ // + -
+ Arithmetic,
+ // * / %
+ Term,
+ // as
+ Cast,
+ // unary - * ! & &mut
+ #[cfg(feature = "printing")]
+ Prefix,
+ // function calls, array indexing, field expressions, method calls, ?
+ #[cfg(feature = "printing")]
+ Postfix,
+ // paths, loops
+ #[cfg(feature = "printing")]
+ Unambiguous,
+}
+
+impl Precedence {
+ pub(crate) fn of_binop(op: &BinOp) -> Self {
+ match op {
+ BinOp::Add(_) | BinOp::Sub(_) => Precedence::Arithmetic,
+ BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Term,
+ 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,
+ }
+ }
+
+ #[cfg(feature = "printing")]
+ pub(crate) fn of(e: &Expr) -> Self {
+ match e {
+ #[cfg(feature = "full")]
+ Expr::Closure(e) => match e.output {
+ ReturnType::Default => Precedence::Any,
+ ReturnType::Type(..) => Precedence::Unambiguous,
+ },
+
+ Expr::Break(_) | Expr::Return(_) | Expr::Yield(_) => Precedence::Any,
+ Expr::Assign(_) => Precedence::Assign,
+ Expr::Range(_) => Precedence::Range,
+ Expr::Binary(e) => Precedence::of_binop(&e.op),
+ Expr::Cast(_) => Precedence::Cast,
+ Expr::Let(_) | Expr::Reference(_) | Expr::Unary(_) => Precedence::Prefix,
+
+ Expr::Await(_)
+ | Expr::Call(_)
+ | Expr::MethodCall(_)
+ | Expr::Field(_)
+ | Expr::Index(_)
+ | Expr::Try(_) => Precedence::Postfix,
+
+ Expr::Array(_)
+ | Expr::Async(_)
+ | Expr::Block(_)
+ | Expr::Const(_)
+ | Expr::Continue(_)
+ | Expr::ForLoop(_)
+ | Expr::Group(_)
+ | Expr::If(_)
+ | Expr::Infer(_)
+ | Expr::Lit(_)
+ | Expr::Loop(_)
+ | Expr::Macro(_)
+ | Expr::Match(_)
+ | Expr::Paren(_)
+ | Expr::Path(_)
+ | Expr::Repeat(_)
+ | Expr::Struct(_)
+ | Expr::TryBlock(_)
+ | Expr::Tuple(_)
+ | Expr::Unsafe(_)
+ | Expr::Verbatim(_)
+ | Expr::While(_) => Precedence::Unambiguous,
+
+ #[cfg(not(feature = "full"))]
+ Expr::Closure(_) => unreachable!(),
+ }
+ }
+
+ #[cfg(feature = "printing")]
+ pub(crate) fn of_rhs(e: &Expr) -> Self {
+ match e {
+ Expr::Break(_) | Expr::Closure(_) | Expr::Return(_) | Expr::Yield(_) => {
+ Precedence::Prefix
+ }
+ #[cfg(feature = "full")]
+ Expr::Range(e) if e.start.is_none() => Precedence::Prefix,
+ _ => Precedence::of(e),
+ }
+ }
+}
+
+impl Copy for Precedence {}
+
+impl Clone for Precedence {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl PartialEq for Precedence {
+ fn eq(&self, other: &Self) -> bool {
+ *self as u8 == *other as u8
+ }
+}
+
+impl PartialOrd for Precedence {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ let this = *self as u8;
+ let other = *other as u8;
+ Some(this.cmp(&other))
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/print.rs b/rust/hw/char/pl011/vendor/syn/src/print.rs
new file mode 100644
index 0000000000..0740993267
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/print.rs
@@ -0,0 +1,16 @@
+use proc_macro2::TokenStream;
+use quote::ToTokens;
+
+pub(crate) struct TokensOrDefault<'a, T: 'a>(pub &'a Option<T>);
+
+impl<'a, T> ToTokens for TokensOrDefault<'a, T>
+where
+ T: ToTokens + Default,
+{
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self.0 {
+ Some(t) => t.to_tokens(tokens),
+ None => T::default().to_tokens(tokens),
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/punctuated.rs b/rust/hw/char/pl011/vendor/syn/src/punctuated.rs
new file mode 100644
index 0000000000..29e8dce15f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/punctuated.rs
@@ -0,0 +1,1132 @@
+//! A punctuated sequence of syntax tree nodes separated by punctuation.
+//!
+//! Lots of things in Rust are punctuated sequences.
+//!
+//! - The fields of a struct are `Punctuated<Field, Token![,]>`.
+//! - The segments of a path are `Punctuated<PathSegment, Token![::]>`.
+//! - The bounds on a generic parameter are `Punctuated<TypeParamBound,
+//! Token![+]>`.
+//! - The arguments to a function call are `Punctuated<Expr, Token![,]>`.
+//!
+//! This module provides a common representation for these punctuated sequences
+//! in the form of the [`Punctuated<T, P>`] type. We store a vector of pairs of
+//! syntax tree node + punctuation, where every node in the sequence is followed
+//! by punctuation except for possibly the final one.
+//!
+//! [`Punctuated<T, P>`]: Punctuated
+//!
+//! ```text
+//! a_function_call(arg1, arg2, arg3);
+//! ~~~~^ ~~~~^ ~~~~
+//! ```
+
+use crate::drops::{NoDrop, TrivialDrop};
+#[cfg(feature = "parsing")]
+use crate::error::Result;
+#[cfg(feature = "parsing")]
+use crate::parse::{Parse, ParseStream};
+#[cfg(feature = "parsing")]
+use crate::token::Token;
+#[cfg(feature = "extra-traits")]
+use std::fmt::{self, Debug};
+#[cfg(feature = "extra-traits")]
+use std::hash::{Hash, Hasher};
+#[cfg(any(feature = "full", feature = "derive"))]
+use std::iter;
+use std::ops::{Index, IndexMut};
+use std::option;
+use std::slice;
+use std::vec;
+
+/// **A punctuated sequence of syntax tree nodes of type `T` separated by
+/// punctuation of type `P`.**
+///
+/// Refer to the [module documentation] for details about punctuated sequences.
+///
+/// [module documentation]: self
+pub struct Punctuated<T, P> {
+ inner: Vec<(T, P)>,
+ last: Option<Box<T>>,
+}
+
+impl<T, P> Punctuated<T, P> {
+ /// Creates an empty punctuated sequence.
+ pub const fn new() -> Self {
+ Punctuated {
+ inner: Vec::new(),
+ last: None,
+ }
+ }
+
+ /// Determines whether this punctuated sequence is empty, meaning it
+ /// contains no syntax tree nodes or punctuation.
+ pub fn is_empty(&self) -> bool {
+ self.inner.len() == 0 && self.last.is_none()
+ }
+
+ /// Returns the number of syntax tree nodes in this punctuated sequence.
+ ///
+ /// This is the number of nodes of type `T`, not counting the punctuation of
+ /// type `P`.
+ pub fn len(&self) -> usize {
+ self.inner.len() + if self.last.is_some() { 1 } else { 0 }
+ }
+
+ /// Borrows the first element in this sequence.
+ pub fn first(&self) -> Option<&T> {
+ self.iter().next()
+ }
+
+ /// Mutably borrows the first element in this sequence.
+ pub fn first_mut(&mut self) -> Option<&mut T> {
+ self.iter_mut().next()
+ }
+
+ /// Borrows the last element in this sequence.
+ pub fn last(&self) -> Option<&T> {
+ self.iter().next_back()
+ }
+
+ /// Mutably borrows the last element in this sequence.
+ pub fn last_mut(&mut self) -> Option<&mut T> {
+ self.iter_mut().next_back()
+ }
+
+ /// Returns an iterator over borrowed syntax tree nodes of type `&T`.
+ pub fn iter(&self) -> Iter<T> {
+ Iter {
+ inner: Box::new(NoDrop::new(PrivateIter {
+ inner: self.inner.iter(),
+ last: self.last.as_ref().map(Box::as_ref).into_iter(),
+ })),
+ }
+ }
+
+ /// Returns an iterator over mutably borrowed syntax tree nodes of type
+ /// `&mut T`.
+ pub fn iter_mut(&mut self) -> IterMut<T> {
+ IterMut {
+ inner: Box::new(NoDrop::new(PrivateIterMut {
+ inner: self.inner.iter_mut(),
+ last: self.last.as_mut().map(Box::as_mut).into_iter(),
+ })),
+ }
+ }
+
+ /// Returns an iterator over the contents of this sequence as borrowed
+ /// punctuated pairs.
+ pub fn pairs(&self) -> Pairs<T, P> {
+ Pairs {
+ inner: self.inner.iter(),
+ last: self.last.as_ref().map(Box::as_ref).into_iter(),
+ }
+ }
+
+ /// Returns an iterator over the contents of this sequence as mutably
+ /// borrowed punctuated pairs.
+ pub fn pairs_mut(&mut self) -> PairsMut<T, P> {
+ PairsMut {
+ inner: self.inner.iter_mut(),
+ last: self.last.as_mut().map(Box::as_mut).into_iter(),
+ }
+ }
+
+ /// Returns an iterator over the contents of this sequence as owned
+ /// punctuated pairs.
+ pub fn into_pairs(self) -> IntoPairs<T, P> {
+ IntoPairs {
+ inner: self.inner.into_iter(),
+ last: self.last.map(|t| *t).into_iter(),
+ }
+ }
+
+ /// Appends a syntax tree node onto the end of this punctuated sequence. The
+ /// sequence must already have a trailing punctuation, or be empty.
+ ///
+ /// Use [`push`] instead if the punctuated sequence may or may not already
+ /// have trailing punctuation.
+ ///
+ /// [`push`]: Punctuated::push
+ ///
+ /// # Panics
+ ///
+ /// Panics if the sequence is nonempty and does not already have a trailing
+ /// punctuation.
+ pub fn push_value(&mut self, value: T) {
+ assert!(
+ self.empty_or_trailing(),
+ "Punctuated::push_value: cannot push value if Punctuated is missing trailing punctuation",
+ );
+
+ self.last = Some(Box::new(value));
+ }
+
+ /// Appends a trailing punctuation onto the end of this punctuated sequence.
+ /// The sequence must be non-empty and must not already have trailing
+ /// punctuation.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the sequence is empty or already has a trailing punctuation.
+ pub fn push_punct(&mut self, punctuation: P) {
+ assert!(
+ self.last.is_some(),
+ "Punctuated::push_punct: cannot push punctuation if Punctuated is empty or already has trailing punctuation",
+ );
+
+ let last = self.last.take().unwrap();
+ self.inner.push((*last, punctuation));
+ }
+
+ /// Removes the last punctuated pair from this sequence, or `None` if the
+ /// sequence is empty.
+ pub fn pop(&mut self) -> Option<Pair<T, P>> {
+ if self.last.is_some() {
+ self.last.take().map(|t| Pair::End(*t))
+ } else {
+ self.inner.pop().map(|(t, p)| Pair::Punctuated(t, p))
+ }
+ }
+
+ /// Removes the trailing punctuation from this punctuated sequence, or
+ /// `None` if there isn't any.
+ pub fn pop_punct(&mut self) -> Option<P> {
+ if self.last.is_some() {
+ None
+ } else {
+ let (t, p) = self.inner.pop()?;
+ self.last = Some(Box::new(t));
+ Some(p)
+ }
+ }
+
+ /// Determines whether this punctuated sequence ends with a trailing
+ /// punctuation.
+ pub fn trailing_punct(&self) -> bool {
+ self.last.is_none() && !self.is_empty()
+ }
+
+ /// Returns true if either this `Punctuated` is empty, or it has a trailing
+ /// punctuation.
+ ///
+ /// Equivalent to `punctuated.is_empty() || punctuated.trailing_punct()`.
+ pub fn empty_or_trailing(&self) -> bool {
+ self.last.is_none()
+ }
+
+ /// Appends a syntax tree node onto the end of this punctuated sequence.
+ ///
+ /// If there is not a trailing punctuation in this sequence when this method
+ /// is called, the default value of punctuation type `P` is inserted before
+ /// the given value of type `T`.
+ pub fn push(&mut self, value: T)
+ where
+ P: Default,
+ {
+ if !self.empty_or_trailing() {
+ self.push_punct(Default::default());
+ }
+ self.push_value(value);
+ }
+
+ /// Inserts an element at position `index`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `index` is greater than the number of elements previously in
+ /// this punctuated sequence.
+ pub fn insert(&mut self, index: usize, value: T)
+ where
+ P: Default,
+ {
+ assert!(
+ index <= self.len(),
+ "Punctuated::insert: index out of range",
+ );
+
+ if index == self.len() {
+ self.push(value);
+ } else {
+ self.inner.insert(index, (value, Default::default()));
+ }
+ }
+
+ /// Clears the sequence of all values and punctuation, making it empty.
+ pub fn clear(&mut self) {
+ self.inner.clear();
+ self.last = None;
+ }
+
+ /// Parses zero or more occurrences of `T` separated by punctuation of type
+ /// `P`, with optional trailing punctuation.
+ ///
+ /// Parsing continues until the end of this parse stream. The entire content
+ /// of this parse stream must consist of `T` and `P`.
+ #[cfg(feature = "parsing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn parse_terminated(input: ParseStream) -> Result<Self>
+ where
+ T: Parse,
+ P: Parse,
+ {
+ Self::parse_terminated_with(input, T::parse)
+ }
+
+ /// Parses zero or more occurrences of `T` using the given parse function,
+ /// separated by punctuation of type `P`, with optional trailing
+ /// punctuation.
+ ///
+ /// Like [`parse_terminated`], the entire content of this stream is expected
+ /// to be parsed.
+ ///
+ /// [`parse_terminated`]: Punctuated::parse_terminated
+ #[cfg(feature = "parsing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn parse_terminated_with(
+ input: ParseStream,
+ parser: fn(ParseStream) -> Result<T>,
+ ) -> Result<Self>
+ where
+ P: Parse,
+ {
+ let mut punctuated = Punctuated::new();
+
+ loop {
+ if input.is_empty() {
+ break;
+ }
+ let value = parser(input)?;
+ punctuated.push_value(value);
+ if input.is_empty() {
+ break;
+ }
+ let punct = input.parse()?;
+ punctuated.push_punct(punct);
+ }
+
+ Ok(punctuated)
+ }
+
+ /// Parses one or more occurrences of `T` separated by punctuation of type
+ /// `P`, not accepting trailing punctuation.
+ ///
+ /// Parsing continues as long as punctuation `P` is present at the head of
+ /// the stream. This method returns upon parsing a `T` and observing that it
+ /// is not followed by a `P`, even if there are remaining tokens in the
+ /// stream.
+ #[cfg(feature = "parsing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self>
+ where
+ T: Parse,
+ P: Token + Parse,
+ {
+ Self::parse_separated_nonempty_with(input, T::parse)
+ }
+
+ /// Parses one or more occurrences of `T` using the given parse function,
+ /// separated by punctuation of type `P`, not accepting trailing
+ /// punctuation.
+ ///
+ /// Like [`parse_separated_nonempty`], may complete early without parsing
+ /// the entire content of this stream.
+ ///
+ /// [`parse_separated_nonempty`]: Punctuated::parse_separated_nonempty
+ #[cfg(feature = "parsing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn parse_separated_nonempty_with(
+ input: ParseStream,
+ parser: fn(ParseStream) -> Result<T>,
+ ) -> Result<Self>
+ where
+ P: Token + Parse,
+ {
+ let mut punctuated = Punctuated::new();
+
+ loop {
+ let value = parser(input)?;
+ punctuated.push_value(value);
+ if !P::peek(input.cursor()) {
+ break;
+ }
+ let punct = input.parse()?;
+ punctuated.push_punct(punct);
+ }
+
+ Ok(punctuated)
+ }
+}
+
+#[cfg(feature = "clone-impls")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl<T, P> Clone for Punctuated<T, P>
+where
+ T: Clone,
+ P: Clone,
+{
+ fn clone(&self) -> Self {
+ Punctuated {
+ inner: self.inner.clone(),
+ last: self.last.clone(),
+ }
+ }
+
+ fn clone_from(&mut self, other: &Self) {
+ self.inner.clone_from(&other.inner);
+ self.last.clone_from(&other.last);
+ }
+}
+
+#[cfg(feature = "extra-traits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl<T, P> Eq for Punctuated<T, P>
+where
+ T: Eq,
+ P: Eq,
+{
+}
+
+#[cfg(feature = "extra-traits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl<T, P> PartialEq for Punctuated<T, P>
+where
+ T: PartialEq,
+ P: PartialEq,
+{
+ fn eq(&self, other: &Self) -> bool {
+ let Punctuated { inner, last } = self;
+ *inner == other.inner && *last == other.last
+ }
+}
+
+#[cfg(feature = "extra-traits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl<T, P> Hash for Punctuated<T, P>
+where
+ T: Hash,
+ P: Hash,
+{
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ let Punctuated { inner, last } = self;
+ inner.hash(state);
+ last.hash(state);
+ }
+}
+
+#[cfg(feature = "extra-traits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let mut list = f.debug_list();
+ for (t, p) in &self.inner {
+ list.entry(t);
+ list.entry(p);
+ }
+ if let Some(last) = &self.last {
+ list.entry(last);
+ }
+ list.finish()
+ }
+}
+
+impl<T, P> FromIterator<T> for Punctuated<T, P>
+where
+ P: Default,
+{
+ fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
+ let mut ret = Punctuated::new();
+ ret.extend(i);
+ ret
+ }
+}
+
+impl<T, P> Extend<T> for Punctuated<T, P>
+where
+ P: Default,
+{
+ fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
+ for value in i {
+ self.push(value);
+ }
+ }
+}
+
+impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
+ fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self {
+ let mut ret = Punctuated::new();
+ do_extend(&mut ret, i.into_iter());
+ ret
+ }
+}
+
+impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P>
+where
+ P: Default,
+{
+ fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) {
+ if !self.empty_or_trailing() {
+ self.push_punct(P::default());
+ }
+ do_extend(self, i.into_iter());
+ }
+}
+
+fn do_extend<T, P, I>(punctuated: &mut Punctuated<T, P>, i: I)
+where
+ I: Iterator<Item = Pair<T, P>>,
+{
+ let mut nomore = false;
+ for pair in i {
+ if nomore {
+ panic!("punctuated extended with items after a Pair::End");
+ }
+ match pair {
+ Pair::Punctuated(a, b) => punctuated.inner.push((a, b)),
+ Pair::End(a) => {
+ punctuated.last = Some(Box::new(a));
+ nomore = true;
+ }
+ }
+ }
+}
+
+impl<T, P> IntoIterator for Punctuated<T, P> {
+ type Item = T;
+ type IntoIter = IntoIter<T>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ let mut elements = Vec::with_capacity(self.len());
+ elements.extend(self.inner.into_iter().map(|pair| pair.0));
+ elements.extend(self.last.map(|t| *t));
+
+ IntoIter {
+ inner: elements.into_iter(),
+ }
+ }
+}
+
+impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
+ type Item = &'a T;
+ type IntoIter = Iter<'a, T>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ Punctuated::iter(self)
+ }
+}
+
+impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
+ type Item = &'a mut T;
+ type IntoIter = IterMut<'a, T>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ Punctuated::iter_mut(self)
+ }
+}
+
+impl<T, P> Default for Punctuated<T, P> {
+ fn default() -> Self {
+ Punctuated::new()
+ }
+}
+
+/// An iterator over borrowed pairs of type `Pair<&T, &P>`.
+///
+/// Refer to the [module documentation] for details about punctuated sequences.
+///
+/// [module documentation]: self
+pub struct Pairs<'a, T: 'a, P: 'a> {
+ inner: slice::Iter<'a, (T, P)>,
+ last: option::IntoIter<&'a T>,
+}
+
+impl<'a, T, P> Iterator for Pairs<'a, T, P> {
+ type Item = Pair<&'a T, &'a P>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner
+ .next()
+ .map(|(t, p)| Pair::Punctuated(t, p))
+ .or_else(|| self.last.next().map(Pair::End))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.len(), Some(self.len()))
+ }
+}
+
+impl<'a, T, P> DoubleEndedIterator for Pairs<'a, T, P> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.last
+ .next()
+ .map(Pair::End)
+ .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
+ }
+}
+
+impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> {
+ fn len(&self) -> usize {
+ self.inner.len() + self.last.len()
+ }
+}
+
+// No Clone bound on T or P.
+impl<'a, T, P> Clone for Pairs<'a, T, P> {
+ fn clone(&self) -> Self {
+ Pairs {
+ inner: self.inner.clone(),
+ last: self.last.clone(),
+ }
+ }
+}
+
+/// An iterator over mutably borrowed pairs of type `Pair<&mut T, &mut P>`.
+///
+/// Refer to the [module documentation] for details about punctuated sequences.
+///
+/// [module documentation]: self
+pub struct PairsMut<'a, T: 'a, P: 'a> {
+ inner: slice::IterMut<'a, (T, P)>,
+ last: option::IntoIter<&'a mut T>,
+}
+
+impl<'a, T, P> Iterator for PairsMut<'a, T, P> {
+ type Item = Pair<&'a mut T, &'a mut P>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner
+ .next()
+ .map(|(t, p)| Pair::Punctuated(t, p))
+ .or_else(|| self.last.next().map(Pair::End))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.len(), Some(self.len()))
+ }
+}
+
+impl<'a, T, P> DoubleEndedIterator for PairsMut<'a, T, P> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.last
+ .next()
+ .map(Pair::End)
+ .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
+ }
+}
+
+impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> {
+ fn len(&self) -> usize {
+ self.inner.len() + self.last.len()
+ }
+}
+
+/// An iterator over owned pairs of type `Pair<T, P>`.
+///
+/// Refer to the [module documentation] for details about punctuated sequences.
+///
+/// [module documentation]: self
+pub struct IntoPairs<T, P> {
+ inner: vec::IntoIter<(T, P)>,
+ last: option::IntoIter<T>,
+}
+
+impl<T, P> Iterator for IntoPairs<T, P> {
+ type Item = Pair<T, P>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner
+ .next()
+ .map(|(t, p)| Pair::Punctuated(t, p))
+ .or_else(|| self.last.next().map(Pair::End))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.len(), Some(self.len()))
+ }
+}
+
+impl<T, P> DoubleEndedIterator for IntoPairs<T, P> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.last
+ .next()
+ .map(Pair::End)
+ .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
+ }
+}
+
+impl<T, P> ExactSizeIterator for IntoPairs<T, P> {
+ fn len(&self) -> usize {
+ self.inner.len() + self.last.len()
+ }
+}
+
+impl<T, P> Clone for IntoPairs<T, P>
+where
+ T: Clone,
+ P: Clone,
+{
+ fn clone(&self) -> Self {
+ IntoPairs {
+ inner: self.inner.clone(),
+ last: self.last.clone(),
+ }
+ }
+}
+
+/// An iterator over owned values of type `T`.
+///
+/// Refer to the [module documentation] for details about punctuated sequences.
+///
+/// [module documentation]: self
+pub struct IntoIter<T> {
+ inner: vec::IntoIter<T>,
+}
+
+impl<T> Iterator for IntoIter<T> {
+ type Item = T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner.next()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.len(), Some(self.len()))
+ }
+}
+
+impl<T> DoubleEndedIterator for IntoIter<T> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.inner.next_back()
+ }
+}
+
+impl<T> ExactSizeIterator for IntoIter<T> {
+ fn len(&self) -> usize {
+ self.inner.len()
+ }
+}
+
+impl<T> Clone for IntoIter<T>
+where
+ T: Clone,
+{
+ fn clone(&self) -> Self {
+ IntoIter {
+ inner: self.inner.clone(),
+ }
+ }
+}
+
+/// An iterator over borrowed values of type `&T`.
+///
+/// Refer to the [module documentation] for details about punctuated sequences.
+///
+/// [module documentation]: self
+pub struct Iter<'a, T: 'a> {
+ inner: Box<NoDrop<dyn IterTrait<'a, T> + 'a>>,
+}
+
+trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> + DoubleEndedIterator + ExactSizeIterator {
+ fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T> + 'a>>;
+}
+
+struct PrivateIter<'a, T: 'a, P: 'a> {
+ inner: slice::Iter<'a, (T, P)>,
+ last: option::IntoIter<&'a T>,
+}
+
+impl<'a, T, P> TrivialDrop for PrivateIter<'a, T, P>
+where
+ slice::Iter<'a, (T, P)>: TrivialDrop,
+ option::IntoIter<&'a T>: TrivialDrop,
+{
+}
+
+#[cfg(any(feature = "full", feature = "derive"))]
+pub(crate) fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> {
+ Iter {
+ inner: Box::new(NoDrop::new(iter::empty())),
+ }
+}
+
+// No Clone bound on T.
+impl<'a, T> Clone for Iter<'a, T> {
+ fn clone(&self) -> Self {
+ Iter {
+ inner: self.inner.clone_box(),
+ }
+ }
+}
+
+impl<'a, T> Iterator for Iter<'a, T> {
+ type Item = &'a T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner.next()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.len(), Some(self.len()))
+ }
+}
+
+impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.inner.next_back()
+ }
+}
+
+impl<'a, T> ExactSizeIterator for Iter<'a, T> {
+ fn len(&self) -> usize {
+ self.inner.len()
+ }
+}
+
+impl<'a, T, P> Iterator for PrivateIter<'a, T, P> {
+ type Item = &'a T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner
+ .next()
+ .map(|pair| &pair.0)
+ .or_else(|| self.last.next())
+ }
+}
+
+impl<'a, T, P> DoubleEndedIterator for PrivateIter<'a, T, P> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.last
+ .next()
+ .or_else(|| self.inner.next_back().map(|pair| &pair.0))
+ }
+}
+
+impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> {
+ fn len(&self) -> usize {
+ self.inner.len() + self.last.len()
+ }
+}
+
+// No Clone bound on T or P.
+impl<'a, T, P> Clone for PrivateIter<'a, T, P> {
+ fn clone(&self) -> Self {
+ PrivateIter {
+ inner: self.inner.clone(),
+ last: self.last.clone(),
+ }
+ }
+}
+
+impl<'a, T, I> IterTrait<'a, T> for I
+where
+ T: 'a,
+ I: DoubleEndedIterator<Item = &'a T>
+ + ExactSizeIterator<Item = &'a T>
+ + Clone
+ + TrivialDrop
+ + 'a,
+{
+ fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T> + 'a>> {
+ Box::new(NoDrop::new(self.clone()))
+ }
+}
+
+/// An iterator over mutably borrowed values of type `&mut T`.
+///
+/// Refer to the [module documentation] for details about punctuated sequences.
+///
+/// [module documentation]: self
+pub struct IterMut<'a, T: 'a> {
+ inner: Box<NoDrop<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>>,
+}
+
+trait IterMutTrait<'a, T: 'a>:
+ DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
+{
+}
+
+struct PrivateIterMut<'a, T: 'a, P: 'a> {
+ inner: slice::IterMut<'a, (T, P)>,
+ last: option::IntoIter<&'a mut T>,
+}
+
+impl<'a, T, P> TrivialDrop for PrivateIterMut<'a, T, P>
+where
+ slice::IterMut<'a, (T, P)>: TrivialDrop,
+ option::IntoIter<&'a mut T>: TrivialDrop,
+{
+}
+
+#[cfg(any(feature = "full", feature = "derive"))]
+pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
+ IterMut {
+ inner: Box::new(NoDrop::new(iter::empty())),
+ }
+}
+
+impl<'a, T> Iterator for IterMut<'a, T> {
+ type Item = &'a mut T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner.next()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.len(), Some(self.len()))
+ }
+}
+
+impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.inner.next_back()
+ }
+}
+
+impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
+ fn len(&self) -> usize {
+ self.inner.len()
+ }
+}
+
+impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> {
+ type Item = &'a mut T;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner
+ .next()
+ .map(|pair| &mut pair.0)
+ .or_else(|| self.last.next())
+ }
+}
+
+impl<'a, T, P> DoubleEndedIterator for PrivateIterMut<'a, T, P> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.last
+ .next()
+ .or_else(|| self.inner.next_back().map(|pair| &mut pair.0))
+ }
+}
+
+impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> {
+ fn len(&self) -> usize {
+ self.inner.len() + self.last.len()
+ }
+}
+
+impl<'a, T, I> IterMutTrait<'a, T> for I
+where
+ T: 'a,
+ I: DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T> + 'a,
+{
+}
+
+/// A single syntax tree node of type `T` followed by its trailing punctuation
+/// of type `P` if any.
+///
+/// Refer to the [module documentation] for details about punctuated sequences.
+///
+/// [module documentation]: self
+pub enum Pair<T, P> {
+ Punctuated(T, P),
+ End(T),
+}
+
+impl<T, P> Pair<T, P> {
+ /// Extracts the syntax tree node from this punctuated pair, discarding the
+ /// following punctuation.
+ pub fn into_value(self) -> T {
+ match self {
+ Pair::Punctuated(t, _) | Pair::End(t) => t,
+ }
+ }
+
+ /// Borrows the syntax tree node from this punctuated pair.
+ pub fn value(&self) -> &T {
+ match self {
+ Pair::Punctuated(t, _) | Pair::End(t) => t,
+ }
+ }
+
+ /// Mutably borrows the syntax tree node from this punctuated pair.
+ pub fn value_mut(&mut self) -> &mut T {
+ match self {
+ Pair::Punctuated(t, _) | Pair::End(t) => t,
+ }
+ }
+
+ /// Borrows the punctuation from this punctuated pair, unless this pair is
+ /// the final one and there is no trailing punctuation.
+ pub fn punct(&self) -> Option<&P> {
+ match self {
+ Pair::Punctuated(_, p) => Some(p),
+ Pair::End(_) => None,
+ }
+ }
+
+ /// Mutably borrows the punctuation from this punctuated pair, unless the
+ /// pair is the final one and there is no trailing punctuation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// # use proc_macro2::Span;
+ /// # use syn::punctuated::Punctuated;
+ /// # use syn::{parse_quote, Token, TypeParamBound};
+ /// #
+ /// # let mut punctuated = Punctuated::<TypeParamBound, Token![+]>::new();
+ /// # let span = Span::call_site();
+ /// #
+ /// punctuated.insert(0, parse_quote!('lifetime));
+ /// if let Some(punct) = punctuated.pairs_mut().next().unwrap().punct_mut() {
+ /// punct.span = span;
+ /// }
+ /// ```
+ pub fn punct_mut(&mut self) -> Option<&mut P> {
+ match self {
+ Pair::Punctuated(_, p) => Some(p),
+ Pair::End(_) => None,
+ }
+ }
+
+ /// Creates a punctuated pair out of a syntax tree node and an optional
+ /// following punctuation.
+ pub fn new(t: T, p: Option<P>) -> Self {
+ match p {
+ Some(p) => Pair::Punctuated(t, p),
+ None => Pair::End(t),
+ }
+ }
+
+ /// Produces this punctuated pair as a tuple of syntax tree node and
+ /// optional following punctuation.
+ pub fn into_tuple(self) -> (T, Option<P>) {
+ match self {
+ Pair::Punctuated(t, p) => (t, Some(p)),
+ Pair::End(t) => (t, None),
+ }
+ }
+}
+
+#[cfg(feature = "clone-impls")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl<T, P> Pair<&T, &P> {
+ pub fn cloned(self) -> Pair<T, P>
+ where
+ T: Clone,
+ P: Clone,
+ {
+ match self {
+ Pair::Punctuated(t, p) => Pair::Punctuated(t.clone(), p.clone()),
+ Pair::End(t) => Pair::End(t.clone()),
+ }
+ }
+}
+
+#[cfg(feature = "clone-impls")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl<T, P> Clone for Pair<T, P>
+where
+ T: Clone,
+ P: Clone,
+{
+ fn clone(&self) -> Self {
+ match self {
+ Pair::Punctuated(t, p) => Pair::Punctuated(t.clone(), p.clone()),
+ Pair::End(t) => Pair::End(t.clone()),
+ }
+ }
+}
+
+#[cfg(feature = "clone-impls")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl<T, P> Copy for Pair<T, P>
+where
+ T: Copy,
+ P: Copy,
+{
+}
+
+impl<T, P> Index<usize> for Punctuated<T, P> {
+ type Output = T;
+
+ fn index(&self, index: usize) -> &Self::Output {
+ if index == self.len() - 1 {
+ match &self.last {
+ Some(t) => t,
+ None => &self.inner[index].0,
+ }
+ } else {
+ &self.inner[index].0
+ }
+ }
+}
+
+impl<T, P> IndexMut<usize> for Punctuated<T, P> {
+ fn index_mut(&mut self, index: usize) -> &mut Self::Output {
+ if index == self.len() - 1 {
+ match &mut self.last {
+ Some(t) => t,
+ None => &mut self.inner[index].0,
+ }
+ } else {
+ &mut self.inner[index].0
+ }
+ }
+}
+
+#[cfg(all(feature = "fold", any(feature = "full", feature = "derive")))]
+pub(crate) fn fold<T, P, V, F>(
+ punctuated: Punctuated<T, P>,
+ fold: &mut V,
+ mut f: F,
+) -> Punctuated<T, P>
+where
+ V: ?Sized,
+ F: FnMut(&mut V, T) -> T,
+{
+ Punctuated {
+ inner: punctuated
+ .inner
+ .into_iter()
+ .map(|(t, p)| (f(fold, t), p))
+ .collect(),
+ last: match punctuated.last {
+ Some(t) => Some(Box::new(f(fold, *t))),
+ None => None,
+ },
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use crate::punctuated::{Pair, Punctuated};
+ use proc_macro2::TokenStream;
+ use quote::{ToTokens, TokenStreamExt};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl<T, P> ToTokens for Punctuated<T, P>
+ where
+ T: ToTokens,
+ P: ToTokens,
+ {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.pairs());
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl<T, P> ToTokens for Pair<T, P>
+ where
+ T: ToTokens,
+ P: ToTokens,
+ {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ Pair::Punctuated(a, b) => {
+ a.to_tokens(tokens);
+ b.to_tokens(tokens);
+ }
+ Pair::End(a) => a.to_tokens(tokens),
+ }
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/restriction.rs b/rust/hw/char/pl011/vendor/syn/src/restriction.rs
new file mode 100644
index 0000000000..8a4d4706a5
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/restriction.rs
@@ -0,0 +1,176 @@
+use crate::path::Path;
+use crate::token;
+
+ast_enum! {
+ /// The visibility level of an item: inherited or `pub` or
+ /// `pub(restricted)`.
+ ///
+ /// # 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 Visibility {
+ /// A public visibility level: `pub`.
+ Public(Token![pub]),
+
+ /// A visibility level restricted to some path: `pub(self)` or
+ /// `pub(super)` or `pub(crate)` or `pub(in some::module)`.
+ Restricted(VisRestricted),
+
+ /// An inherited visibility, which usually means private.
+ Inherited,
+ }
+}
+
+ast_struct! {
+ /// A visibility level restricted to some path: `pub(self)` or
+ /// `pub(super)` or `pub(crate)` or `pub(in some::module)`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct VisRestricted {
+ pub pub_token: Token![pub],
+ pub paren_token: token::Paren,
+ pub in_token: Option<Token![in]>,
+ pub path: Box<Path>,
+ }
+}
+
+ast_enum! {
+ /// Unused, but reserved for RFC 3323 restrictions.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ #[non_exhaustive]
+ pub enum FieldMutability {
+ None,
+
+ // TODO: https://rust-lang.github.io/rfcs/3323-restrictions.html
+ //
+ // FieldMutability::Restricted(MutRestricted)
+ //
+ // pub struct MutRestricted {
+ // pub mut_token: Token![mut],
+ // pub paren_token: token::Paren,
+ // pub in_token: Option<Token![in]>,
+ // pub path: Box<Path>,
+ // }
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::error::Result;
+ use crate::ext::IdentExt as _;
+ use crate::ident::Ident;
+ use crate::parse::discouraged::Speculative as _;
+ use crate::parse::{Parse, ParseStream};
+ use crate::path::Path;
+ use crate::restriction::{VisRestricted, Visibility};
+ use crate::token;
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Visibility {
+ fn parse(input: ParseStream) -> Result<Self> {
+ // Recognize an empty None-delimited group, as produced by a $:vis
+ // matcher that matched no tokens.
+ if input.peek(token::Group) {
+ let ahead = input.fork();
+ let group = crate::group::parse_group(&ahead)?;
+ if group.content.is_empty() {
+ input.advance_to(&ahead);
+ return Ok(Visibility::Inherited);
+ }
+ }
+
+ if input.peek(Token![pub]) {
+ Self::parse_pub(input)
+ } else {
+ Ok(Visibility::Inherited)
+ }
+ }
+ }
+
+ impl Visibility {
+ fn parse_pub(input: ParseStream) -> Result<Self> {
+ let pub_token = input.parse::<Token![pub]>()?;
+
+ if input.peek(token::Paren) {
+ let ahead = input.fork();
+
+ let content;
+ let paren_token = parenthesized!(content in ahead);
+ if content.peek(Token![crate])
+ || content.peek(Token![self])
+ || content.peek(Token![super])
+ {
+ let path = content.call(Ident::parse_any)?;
+
+ // Ensure there are no additional tokens within `content`.
+ // Without explicitly checking, we may misinterpret a tuple
+ // field as a restricted visibility, causing a parse error.
+ // e.g. `pub (crate::A, crate::B)` (Issue #720).
+ if content.is_empty() {
+ input.advance_to(&ahead);
+ return Ok(Visibility::Restricted(VisRestricted {
+ pub_token,
+ paren_token,
+ in_token: None,
+ path: Box::new(Path::from(path)),
+ }));
+ }
+ } else if content.peek(Token![in]) {
+ let in_token: Token![in] = content.parse()?;
+ let path = content.call(Path::parse_mod_style)?;
+
+ input.advance_to(&ahead);
+ return Ok(Visibility::Restricted(VisRestricted {
+ pub_token,
+ paren_token,
+ in_token: Some(in_token),
+ path: Box::new(path),
+ }));
+ }
+ }
+
+ Ok(Visibility::Public(pub_token))
+ }
+
+ #[cfg(feature = "full")]
+ pub(crate) fn is_some(&self) -> bool {
+ match self {
+ Visibility::Inherited => false,
+ _ => true,
+ }
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use crate::restriction::{VisRestricted, Visibility};
+ use proc_macro2::TokenStream;
+ use quote::ToTokens;
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Visibility {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ Visibility::Public(pub_token) => pub_token.to_tokens(tokens),
+ Visibility::Restricted(vis_restricted) => vis_restricted.to_tokens(tokens),
+ Visibility::Inherited => {}
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for VisRestricted {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.pub_token.to_tokens(tokens);
+ self.paren_token.surround(tokens, |tokens| {
+ // TODO: If we have a path which is not "self" or "super" or
+ // "crate", automatically add the "in" token.
+ self.in_token.to_tokens(tokens);
+ self.path.to_tokens(tokens);
+ });
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/sealed.rs b/rust/hw/char/pl011/vendor/syn/src/sealed.rs
new file mode 100644
index 0000000000..dc804742d1
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/sealed.rs
@@ -0,0 +1,4 @@
+#[cfg(feature = "parsing")]
+pub(crate) mod lookahead {
+ pub trait Sealed: Copy {}
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/span.rs b/rust/hw/char/pl011/vendor/syn/src/span.rs
new file mode 100644
index 0000000000..eb2779479a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/span.rs
@@ -0,0 +1,63 @@
+use proc_macro2::extra::DelimSpan;
+use proc_macro2::{Delimiter, Group, Span, TokenStream};
+
+#[doc(hidden)]
+pub trait IntoSpans<S> {
+ fn into_spans(self) -> S;
+}
+
+impl IntoSpans<Span> for Span {
+ fn into_spans(self) -> Span {
+ self
+ }
+}
+
+impl IntoSpans<[Span; 1]> for Span {
+ fn into_spans(self) -> [Span; 1] {
+ [self]
+ }
+}
+
+impl IntoSpans<[Span; 2]> for Span {
+ fn into_spans(self) -> [Span; 2] {
+ [self, self]
+ }
+}
+
+impl IntoSpans<[Span; 3]> for Span {
+ fn into_spans(self) -> [Span; 3] {
+ [self, self, self]
+ }
+}
+
+impl IntoSpans<[Span; 1]> for [Span; 1] {
+ fn into_spans(self) -> [Span; 1] {
+ self
+ }
+}
+
+impl IntoSpans<[Span; 2]> for [Span; 2] {
+ fn into_spans(self) -> [Span; 2] {
+ self
+ }
+}
+
+impl IntoSpans<[Span; 3]> for [Span; 3] {
+ fn into_spans(self) -> [Span; 3] {
+ self
+ }
+}
+
+impl IntoSpans<DelimSpan> for Span {
+ fn into_spans(self) -> DelimSpan {
+ let mut group = Group::new(Delimiter::None, TokenStream::new());
+ group.set_span(self);
+ group.delim_span()
+ }
+}
+
+impl IntoSpans<DelimSpan> for DelimSpan {
+ fn into_spans(self) -> DelimSpan {
+ self
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/spanned.rs b/rust/hw/char/pl011/vendor/syn/src/spanned.rs
new file mode 100644
index 0000000000..17b69e9f5b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/spanned.rs
@@ -0,0 +1,118 @@
+//! A trait that can provide the `Span` of the complete contents of a syntax
+//! tree node.
+//!
+//! <br>
+//!
+//! # Example
+//!
+//! Suppose in a procedural macro we have a [`Type`] that we want to assert
+//! implements the [`Sync`] trait. Maybe this is the type of one of the fields
+//! of a struct for which we are deriving a trait implementation, and we need to
+//! be able to pass a reference to one of those fields across threads.
+//!
+//! [`Type`]: crate::Type
+//! [`Sync`]: std::marker::Sync
+//!
+//! If the field type does *not* implement `Sync` as required, we want the
+//! compiler to report an error pointing out exactly which type it was.
+//!
+//! The following macro code takes a variable `ty` of type `Type` and produces a
+//! static assertion that `Sync` is implemented for that type.
+//!
+//! ```
+//! # extern crate proc_macro;
+//! #
+//! use proc_macro::TokenStream;
+//! use proc_macro2::Span;
+//! use quote::quote_spanned;
+//! use syn::Type;
+//! use syn::spanned::Spanned;
+//!
+//! # const IGNORE_TOKENS: &str = stringify! {
+//! #[proc_macro_derive(MyMacro)]
+//! # };
+//! pub fn my_macro(input: TokenStream) -> TokenStream {
+//! # let ty = get_a_type();
+//! /* ... */
+//!
+//! let assert_sync = quote_spanned! {ty.span()=>
+//! struct _AssertSync where #ty: Sync;
+//! };
+//!
+//! /* ... */
+//! # input
+//! }
+//! #
+//! # fn get_a_type() -> Type {
+//! # unimplemented!()
+//! # }
+//! ```
+//!
+//! By inserting this `assert_sync` fragment into the output code generated by
+//! our macro, the user's code will fail to compile if `ty` does not implement
+//! `Sync`. The errors they would see look like the following.
+//!
+//! ```text
+//! error[E0277]: the trait bound `*const i32: std::marker::Sync` is not satisfied
+//! --> src/main.rs:10:21
+//! |
+//! 10 | bad_field: *const i32,
+//! | ^^^^^^^^^^ `*const i32` cannot be shared between threads safely
+//! ```
+//!
+//! In this technique, using the `Type`'s span for the error message makes the
+//! error appear in the correct place underlining the right type.
+//!
+//! <br>
+//!
+//! # Limitations
+//!
+//! The underlying [`proc_macro::Span::join`] method is nightly-only. When
+//! called from within a procedural macro in a nightly compiler, `Spanned` will
+//! use `join` to produce the intended span. When not using a nightly compiler,
+//! only the span of the *first token* of the syntax tree node is returned.
+//!
+//! In the common case of wanting to use the joined span as the span of a
+//! `syn::Error`, consider instead using [`syn::Error::new_spanned`] which is
+//! able to span the error correctly under the complete syntax tree node without
+//! needing the unstable `join`.
+//!
+//! [`syn::Error::new_spanned`]: crate::Error::new_spanned
+
+use proc_macro2::Span;
+use quote::spanned::Spanned as ToTokens;
+
+/// A trait that can provide the `Span` of the complete contents of a syntax
+/// tree node.
+///
+/// This trait is automatically implemented for all types that implement
+/// [`ToTokens`] from the `quote` crate, as well as for `Span` itself.
+///
+/// [`ToTokens`]: quote::ToTokens
+///
+/// See the [module documentation] for an example.
+///
+/// [module documentation]: self
+pub trait Spanned: private::Sealed {
+ /// Returns a `Span` covering the complete contents of this syntax tree
+ /// node, or [`Span::call_site()`] if this node is empty.
+ ///
+ /// [`Span::call_site()`]: proc_macro2::Span::call_site
+ fn span(&self) -> Span;
+}
+
+impl<T: ?Sized + ToTokens> Spanned for T {
+ fn span(&self) -> Span {
+ self.__span()
+ }
+}
+
+mod private {
+ use crate::spanned::ToTokens;
+
+ pub trait Sealed {}
+ impl<T: ?Sized + ToTokens> Sealed for T {}
+
+ #[cfg(any(feature = "full", feature = "derive"))]
+ impl Sealed for crate::QSelf {}
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/stmt.rs b/rust/hw/char/pl011/vendor/syn/src/stmt.rs
new file mode 100644
index 0000000000..51d000581a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/stmt.rs
@@ -0,0 +1,481 @@
+use crate::attr::Attribute;
+use crate::expr::Expr;
+use crate::item::Item;
+use crate::mac::Macro;
+use crate::pat::Pat;
+use crate::token;
+
+ast_struct! {
+ /// A braced block containing Rust statements.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct Block {
+ pub brace_token: token::Brace,
+ /// Statements in a block
+ pub stmts: Vec<Stmt>,
+ }
+}
+
+ast_enum! {
+ /// A statement, usually ending in a semicolon.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub enum Stmt {
+ /// A local (let) binding.
+ Local(Local),
+
+ /// An item definition.
+ Item(Item),
+
+ /// Expression, with or without trailing semicolon.
+ Expr(Expr, Option<Token![;]>),
+
+ /// A macro invocation in statement position.
+ ///
+ /// Syntactically it's ambiguous which other kind of statement this
+ /// macro would expand to. It can be any of local variable (`let`),
+ /// item, or expression.
+ Macro(StmtMacro),
+ }
+}
+
+ast_struct! {
+ /// A local `let` binding: `let x: u64 = s.parse()?`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct Local {
+ pub attrs: Vec<Attribute>,
+ pub let_token: Token![let],
+ pub pat: Pat,
+ pub init: Option<LocalInit>,
+ pub semi_token: Token![;],
+ }
+}
+
+ast_struct! {
+ /// The expression assigned in a local `let` binding, including optional
+ /// diverging `else` block.
+ ///
+ /// `LocalInit` represents `= s.parse()?` in `let x: u64 = s.parse()?` and
+ /// `= r else { return }` in `let Ok(x) = r else { return }`.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct LocalInit {
+ pub eq_token: Token![=],
+ pub expr: Box<Expr>,
+ pub diverge: Option<(Token![else], Box<Expr>)>,
+ }
+}
+
+ast_struct! {
+ /// A macro invocation in statement position.
+ ///
+ /// Syntactically it's ambiguous which other kind of statement this macro
+ /// would expand to. It can be any of local variable (`let`), item, or
+ /// expression.
+ #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
+ pub struct StmtMacro {
+ pub attrs: Vec<Attribute>,
+ pub mac: Macro,
+ pub semi_token: Option<Token![;]>,
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::attr::Attribute;
+ use crate::classify;
+ use crate::error::Result;
+ use crate::expr::{Expr, ExprBlock, ExprMacro};
+ use crate::ident::Ident;
+ use crate::item;
+ use crate::mac::{self, Macro};
+ use crate::parse::discouraged::Speculative as _;
+ use crate::parse::{Parse, ParseStream};
+ use crate::pat::{Pat, PatType};
+ use crate::path::Path;
+ use crate::stmt::{Block, Local, LocalInit, Stmt, StmtMacro};
+ use crate::token;
+ use crate::ty::Type;
+ use proc_macro2::TokenStream;
+
+ struct AllowNoSemi(bool);
+
+ impl Block {
+ /// Parse the body of a block as zero or more statements, possibly
+ /// including one trailing expression.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use syn::{braced, token, Attribute, Block, Ident, Result, Stmt, Token};
+ /// use syn::parse::{Parse, ParseStream};
+ ///
+ /// // Parse a function with no generics or parameter list.
+ /// //
+ /// // fn playground {
+ /// // let mut x = 1;
+ /// // x += 1;
+ /// // println!("{}", x);
+ /// // }
+ /// struct MiniFunction {
+ /// attrs: Vec<Attribute>,
+ /// fn_token: Token![fn],
+ /// name: Ident,
+ /// brace_token: token::Brace,
+ /// stmts: Vec<Stmt>,
+ /// }
+ ///
+ /// impl Parse for MiniFunction {
+ /// fn parse(input: ParseStream) -> Result<Self> {
+ /// let outer_attrs = input.call(Attribute::parse_outer)?;
+ /// let fn_token: Token![fn] = input.parse()?;
+ /// let name: Ident = input.parse()?;
+ ///
+ /// let content;
+ /// let brace_token = braced!(content in input);
+ /// let inner_attrs = content.call(Attribute::parse_inner)?;
+ /// let stmts = content.call(Block::parse_within)?;
+ ///
+ /// Ok(MiniFunction {
+ /// attrs: {
+ /// let mut attrs = outer_attrs;
+ /// attrs.extend(inner_attrs);
+ /// attrs
+ /// },
+ /// fn_token,
+ /// name,
+ /// brace_token,
+ /// stmts,
+ /// })
+ /// }
+ /// }
+ /// ```
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn parse_within(input: ParseStream) -> Result<Vec<Stmt>> {
+ let mut stmts = Vec::new();
+ loop {
+ while let semi @ Some(_) = input.parse()? {
+ stmts.push(Stmt::Expr(Expr::Verbatim(TokenStream::new()), semi));
+ }
+ if input.is_empty() {
+ break;
+ }
+ let stmt = parse_stmt(input, AllowNoSemi(true))?;
+ let requires_semicolon = match &stmt {
+ Stmt::Expr(stmt, None) => classify::requires_semi_to_be_stmt(stmt),
+ Stmt::Macro(stmt) => {
+ stmt.semi_token.is_none() && !stmt.mac.delimiter.is_brace()
+ }
+ Stmt::Local(_) | Stmt::Item(_) | Stmt::Expr(_, Some(_)) => false,
+ };
+ stmts.push(stmt);
+ if input.is_empty() {
+ break;
+ } else if requires_semicolon {
+ return Err(input.error("unexpected token, expected `;`"));
+ }
+ }
+ Ok(stmts)
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Block {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(Block {
+ brace_token: braced!(content in input),
+ stmts: content.call(Block::parse_within)?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Stmt {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_nosemi = AllowNoSemi(false);
+ parse_stmt(input, allow_nosemi)
+ }
+ }
+
+ fn parse_stmt(input: ParseStream, allow_nosemi: AllowNoSemi) -> Result<Stmt> {
+ let begin = input.fork();
+ let attrs = input.call(Attribute::parse_outer)?;
+
+ // brace-style macros; paren and bracket macros get parsed as
+ // expression statements.
+ let ahead = input.fork();
+ let mut is_item_macro = false;
+ if let Ok(path) = ahead.call(Path::parse_mod_style) {
+ if ahead.peek(Token![!]) {
+ if ahead.peek2(Ident) || ahead.peek2(Token![try]) {
+ is_item_macro = true;
+ } else if ahead.peek2(token::Brace)
+ && !(ahead.peek3(Token![.]) || ahead.peek3(Token![?]))
+ {
+ input.advance_to(&ahead);
+ return stmt_mac(input, attrs, path).map(Stmt::Macro);
+ }
+ }
+ }
+
+ if input.peek(Token![let]) && !input.peek(token::Group) {
+ stmt_local(input, attrs).map(Stmt::Local)
+ } else if input.peek(Token![pub])
+ || input.peek(Token![crate]) && !input.peek2(Token![::])
+ || input.peek(Token![extern])
+ || input.peek(Token![use])
+ || input.peek(Token![static])
+ && (input.peek2(Token![mut])
+ || input.peek2(Ident)
+ && !(input.peek2(Token![async])
+ && (input.peek3(Token![move]) || input.peek3(Token![|]))))
+ || input.peek(Token![const])
+ && !(input.peek2(token::Brace)
+ || input.peek2(Token![static])
+ || input.peek2(Token![async])
+ && !(input.peek3(Token![unsafe])
+ || input.peek3(Token![extern])
+ || input.peek3(Token![fn]))
+ || input.peek2(Token![move])
+ || input.peek2(Token![|]))
+ || input.peek(Token![unsafe]) && !input.peek2(token::Brace)
+ || input.peek(Token![async])
+ && (input.peek2(Token![unsafe])
+ || input.peek2(Token![extern])
+ || input.peek2(Token![fn]))
+ || input.peek(Token![fn])
+ || input.peek(Token![mod])
+ || input.peek(Token![type])
+ || input.peek(Token![struct])
+ || input.peek(Token![enum])
+ || input.peek(Token![union]) && input.peek2(Ident)
+ || input.peek(Token![auto]) && input.peek2(Token![trait])
+ || input.peek(Token![trait])
+ || input.peek(Token![default])
+ && (input.peek2(Token![unsafe]) || input.peek2(Token![impl]))
+ || input.peek(Token![impl])
+ || input.peek(Token![macro])
+ || is_item_macro
+ {
+ let item = item::parsing::parse_rest_of_item(begin, attrs, input)?;
+ Ok(Stmt::Item(item))
+ } else {
+ stmt_expr(input, allow_nosemi, attrs)
+ }
+ }
+
+ fn stmt_mac(input: ParseStream, attrs: Vec<Attribute>, path: Path) -> Result<StmtMacro> {
+ let bang_token: Token![!] = input.parse()?;
+ let (delimiter, tokens) = mac::parse_delimiter(input)?;
+ let semi_token: Option<Token![;]> = input.parse()?;
+
+ Ok(StmtMacro {
+ attrs,
+ mac: Macro {
+ path,
+ bang_token,
+ delimiter,
+ tokens,
+ },
+ semi_token,
+ })
+ }
+
+ fn stmt_local(input: ParseStream, attrs: Vec<Attribute>) -> Result<Local> {
+ let let_token: Token![let] = input.parse()?;
+
+ let mut pat = Pat::parse_single(input)?;
+ if input.peek(Token![:]) {
+ let colon_token: Token![:] = input.parse()?;
+ let ty: Type = input.parse()?;
+ pat = Pat::Type(PatType {
+ attrs: Vec::new(),
+ pat: Box::new(pat),
+ colon_token,
+ ty: Box::new(ty),
+ });
+ }
+
+ let init = if let Some(eq_token) = input.parse()? {
+ let eq_token: Token![=] = eq_token;
+ let expr: Expr = input.parse()?;
+
+ let diverge = if !classify::expr_trailing_brace(&expr) && input.peek(Token![else]) {
+ let else_token: Token![else] = input.parse()?;
+ let diverge = ExprBlock {
+ attrs: Vec::new(),
+ label: None,
+ block: input.parse()?,
+ };
+ Some((else_token, Box::new(Expr::Block(diverge))))
+ } else {
+ None
+ };
+
+ Some(LocalInit {
+ eq_token,
+ expr: Box::new(expr),
+ diverge,
+ })
+ } else {
+ None
+ };
+
+ let semi_token: Token![;] = input.parse()?;
+
+ Ok(Local {
+ attrs,
+ let_token,
+ pat,
+ init,
+ semi_token,
+ })
+ }
+
+ fn stmt_expr(
+ input: ParseStream,
+ allow_nosemi: AllowNoSemi,
+ mut attrs: Vec<Attribute>,
+ ) -> Result<Stmt> {
+ let mut e = Expr::parse_with_earlier_boundary_rule(input)?;
+
+ let mut attr_target = &mut e;
+ loop {
+ attr_target = match attr_target {
+ Expr::Assign(e) => &mut e.left,
+ Expr::Binary(e) => &mut e.left,
+ Expr::Cast(e) => &mut e.expr,
+ Expr::Array(_)
+ | Expr::Async(_)
+ | Expr::Await(_)
+ | Expr::Block(_)
+ | Expr::Break(_)
+ | Expr::Call(_)
+ | Expr::Closure(_)
+ | Expr::Const(_)
+ | Expr::Continue(_)
+ | Expr::Field(_)
+ | Expr::ForLoop(_)
+ | Expr::Group(_)
+ | Expr::If(_)
+ | Expr::Index(_)
+ | Expr::Infer(_)
+ | Expr::Let(_)
+ | Expr::Lit(_)
+ | Expr::Loop(_)
+ | Expr::Macro(_)
+ | Expr::Match(_)
+ | Expr::MethodCall(_)
+ | Expr::Paren(_)
+ | Expr::Path(_)
+ | Expr::Range(_)
+ | Expr::Reference(_)
+ | Expr::Repeat(_)
+ | Expr::Return(_)
+ | Expr::Struct(_)
+ | Expr::Try(_)
+ | Expr::TryBlock(_)
+ | Expr::Tuple(_)
+ | Expr::Unary(_)
+ | Expr::Unsafe(_)
+ | Expr::While(_)
+ | Expr::Yield(_)
+ | Expr::Verbatim(_) => break,
+ };
+ }
+ attrs.extend(attr_target.replace_attrs(Vec::new()));
+ attr_target.replace_attrs(attrs);
+
+ let semi_token: Option<Token![;]> = input.parse()?;
+
+ match e {
+ Expr::Macro(ExprMacro { attrs, mac })
+ if semi_token.is_some() || mac.delimiter.is_brace() =>
+ {
+ return Ok(Stmt::Macro(StmtMacro {
+ attrs,
+ mac,
+ semi_token,
+ }));
+ }
+ _ => {}
+ }
+
+ if semi_token.is_some() {
+ Ok(Stmt::Expr(e, semi_token))
+ } else if allow_nosemi.0 || !classify::requires_semi_to_be_stmt(&e) {
+ Ok(Stmt::Expr(e, None))
+ } else {
+ Err(input.error("expected semicolon"))
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+pub(crate) mod printing {
+ use crate::classify;
+ use crate::expr::{self, Expr};
+ use crate::fixup::FixupContext;
+ use crate::stmt::{Block, Local, Stmt, StmtMacro};
+ use crate::token;
+ use proc_macro2::TokenStream;
+ use quote::{ToTokens, TokenStreamExt};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Block {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.brace_token.surround(tokens, |tokens| {
+ tokens.append_all(&self.stmts);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Stmt {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ Stmt::Local(local) => local.to_tokens(tokens),
+ Stmt::Item(item) => item.to_tokens(tokens),
+ Stmt::Expr(expr, semi) => {
+ expr::printing::print_expr(expr, tokens, FixupContext::new_stmt());
+ semi.to_tokens(tokens);
+ }
+ Stmt::Macro(mac) => mac.to_tokens(tokens),
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Local {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ expr::printing::outer_attrs_to_tokens(&self.attrs, tokens);
+ self.let_token.to_tokens(tokens);
+ self.pat.to_tokens(tokens);
+ if let Some(init) = &self.init {
+ init.eq_token.to_tokens(tokens);
+ if init.diverge.is_some() && classify::expr_trailing_brace(&init.expr) {
+ token::Paren::default().surround(tokens, |tokens| init.expr.to_tokens(tokens));
+ } else {
+ init.expr.to_tokens(tokens);
+ }
+ if let Some((else_token, diverge)) = &init.diverge {
+ else_token.to_tokens(tokens);
+ match &**diverge {
+ Expr::Block(diverge) => diverge.to_tokens(tokens),
+ _ => token::Brace::default().surround(tokens, |tokens| {
+ expr::printing::print_expr(diverge, tokens, FixupContext::new_stmt());
+ }),
+ }
+ }
+ }
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for StmtMacro {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ expr::printing::outer_attrs_to_tokens(&self.attrs, tokens);
+ self.mac.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/thread.rs b/rust/hw/char/pl011/vendor/syn/src/thread.rs
new file mode 100644
index 0000000000..b33d248afc
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/thread.rs
@@ -0,0 +1,60 @@
+use std::fmt::{self, Debug};
+use std::thread::{self, ThreadId};
+
+/// ThreadBound is a Sync-maker and Send-maker that allows accessing a value
+/// of type T only from the original thread on which the ThreadBound was
+/// constructed.
+pub(crate) struct ThreadBound<T> {
+ value: T,
+ thread_id: ThreadId,
+}
+
+unsafe impl<T> Sync for ThreadBound<T> {}
+
+// Send bound requires Copy, as otherwise Drop could run in the wrong place.
+//
+// Today Copy and Drop are mutually exclusive so `T: Copy` implies `T: !Drop`.
+// This impl needs to be revisited if that restriction is relaxed in the future.
+unsafe impl<T: Copy> Send for ThreadBound<T> {}
+
+impl<T> ThreadBound<T> {
+ pub(crate) fn new(value: T) -> Self {
+ ThreadBound {
+ value,
+ thread_id: thread::current().id(),
+ }
+ }
+
+ pub(crate) fn get(&self) -> Option<&T> {
+ if thread::current().id() == self.thread_id {
+ Some(&self.value)
+ } else {
+ None
+ }
+ }
+}
+
+impl<T: Debug> Debug for ThreadBound<T> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self.get() {
+ Some(value) => Debug::fmt(value, formatter),
+ None => formatter.write_str("unknown"),
+ }
+ }
+}
+
+// Copy the bytes of T, even if the currently running thread is the "wrong"
+// thread. This is fine as long as the original thread is not simultaneously
+// mutating this value via interior mutability, which would be a data race.
+//
+// Currently `T: Copy` is sufficient to guarantee that T contains no interior
+// mutability, because _all_ interior mutability in Rust is built on
+// std::cell::UnsafeCell, which has no Copy impl. This impl needs to be
+// revisited if that restriction is relaxed in the future.
+impl<T: Copy> Copy for ThreadBound<T> {}
+
+impl<T: Copy> Clone for ThreadBound<T> {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/token.rs b/rust/hw/char/pl011/vendor/syn/src/token.rs
new file mode 100644
index 0000000000..e04f105747
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/token.rs
@@ -0,0 +1,1138 @@
+//! Tokens representing Rust punctuation, keywords, and delimiters.
+//!
+//! The type names in this module can be difficult to keep straight, so we
+//! prefer to use the [`Token!`] macro instead. This is a type-macro that
+//! expands to the token type of the given token.
+//!
+//! [`Token!`]: crate::Token
+//!
+//! # Example
+//!
+//! The [`ItemStatic`] syntax tree node is defined like this.
+//!
+//! [`ItemStatic`]: crate::ItemStatic
+//!
+//! ```
+//! # use syn::{Attribute, Expr, Ident, Token, Type, Visibility};
+//! #
+//! pub struct ItemStatic {
+//! pub attrs: Vec<Attribute>,
+//! pub vis: Visibility,
+//! pub static_token: Token![static],
+//! pub mutability: Option<Token![mut]>,
+//! pub ident: Ident,
+//! pub colon_token: Token![:],
+//! pub ty: Box<Type>,
+//! pub eq_token: Token![=],
+//! pub expr: Box<Expr>,
+//! pub semi_token: Token![;],
+//! }
+//! ```
+//!
+//! # Parsing
+//!
+//! Keywords and punctuation can be parsed through the [`ParseStream::parse`]
+//! method. Delimiter tokens are parsed using the [`parenthesized!`],
+//! [`bracketed!`] and [`braced!`] macros.
+//!
+//! [`ParseStream::parse`]: crate::parse::ParseBuffer::parse()
+//! [`parenthesized!`]: crate::parenthesized!
+//! [`bracketed!`]: crate::bracketed!
+//! [`braced!`]: crate::braced!
+//!
+//! ```
+//! use syn::{Attribute, Result};
+//! use syn::parse::{Parse, ParseStream};
+//! #
+//! # enum ItemStatic {}
+//!
+//! // Parse the ItemStatic struct shown above.
+//! impl Parse for ItemStatic {
+//! fn parse(input: ParseStream) -> Result<Self> {
+//! # use syn::ItemStatic;
+//! # fn parse(input: ParseStream) -> Result<ItemStatic> {
+//! Ok(ItemStatic {
+//! attrs: input.call(Attribute::parse_outer)?,
+//! vis: input.parse()?,
+//! static_token: input.parse()?,
+//! mutability: input.parse()?,
+//! ident: input.parse()?,
+//! colon_token: input.parse()?,
+//! ty: input.parse()?,
+//! eq_token: input.parse()?,
+//! expr: input.parse()?,
+//! semi_token: input.parse()?,
+//! })
+//! # }
+//! # unimplemented!()
+//! }
+//! }
+//! ```
+//!
+//! # Other operations
+//!
+//! Every keyword and punctuation token supports the following operations.
+//!
+//! - [Peeking] — `input.peek(Token![...])`
+//!
+//! - [Parsing] — `input.parse::<Token![...]>()?`
+//!
+//! - [Printing] — `quote!( ... #the_token ... )`
+//!
+//! - Construction from a [`Span`] — `let the_token = Token`
+//!
+//! - Field access to its span — `let sp = the_token.span`
+//!
+//! [Peeking]: crate::parse::ParseBuffer::peek()
+//! [Parsing]: crate::parse::ParseBuffer::parse()
+//! [Printing]: https://docs.rs/quote/1.0/quote/trait.ToTokens.html
+//! [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html
+
+#[cfg(feature = "parsing")]
+pub(crate) use self::private::CustomToken;
+use self::private::WithSpan;
+#[cfg(feature = "parsing")]
+use crate::buffer::Cursor;
+#[cfg(feature = "parsing")]
+use crate::error::Result;
+#[cfg(feature = "parsing")]
+use crate::lifetime::Lifetime;
+#[cfg(feature = "parsing")]
+use crate::lit::{Lit, LitBool, LitByte, LitByteStr, LitChar, LitFloat, LitInt, LitStr};
+#[cfg(feature = "parsing")]
+use crate::lookahead;
+#[cfg(feature = "parsing")]
+use crate::parse::{Parse, ParseStream};
+use crate::span::IntoSpans;
+use proc_macro2::extra::DelimSpan;
+use proc_macro2::Span;
+#[cfg(feature = "printing")]
+use proc_macro2::TokenStream;
+#[cfg(any(feature = "parsing", feature = "printing"))]
+use proc_macro2::{Delimiter, Ident};
+#[cfg(feature = "parsing")]
+use proc_macro2::{Literal, Punct, TokenTree};
+#[cfg(feature = "printing")]
+use quote::{ToTokens, TokenStreamExt};
+#[cfg(feature = "extra-traits")]
+use std::cmp;
+#[cfg(feature = "extra-traits")]
+use std::fmt::{self, Debug};
+#[cfg(feature = "extra-traits")]
+use std::hash::{Hash, Hasher};
+use std::ops::{Deref, DerefMut};
+
+/// Marker trait for types that represent single tokens.
+///
+/// This trait is sealed and cannot be implemented for types outside of Syn.
+#[cfg(feature = "parsing")]
+pub trait Token: private::Sealed {
+ // Not public API.
+ #[doc(hidden)]
+ fn peek(cursor: Cursor) -> bool;
+
+ // Not public API.
+ #[doc(hidden)]
+ fn display() -> &'static str;
+}
+
+pub(crate) mod private {
+ #[cfg(feature = "parsing")]
+ use crate::buffer::Cursor;
+ use proc_macro2::Span;
+
+ #[cfg(feature = "parsing")]
+ pub trait Sealed {}
+
+ /// Support writing `token.span` rather than `token.spans[0]` on tokens that
+ /// hold a single span.
+ #[repr(transparent)]
+ #[allow(unknown_lints, repr_transparent_external_private_fields)] // False positive: https://github.com/rust-lang/rust/issues/78586#issuecomment-1722680482
+ pub struct WithSpan {
+ pub span: Span,
+ }
+
+ // Not public API.
+ #[doc(hidden)]
+ #[cfg(feature = "parsing")]
+ pub trait CustomToken {
+ fn peek(cursor: Cursor) -> bool;
+ fn display() -> &'static str;
+ }
+}
+
+#[cfg(feature = "parsing")]
+impl private::Sealed for Ident {}
+
+#[cfg(feature = "parsing")]
+fn peek_impl(cursor: Cursor, peek: fn(ParseStream) -> bool) -> bool {
+ use crate::parse::Unexpected;
+ use std::cell::Cell;
+ use std::rc::Rc;
+
+ let scope = Span::call_site();
+ let unexpected = Rc::new(Cell::new(Unexpected::None));
+ let buffer = crate::parse::new_parse_buffer(scope, cursor, unexpected);
+ peek(&buffer)
+}
+
+macro_rules! impl_token {
+ ($display:literal $name:ty) => {
+ #[cfg(feature = "parsing")]
+ impl Token for $name {
+ fn peek(cursor: Cursor) -> bool {
+ fn peek(input: ParseStream) -> bool {
+ <$name as Parse>::parse(input).is_ok()
+ }
+ peek_impl(cursor, peek)
+ }
+
+ fn display() -> &'static str {
+ $display
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ impl private::Sealed for $name {}
+ };
+}
+
+impl_token!("lifetime" Lifetime);
+impl_token!("literal" Lit);
+impl_token!("string literal" LitStr);
+impl_token!("byte string literal" LitByteStr);
+impl_token!("byte literal" LitByte);
+impl_token!("character literal" LitChar);
+impl_token!("integer literal" LitInt);
+impl_token!("floating point literal" LitFloat);
+impl_token!("boolean literal" LitBool);
+impl_token!("group token" proc_macro2::Group);
+
+macro_rules! impl_low_level_token {
+ ($display:literal $ty:ident $get:ident) => {
+ #[cfg(feature = "parsing")]
+ impl Token for $ty {
+ fn peek(cursor: Cursor) -> bool {
+ cursor.$get().is_some()
+ }
+
+ fn display() -> &'static str {
+ $display
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ impl private::Sealed for $ty {}
+ };
+}
+
+impl_low_level_token!("punctuation token" Punct punct);
+impl_low_level_token!("literal" Literal literal);
+impl_low_level_token!("token" TokenTree token_tree);
+
+#[cfg(feature = "parsing")]
+impl<T: CustomToken> private::Sealed for T {}
+
+#[cfg(feature = "parsing")]
+impl<T: CustomToken> Token for T {
+ fn peek(cursor: Cursor) -> bool {
+ <Self as CustomToken>::peek(cursor)
+ }
+
+ fn display() -> &'static str {
+ <Self as CustomToken>::display()
+ }
+}
+
+macro_rules! define_keywords {
+ ($($token:literal pub struct $name:ident)*) => {
+ $(
+ #[doc = concat!('`', $token, '`')]
+ ///
+ /// Don't try to remember the name of this type — use the
+ /// [`Token!`] macro instead.
+ ///
+ /// [`Token!`]: crate::token
+ pub struct $name {
+ pub span: Span,
+ }
+
+ #[doc(hidden)]
+ #[allow(non_snake_case)]
+ pub fn $name<S: IntoSpans<Span>>(span: S) -> $name {
+ $name {
+ span: span.into_spans(),
+ }
+ }
+
+ impl std::default::Default for $name {
+ fn default() -> Self {
+ $name {
+ span: Span::call_site(),
+ }
+ }
+ }
+
+ #[cfg(feature = "clone-impls")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+ impl Copy for $name {}
+
+ #[cfg(feature = "clone-impls")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+ impl Clone for $name {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Debug for $name {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(stringify!($name))
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl cmp::Eq for $name {}
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl PartialEq for $name {
+ fn eq(&self, _other: &$name) -> bool {
+ true
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Hash for $name {
+ fn hash<H: Hasher>(&self, _state: &mut H) {}
+ }
+
+ #[cfg(feature = "printing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for $name {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ printing::keyword($token, self.span, tokens);
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for $name {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok($name {
+ span: parsing::keyword(input, $token)?,
+ })
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ impl Token for $name {
+ fn peek(cursor: Cursor) -> bool {
+ parsing::peek_keyword(cursor, $token)
+ }
+
+ fn display() -> &'static str {
+ concat!("`", $token, "`")
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ impl private::Sealed for $name {}
+ )*
+ };
+}
+
+macro_rules! impl_deref_if_len_is_1 {
+ ($name:ident/1) => {
+ impl Deref for $name {
+ type Target = WithSpan;
+
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*(self as *const Self).cast::<WithSpan>() }
+ }
+ }
+
+ impl DerefMut for $name {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ unsafe { &mut *(self as *mut Self).cast::<WithSpan>() }
+ }
+ }
+ };
+
+ ($name:ident/$len:literal) => {};
+}
+
+macro_rules! define_punctuation_structs {
+ ($($token:literal pub struct $name:ident/$len:tt #[doc = $usage:literal])*) => {
+ $(
+ #[cfg_attr(not(doc), repr(transparent))]
+ #[allow(unknown_lints, repr_transparent_external_private_fields)] // False positive: https://github.com/rust-lang/rust/issues/78586#issuecomment-1722680482
+ #[doc = concat!('`', $token, '`')]
+ ///
+ /// Usage:
+ #[doc = concat!($usage, '.')]
+ ///
+ /// Don't try to remember the name of this type — use the
+ /// [`Token!`] macro instead.
+ ///
+ /// [`Token!`]: crate::token
+ pub struct $name {
+ pub spans: [Span; $len],
+ }
+
+ #[doc(hidden)]
+ #[allow(non_snake_case)]
+ pub fn $name<S: IntoSpans<[Span; $len]>>(spans: S) -> $name {
+ $name {
+ spans: spans.into_spans(),
+ }
+ }
+
+ impl std::default::Default for $name {
+ fn default() -> Self {
+ $name {
+ spans: [Span::call_site(); $len],
+ }
+ }
+ }
+
+ #[cfg(feature = "clone-impls")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+ impl Copy for $name {}
+
+ #[cfg(feature = "clone-impls")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+ impl Clone for $name {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Debug for $name {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(stringify!($name))
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl cmp::Eq for $name {}
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl PartialEq for $name {
+ fn eq(&self, _other: &$name) -> bool {
+ true
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Hash for $name {
+ fn hash<H: Hasher>(&self, _state: &mut H) {}
+ }
+
+ impl_deref_if_len_is_1!($name/$len);
+ )*
+ };
+}
+
+macro_rules! define_punctuation {
+ ($($token:literal pub struct $name:ident/$len:tt #[doc = $usage:literal])*) => {
+ $(
+ define_punctuation_structs! {
+ $token pub struct $name/$len #[doc = $usage]
+ }
+
+ #[cfg(feature = "printing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for $name {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ printing::punct($token, &self.spans, tokens);
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for $name {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok($name {
+ spans: parsing::punct(input, $token)?,
+ })
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ impl Token for $name {
+ fn peek(cursor: Cursor) -> bool {
+ parsing::peek_punct(cursor, $token)
+ }
+
+ fn display() -> &'static str {
+ concat!("`", $token, "`")
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ impl private::Sealed for $name {}
+ )*
+ };
+}
+
+macro_rules! define_delimiters {
+ ($($delim:ident pub struct $name:ident #[$doc:meta])*) => {
+ $(
+ #[$doc]
+ pub struct $name {
+ pub span: DelimSpan,
+ }
+
+ #[doc(hidden)]
+ #[allow(non_snake_case)]
+ pub fn $name<S: IntoSpans<DelimSpan>>(span: S) -> $name {
+ $name {
+ span: span.into_spans(),
+ }
+ }
+
+ impl std::default::Default for $name {
+ fn default() -> Self {
+ $name(Span::call_site())
+ }
+ }
+
+ #[cfg(feature = "clone-impls")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+ impl Copy for $name {}
+
+ #[cfg(feature = "clone-impls")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+ impl Clone for $name {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Debug for $name {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(stringify!($name))
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl cmp::Eq for $name {}
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl PartialEq for $name {
+ fn eq(&self, _other: &$name) -> bool {
+ true
+ }
+ }
+
+ #[cfg(feature = "extra-traits")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+ impl Hash for $name {
+ fn hash<H: Hasher>(&self, _state: &mut H) {}
+ }
+
+ impl $name {
+ #[cfg(feature = "printing")]
+ pub fn surround<F>(&self, tokens: &mut TokenStream, f: F)
+ where
+ F: FnOnce(&mut TokenStream),
+ {
+ let mut inner = TokenStream::new();
+ f(&mut inner);
+ printing::delim(Delimiter::$delim, self.span.join(), tokens, inner);
+ }
+ }
+
+ #[cfg(feature = "parsing")]
+ impl private::Sealed for $name {}
+ )*
+ };
+}
+
+define_punctuation_structs! {
+ "_" pub struct Underscore/1 /// wildcard patterns, inferred types, unnamed items in constants, extern crates, use declarations, and destructuring assignment
+}
+
+#[cfg(feature = "printing")]
+#[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+impl ToTokens for Underscore {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append(Ident::new("_", self.span));
+ }
+}
+
+#[cfg(feature = "parsing")]
+#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+impl Parse for Underscore {
+ fn parse(input: ParseStream) -> Result<Self> {
+ input.step(|cursor| {
+ if let Some((ident, rest)) = cursor.ident() {
+ if ident == "_" {
+ return Ok((Underscore(ident.span()), rest));
+ }
+ }
+ if let Some((punct, rest)) = cursor.punct() {
+ if punct.as_char() == '_' {
+ return Ok((Underscore(punct.span()), rest));
+ }
+ }
+ Err(cursor.error("expected `_`"))
+ })
+ }
+}
+
+#[cfg(feature = "parsing")]
+impl Token for Underscore {
+ fn peek(cursor: Cursor) -> bool {
+ if let Some((ident, _rest)) = cursor.ident() {
+ return ident == "_";
+ }
+ if let Some((punct, _rest)) = cursor.punct() {
+ return punct.as_char() == '_';
+ }
+ false
+ }
+
+ fn display() -> &'static str {
+ "`_`"
+ }
+}
+
+#[cfg(feature = "parsing")]
+impl private::Sealed for Underscore {}
+
+/// None-delimited group
+pub struct Group {
+ pub span: Span,
+}
+
+#[doc(hidden)]
+#[allow(non_snake_case)]
+pub fn Group<S: IntoSpans<Span>>(span: S) -> Group {
+ Group {
+ span: span.into_spans(),
+ }
+}
+
+impl std::default::Default for Group {
+ fn default() -> Self {
+ Group {
+ span: Span::call_site(),
+ }
+ }
+}
+
+#[cfg(feature = "clone-impls")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Copy for Group {}
+
+#[cfg(feature = "clone-impls")]
+#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
+impl Clone for Group {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+#[cfg(feature = "extra-traits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Debug for Group {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("Group")
+ }
+}
+
+#[cfg(feature = "extra-traits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl cmp::Eq for Group {}
+
+#[cfg(feature = "extra-traits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl PartialEq for Group {
+ fn eq(&self, _other: &Group) -> bool {
+ true
+ }
+}
+
+#[cfg(feature = "extra-traits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
+impl Hash for Group {
+ fn hash<H: Hasher>(&self, _state: &mut H) {}
+}
+
+impl Group {
+ #[cfg(feature = "printing")]
+ pub fn surround<F>(&self, tokens: &mut TokenStream, f: F)
+ where
+ F: FnOnce(&mut TokenStream),
+ {
+ let mut inner = TokenStream::new();
+ f(&mut inner);
+ printing::delim(Delimiter::None, self.span, tokens, inner);
+ }
+}
+
+#[cfg(feature = "parsing")]
+impl private::Sealed for Group {}
+
+#[cfg(feature = "parsing")]
+impl Token for Paren {
+ fn peek(cursor: Cursor) -> bool {
+ lookahead::is_delimiter(cursor, Delimiter::Parenthesis)
+ }
+
+ fn display() -> &'static str {
+ "parentheses"
+ }
+}
+
+#[cfg(feature = "parsing")]
+impl Token for Brace {
+ fn peek(cursor: Cursor) -> bool {
+ lookahead::is_delimiter(cursor, Delimiter::Brace)
+ }
+
+ fn display() -> &'static str {
+ "curly braces"
+ }
+}
+
+#[cfg(feature = "parsing")]
+impl Token for Bracket {
+ fn peek(cursor: Cursor) -> bool {
+ lookahead::is_delimiter(cursor, Delimiter::Bracket)
+ }
+
+ fn display() -> &'static str {
+ "square brackets"
+ }
+}
+
+#[cfg(feature = "parsing")]
+impl Token for Group {
+ fn peek(cursor: Cursor) -> bool {
+ lookahead::is_delimiter(cursor, Delimiter::None)
+ }
+
+ fn display() -> &'static str {
+ "invisible group"
+ }
+}
+
+define_keywords! {
+ "abstract" pub struct Abstract
+ "as" pub struct As
+ "async" pub struct Async
+ "auto" pub struct Auto
+ "await" pub struct Await
+ "become" pub struct Become
+ "box" pub struct Box
+ "break" pub struct Break
+ "const" pub struct Const
+ "continue" pub struct Continue
+ "crate" pub struct Crate
+ "default" pub struct Default
+ "do" pub struct Do
+ "dyn" pub struct Dyn
+ "else" pub struct Else
+ "enum" pub struct Enum
+ "extern" pub struct Extern
+ "final" pub struct Final
+ "fn" pub struct Fn
+ "for" pub struct For
+ "if" pub struct If
+ "impl" pub struct Impl
+ "in" pub struct In
+ "let" pub struct Let
+ "loop" pub struct Loop
+ "macro" pub struct Macro
+ "match" pub struct Match
+ "mod" pub struct Mod
+ "move" pub struct Move
+ "mut" pub struct Mut
+ "override" pub struct Override
+ "priv" pub struct Priv
+ "pub" pub struct Pub
+ "ref" pub struct Ref
+ "return" pub struct Return
+ "Self" pub struct SelfType
+ "self" pub struct SelfValue
+ "static" pub struct Static
+ "struct" pub struct Struct
+ "super" pub struct Super
+ "trait" pub struct Trait
+ "try" pub struct Try
+ "type" pub struct Type
+ "typeof" pub struct Typeof
+ "union" pub struct Union
+ "unsafe" pub struct Unsafe
+ "unsized" pub struct Unsized
+ "use" pub struct Use
+ "virtual" pub struct Virtual
+ "where" pub struct Where
+ "while" pub struct While
+ "yield" pub struct Yield
+}
+
+define_punctuation! {
+ "&" pub struct And/1 /// bitwise and logical AND, borrow, references, reference patterns
+ "&&" pub struct AndAnd/2 /// lazy AND, borrow, references, reference patterns
+ "&=" pub struct AndEq/2 /// bitwise AND assignment
+ "@" pub struct At/1 /// subpattern binding
+ "^" pub struct Caret/1 /// bitwise and logical XOR
+ "^=" pub struct CaretEq/2 /// bitwise XOR assignment
+ ":" pub struct Colon/1 /// various separators
+ "," pub struct Comma/1 /// various separators
+ "$" pub struct Dollar/1 /// macros
+ "." pub struct Dot/1 /// field access, tuple index
+ ".." pub struct DotDot/2 /// range, struct expressions, patterns, range patterns
+ "..." pub struct DotDotDot/3 /// variadic functions, range patterns
+ "..=" pub struct DotDotEq/3 /// inclusive range, range patterns
+ "=" pub struct Eq/1 /// assignment, attributes, various type definitions
+ "==" pub struct EqEq/2 /// equal
+ "=>" pub struct FatArrow/2 /// match arms, macros
+ ">=" pub struct Ge/2 /// greater than or equal to, generics
+ ">" pub struct Gt/1 /// greater than, generics, paths
+ "<-" pub struct LArrow/2 /// unused
+ "<=" pub struct Le/2 /// less than or equal to
+ "<" pub struct Lt/1 /// less than, generics, paths
+ "-" pub struct Minus/1 /// subtraction, negation
+ "-=" pub struct MinusEq/2 /// subtraction assignment
+ "!=" pub struct Ne/2 /// not equal
+ "!" pub struct Not/1 /// bitwise and logical NOT, macro calls, inner attributes, never type, negative impls
+ "|" pub struct Or/1 /// bitwise and logical OR, closures, patterns in match, if let, and while let
+ "|=" pub struct OrEq/2 /// bitwise OR assignment
+ "||" pub struct OrOr/2 /// lazy OR, closures
+ "::" pub struct PathSep/2 /// path separator
+ "%" pub struct Percent/1 /// remainder
+ "%=" pub struct PercentEq/2 /// remainder assignment
+ "+" pub struct Plus/1 /// addition, trait bounds, macro Kleene matcher
+ "+=" pub struct PlusEq/2 /// addition assignment
+ "#" pub struct Pound/1 /// attributes
+ "?" pub struct Question/1 /// question mark operator, questionably sized, macro Kleene matcher
+ "->" pub struct RArrow/2 /// function return type, closure return type, function pointer type
+ ";" pub struct Semi/1 /// terminator for various items and statements, array types
+ "<<" pub struct Shl/2 /// shift left, nested generics
+ "<<=" pub struct ShlEq/3 /// shift left assignment
+ ">>" pub struct Shr/2 /// shift right, nested generics
+ ">>=" pub struct ShrEq/3 /// shift right assignment, nested generics
+ "/" pub struct Slash/1 /// division
+ "/=" pub struct SlashEq/2 /// division assignment
+ "*" pub struct Star/1 /// multiplication, dereference, raw pointers, macro Kleene matcher, use wildcards
+ "*=" pub struct StarEq/2 /// multiplication assignment
+ "~" pub struct Tilde/1 /// unused since before Rust 1.0
+}
+
+define_delimiters! {
+ Brace pub struct Brace /// `{`…`}`
+ Bracket pub struct Bracket /// `[`…`]`
+ Parenthesis pub struct Paren /// `(`…`)`
+}
+
+/// A type-macro that expands to the name of the Rust type representation of a
+/// given token.
+///
+/// As a type, `Token!` is commonly used in the type of struct fields, the type
+/// of a `let` statement, or in turbofish for a `parse` function.
+///
+/// ```
+/// use syn::{Ident, Token};
+/// use syn::parse::{Parse, ParseStream, Result};
+///
+/// // `struct Foo;`
+/// pub struct UnitStruct {
+/// struct_token: Token![struct],
+/// ident: Ident,
+/// semi_token: Token![;],
+/// }
+///
+/// impl Parse for UnitStruct {
+/// fn parse(input: ParseStream) -> Result<Self> {
+/// let struct_token: Token![struct] = input.parse()?;
+/// let ident: Ident = input.parse()?;
+/// let semi_token = input.parse::<Token![;]>()?;
+/// Ok(UnitStruct { struct_token, ident, semi_token })
+/// }
+/// }
+/// ```
+///
+/// As an expression, `Token!` is used for peeking tokens or instantiating
+/// tokens from a span.
+///
+/// ```
+/// # use syn::{Ident, Token};
+/// # use syn::parse::{Parse, ParseStream, Result};
+/// #
+/// # struct UnitStruct {
+/// # struct_token: Token![struct],
+/// # ident: Ident,
+/// # semi_token: Token![;],
+/// # }
+/// #
+/// # impl Parse for UnitStruct {
+/// # fn parse(input: ParseStream) -> Result<Self> {
+/// # unimplemented!()
+/// # }
+/// # }
+/// #
+/// fn make_unit_struct(name: Ident) -> UnitStruct {
+/// let span = name.span();
+/// UnitStruct {
+/// struct_token: Token,
+/// ident: name,
+/// semi_token: Token,
+/// }
+/// }
+///
+/// # fn parse(input: ParseStream) -> Result<()> {
+/// if input.peek(Token![struct]) {
+/// let unit_struct: UnitStruct = input.parse()?;
+/// /* ... */
+/// }
+/// # Ok(())
+/// # }
+/// ```
+///
+/// See the [token module] documentation for details and examples.
+///
+/// [token module]: crate::token
+#[macro_export]
+macro_rules! Token {
+ [abstract] => { $crate::token::Abstract };
+ [as] => { $crate::token::As };
+ [async] => { $crate::token::Async };
+ [auto] => { $crate::token::Auto };
+ [await] => { $crate::token::Await };
+ [become] => { $crate::token::Become };
+ [box] => { $crate::token::Box };
+ [break] => { $crate::token::Break };
+ [const] => { $crate::token::Const };
+ [continue] => { $crate::token::Continue };
+ [crate] => { $crate::token::Crate };
+ [default] => { $crate::token::Default };
+ [do] => { $crate::token::Do };
+ [dyn] => { $crate::token::Dyn };
+ [else] => { $crate::token::Else };
+ [enum] => { $crate::token::Enum };
+ [extern] => { $crate::token::Extern };
+ [final] => { $crate::token::Final };
+ [fn] => { $crate::token::Fn };
+ [for] => { $crate::token::For };
+ [if] => { $crate::token::If };
+ [impl] => { $crate::token::Impl };
+ [in] => { $crate::token::In };
+ [let] => { $crate::token::Let };
+ [loop] => { $crate::token::Loop };
+ [macro] => { $crate::token::Macro };
+ [match] => { $crate::token::Match };
+ [mod] => { $crate::token::Mod };
+ [move] => { $crate::token::Move };
+ [mut] => { $crate::token::Mut };
+ [override] => { $crate::token::Override };
+ [priv] => { $crate::token::Priv };
+ [pub] => { $crate::token::Pub };
+ [ref] => { $crate::token::Ref };
+ [return] => { $crate::token::Return };
+ [Self] => { $crate::token::SelfType };
+ [self] => { $crate::token::SelfValue };
+ [static] => { $crate::token::Static };
+ [struct] => { $crate::token::Struct };
+ [super] => { $crate::token::Super };
+ [trait] => { $crate::token::Trait };
+ [try] => { $crate::token::Try };
+ [type] => { $crate::token::Type };
+ [typeof] => { $crate::token::Typeof };
+ [union] => { $crate::token::Union };
+ [unsafe] => { $crate::token::Unsafe };
+ [unsized] => { $crate::token::Unsized };
+ [use] => { $crate::token::Use };
+ [virtual] => { $crate::token::Virtual };
+ [where] => { $crate::token::Where };
+ [while] => { $crate::token::While };
+ [yield] => { $crate::token::Yield };
+ [&] => { $crate::token::And };
+ [&&] => { $crate::token::AndAnd };
+ [&=] => { $crate::token::AndEq };
+ [@] => { $crate::token::At };
+ [^] => { $crate::token::Caret };
+ [^=] => { $crate::token::CaretEq };
+ [:] => { $crate::token::Colon };
+ [,] => { $crate::token::Comma };
+ [$] => { $crate::token::Dollar };
+ [.] => { $crate::token::Dot };
+ [..] => { $crate::token::DotDot };
+ [...] => { $crate::token::DotDotDot };
+ [..=] => { $crate::token::DotDotEq };
+ [=] => { $crate::token::Eq };
+ [==] => { $crate::token::EqEq };
+ [=>] => { $crate::token::FatArrow };
+ [>=] => { $crate::token::Ge };
+ [>] => { $crate::token::Gt };
+ [<-] => { $crate::token::LArrow };
+ [<=] => { $crate::token::Le };
+ [<] => { $crate::token::Lt };
+ [-] => { $crate::token::Minus };
+ [-=] => { $crate::token::MinusEq };
+ [!=] => { $crate::token::Ne };
+ [!] => { $crate::token::Not };
+ [|] => { $crate::token::Or };
+ [|=] => { $crate::token::OrEq };
+ [||] => { $crate::token::OrOr };
+ [::] => { $crate::token::PathSep };
+ [%] => { $crate::token::Percent };
+ [%=] => { $crate::token::PercentEq };
+ [+] => { $crate::token::Plus };
+ [+=] => { $crate::token::PlusEq };
+ [#] => { $crate::token::Pound };
+ [?] => { $crate::token::Question };
+ [->] => { $crate::token::RArrow };
+ [;] => { $crate::token::Semi };
+ [<<] => { $crate::token::Shl };
+ [<<=] => { $crate::token::ShlEq };
+ [>>] => { $crate::token::Shr };
+ [>>=] => { $crate::token::ShrEq };
+ [/] => { $crate::token::Slash };
+ [/=] => { $crate::token::SlashEq };
+ [*] => { $crate::token::Star };
+ [*=] => { $crate::token::StarEq };
+ [~] => { $crate::token::Tilde };
+ [_] => { $crate::token::Underscore };
+}
+
+// Not public API.
+#[doc(hidden)]
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::buffer::Cursor;
+ use crate::error::{Error, Result};
+ use crate::parse::ParseStream;
+ use proc_macro2::{Spacing, Span};
+
+ pub(crate) fn keyword(input: ParseStream, token: &str) -> Result<Span> {
+ input.step(|cursor| {
+ if let Some((ident, rest)) = cursor.ident() {
+ if ident == token {
+ return Ok((ident.span(), rest));
+ }
+ }
+ Err(cursor.error(format!("expected `{}`", token)))
+ })
+ }
+
+ pub(crate) fn peek_keyword(cursor: Cursor, token: &str) -> bool {
+ if let Some((ident, _rest)) = cursor.ident() {
+ ident == token
+ } else {
+ false
+ }
+ }
+
+ #[doc(hidden)]
+ pub fn punct<const N: usize>(input: ParseStream, token: &str) -> Result<[Span; N]> {
+ let mut spans = [input.span(); N];
+ punct_helper(input, token, &mut spans)?;
+ Ok(spans)
+ }
+
+ fn punct_helper(input: ParseStream, token: &str, spans: &mut [Span]) -> Result<()> {
+ input.step(|cursor| {
+ let mut cursor = *cursor;
+ assert_eq!(token.len(), spans.len());
+
+ for (i, ch) in token.chars().enumerate() {
+ match cursor.punct() {
+ Some((punct, rest)) => {
+ spans[i] = punct.span();
+ if punct.as_char() != ch {
+ break;
+ } else if i == token.len() - 1 {
+ return Ok(((), rest));
+ } else if punct.spacing() != Spacing::Joint {
+ break;
+ }
+ cursor = rest;
+ }
+ None => break,
+ }
+ }
+
+ Err(Error::new(spans[0], format!("expected `{}`", token)))
+ })
+ }
+
+ #[doc(hidden)]
+ pub fn peek_punct(mut cursor: Cursor, token: &str) -> bool {
+ for (i, ch) in token.chars().enumerate() {
+ match cursor.punct() {
+ Some((punct, rest)) => {
+ if punct.as_char() != ch {
+ break;
+ } else if i == token.len() - 1 {
+ return true;
+ } else if punct.spacing() != Spacing::Joint {
+ break;
+ }
+ cursor = rest;
+ }
+ None => break,
+ }
+ }
+ false
+ }
+}
+
+// Not public API.
+#[doc(hidden)]
+#[cfg(feature = "printing")]
+pub(crate) mod printing {
+ use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream};
+ use quote::TokenStreamExt;
+
+ #[doc(hidden)]
+ pub fn punct(s: &str, spans: &[Span], tokens: &mut TokenStream) {
+ assert_eq!(s.len(), spans.len());
+
+ let mut chars = s.chars();
+ let mut spans = spans.iter();
+ let ch = chars.next_back().unwrap();
+ let span = spans.next_back().unwrap();
+ for (ch, span) in chars.zip(spans) {
+ let mut op = Punct::new(ch, Spacing::Joint);
+ op.set_span(*span);
+ tokens.append(op);
+ }
+
+ let mut op = Punct::new(ch, Spacing::Alone);
+ op.set_span(*span);
+ tokens.append(op);
+ }
+
+ pub(crate) fn keyword(s: &str, span: Span, tokens: &mut TokenStream) {
+ tokens.append(Ident::new(s, span));
+ }
+
+ pub(crate) fn delim(
+ delim: Delimiter,
+ span: Span,
+ tokens: &mut TokenStream,
+ inner: TokenStream,
+ ) {
+ let mut g = Group::new(delim, inner);
+ g.set_span(span);
+ tokens.append(g);
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/tt.rs b/rust/hw/char/pl011/vendor/syn/src/tt.rs
new file mode 100644
index 0000000000..7d5d6a1ac3
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/tt.rs
@@ -0,0 +1,107 @@
+use proc_macro2::{Delimiter, TokenStream, TokenTree};
+use std::hash::{Hash, Hasher};
+
+pub(crate) struct TokenTreeHelper<'a>(pub &'a TokenTree);
+
+impl<'a> PartialEq for TokenTreeHelper<'a> {
+ fn eq(&self, other: &Self) -> bool {
+ use proc_macro2::Spacing;
+
+ match (self.0, other.0) {
+ (TokenTree::Group(g1), TokenTree::Group(g2)) => {
+ match (g1.delimiter(), g2.delimiter()) {
+ (Delimiter::Parenthesis, Delimiter::Parenthesis)
+ | (Delimiter::Brace, Delimiter::Brace)
+ | (Delimiter::Bracket, Delimiter::Bracket)
+ | (Delimiter::None, Delimiter::None) => {}
+ _ => return false,
+ }
+
+ let s1 = g1.stream().into_iter();
+ let mut s2 = g2.stream().into_iter();
+
+ for item1 in s1 {
+ let item2 = match s2.next() {
+ Some(item) => item,
+ None => return false,
+ };
+ if TokenTreeHelper(&item1) != TokenTreeHelper(&item2) {
+ return false;
+ }
+ }
+ s2.next().is_none()
+ }
+ (TokenTree::Punct(o1), TokenTree::Punct(o2)) => {
+ o1.as_char() == o2.as_char()
+ && match (o1.spacing(), o2.spacing()) {
+ (Spacing::Alone, Spacing::Alone) | (Spacing::Joint, Spacing::Joint) => true,
+ _ => false,
+ }
+ }
+ (TokenTree::Literal(l1), TokenTree::Literal(l2)) => l1.to_string() == l2.to_string(),
+ (TokenTree::Ident(s1), TokenTree::Ident(s2)) => s1 == s2,
+ _ => false,
+ }
+ }
+}
+
+impl<'a> Hash for TokenTreeHelper<'a> {
+ fn hash<H: Hasher>(&self, h: &mut H) {
+ use proc_macro2::Spacing;
+
+ match self.0 {
+ TokenTree::Group(g) => {
+ 0u8.hash(h);
+ match g.delimiter() {
+ Delimiter::Parenthesis => 0u8.hash(h),
+ Delimiter::Brace => 1u8.hash(h),
+ Delimiter::Bracket => 2u8.hash(h),
+ Delimiter::None => 3u8.hash(h),
+ }
+
+ for item in g.stream() {
+ TokenTreeHelper(&item).hash(h);
+ }
+ 0xFFu8.hash(h); // terminator w/ a variant we don't normally hash
+ }
+ TokenTree::Punct(op) => {
+ 1u8.hash(h);
+ op.as_char().hash(h);
+ match op.spacing() {
+ Spacing::Alone => 0u8.hash(h),
+ Spacing::Joint => 1u8.hash(h),
+ }
+ }
+ TokenTree::Literal(lit) => (2u8, lit.to_string()).hash(h),
+ TokenTree::Ident(word) => (3u8, word).hash(h),
+ }
+ }
+}
+
+pub(crate) struct TokenStreamHelper<'a>(pub &'a TokenStream);
+
+impl<'a> PartialEq for TokenStreamHelper<'a> {
+ fn eq(&self, other: &Self) -> bool {
+ let left = self.0.clone().into_iter().collect::<Vec<_>>();
+ let right = other.0.clone().into_iter().collect::<Vec<_>>();
+ if left.len() != right.len() {
+ return false;
+ }
+ for (a, b) in left.into_iter().zip(right) {
+ if TokenTreeHelper(&a) != TokenTreeHelper(&b) {
+ return false;
+ }
+ }
+ true
+ }
+}
+
+impl<'a> Hash for TokenStreamHelper<'a> {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ let tts = self.0.clone().into_iter().collect::<Vec<_>>();
+ tts.len().hash(state);
+ for tt in tts {
+ TokenTreeHelper(&tt).hash(state);
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/ty.rs b/rust/hw/char/pl011/vendor/syn/src/ty.rs
new file mode 100644
index 0000000000..fa9870e5a2
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/ty.rs
@@ -0,0 +1,1216 @@
+use crate::attr::Attribute;
+use crate::expr::Expr;
+use crate::generics::{BoundLifetimes, TypeParamBound};
+use crate::ident::Ident;
+use crate::lifetime::Lifetime;
+use crate::lit::LitStr;
+use crate::mac::Macro;
+use crate::path::{Path, QSelf};
+use crate::punctuated::Punctuated;
+use crate::token;
+use proc_macro2::TokenStream;
+
+ast_enum_of_structs! {
+ /// The possible types that a Rust value could have.
+ ///
+ /// # 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"))))]
+ #[non_exhaustive]
+ pub enum Type {
+ /// A fixed size array type: `[T; n]`.
+ Array(TypeArray),
+
+ /// A bare function type: `fn(usize) -> bool`.
+ BareFn(TypeBareFn),
+
+ /// A type contained within invisible delimiters.
+ Group(TypeGroup),
+
+ /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or
+ /// a lifetime.
+ ImplTrait(TypeImplTrait),
+
+ /// Indication that a type should be inferred by the compiler: `_`.
+ Infer(TypeInfer),
+
+ /// A macro in the type position.
+ Macro(TypeMacro),
+
+ /// The never type: `!`.
+ Never(TypeNever),
+
+ /// A parenthesized type equivalent to the inner type.
+ Paren(TypeParen),
+
+ /// A path like `std::slice::Iter`, optionally qualified with a
+ /// self-type as in `<Vec<T> as SomeTrait>::Associated`.
+ Path(TypePath),
+
+ /// A raw pointer type: `*const T` or `*mut T`.
+ Ptr(TypePtr),
+
+ /// A reference type: `&'a T` or `&'a mut T`.
+ Reference(TypeReference),
+
+ /// A dynamically sized slice type: `[T]`.
+ Slice(TypeSlice),
+
+ /// A trait object type `dyn Bound1 + Bound2 + Bound3` where `Bound` is a
+ /// trait or a lifetime.
+ TraitObject(TypeTraitObject),
+
+ /// A tuple type: `(A, B, C, String)`.
+ Tuple(TypeTuple),
+
+ /// Tokens in type position not interpreted by Syn.
+ Verbatim(TokenStream),
+
+ // For testing exhaustiveness in downstream code, use the following idiom:
+ //
+ // match ty {
+ // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
+ //
+ // Type::Array(ty) => {...}
+ // Type::BareFn(ty) => {...}
+ // ...
+ // Type::Verbatim(ty) => {...}
+ //
+ // _ => { /* 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.
+ }
+}
+
+ast_struct! {
+ /// A fixed size array type: `[T; n]`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeArray {
+ pub bracket_token: token::Bracket,
+ pub elem: Box<Type>,
+ pub semi_token: Token![;],
+ pub len: Expr,
+ }
+}
+
+ast_struct! {
+ /// A bare function type: `fn(usize) -> bool`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeBareFn {
+ pub lifetimes: Option<BoundLifetimes>,
+ pub unsafety: Option<Token![unsafe]>,
+ pub abi: Option<Abi>,
+ pub fn_token: Token![fn],
+ pub paren_token: token::Paren,
+ pub inputs: Punctuated<BareFnArg, Token![,]>,
+ pub variadic: Option<BareVariadic>,
+ pub output: ReturnType,
+ }
+}
+
+ast_struct! {
+ /// A type contained within invisible delimiters.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeGroup {
+ pub group_token: token::Group,
+ pub elem: Box<Type>,
+ }
+}
+
+ast_struct! {
+ /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or
+ /// a lifetime.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeImplTrait {
+ pub impl_token: Token![impl],
+ pub bounds: Punctuated<TypeParamBound, Token![+]>,
+ }
+}
+
+ast_struct! {
+ /// Indication that a type should be inferred by the compiler: `_`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeInfer {
+ pub underscore_token: Token![_],
+ }
+}
+
+ast_struct! {
+ /// A macro in the type position.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeMacro {
+ pub mac: Macro,
+ }
+}
+
+ast_struct! {
+ /// The never type: `!`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeNever {
+ pub bang_token: Token![!],
+ }
+}
+
+ast_struct! {
+ /// A parenthesized type equivalent to the inner type.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeParen {
+ pub paren_token: token::Paren,
+ pub elem: Box<Type>,
+ }
+}
+
+ast_struct! {
+ /// A path like `std::slice::Iter`, optionally qualified with a
+ /// self-type as in `<Vec<T> as SomeTrait>::Associated`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypePath {
+ pub qself: Option<QSelf>,
+ pub path: Path,
+ }
+}
+
+ast_struct! {
+ /// A raw pointer type: `*const T` or `*mut T`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypePtr {
+ pub star_token: Token![*],
+ pub const_token: Option<Token![const]>,
+ pub mutability: Option<Token![mut]>,
+ pub elem: Box<Type>,
+ }
+}
+
+ast_struct! {
+ /// A reference type: `&'a T` or `&'a mut T`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeReference {
+ pub and_token: Token![&],
+ pub lifetime: Option<Lifetime>,
+ pub mutability: Option<Token![mut]>,
+ pub elem: Box<Type>,
+ }
+}
+
+ast_struct! {
+ /// A dynamically sized slice type: `[T]`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeSlice {
+ pub bracket_token: token::Bracket,
+ pub elem: Box<Type>,
+ }
+}
+
+ast_struct! {
+ /// A trait object type `dyn Bound1 + Bound2 + Bound3` where `Bound` is a
+ /// trait or a lifetime.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeTraitObject {
+ pub dyn_token: Option<Token![dyn]>,
+ pub bounds: Punctuated<TypeParamBound, Token![+]>,
+ }
+}
+
+ast_struct! {
+ /// A tuple type: `(A, B, C, String)`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct TypeTuple {
+ pub paren_token: token::Paren,
+ pub elems: Punctuated<Type, Token![,]>,
+ }
+}
+
+ast_struct! {
+ /// The binary interface of a function: `extern "C"`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct Abi {
+ pub extern_token: Token![extern],
+ pub name: Option<LitStr>,
+ }
+}
+
+ast_struct! {
+ /// An argument in a function type: the `usize` in `fn(usize) -> bool`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct BareFnArg {
+ pub attrs: Vec<Attribute>,
+ pub name: Option<(Ident, Token![:])>,
+ pub ty: Type,
+ }
+}
+
+ast_struct! {
+ /// The variadic argument of a function pointer like `fn(usize, ...)`.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub struct BareVariadic {
+ pub attrs: Vec<Attribute>,
+ pub name: Option<(Ident, Token![:])>,
+ pub dots: Token![...],
+ pub comma: Option<Token![,]>,
+ }
+}
+
+ast_enum! {
+ /// Return type of a function signature.
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
+ pub enum ReturnType {
+ /// Return type is not specified.
+ ///
+ /// Functions default to `()` and closures default to type inference.
+ Default,
+ /// A particular type is returned.
+ Type(Token![->], Box<Type>),
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub(crate) mod parsing {
+ use crate::attr::Attribute;
+ use crate::error::{self, Result};
+ use crate::ext::IdentExt as _;
+ use crate::generics::{BoundLifetimes, TraitBound, TraitBoundModifier, TypeParamBound};
+ use crate::ident::Ident;
+ use crate::lifetime::Lifetime;
+ use crate::mac::{self, Macro};
+ use crate::parse::{Parse, ParseStream};
+ use crate::path;
+ use crate::path::{Path, PathArguments, QSelf};
+ use crate::punctuated::Punctuated;
+ use crate::token;
+ use crate::ty::{
+ Abi, BareFnArg, BareVariadic, ReturnType, Type, TypeArray, TypeBareFn, TypeGroup,
+ TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr,
+ TypeReference, TypeSlice, TypeTraitObject, TypeTuple,
+ };
+ use crate::verbatim;
+ use proc_macro2::Span;
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Type {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_plus = true;
+ let allow_group_generic = true;
+ ambig_ty(input, allow_plus, allow_group_generic)
+ }
+ }
+
+ impl Type {
+ /// In some positions, types may not contain the `+` character, to
+ /// disambiguate them. For example in the expression `1 as T`, T may not
+ /// contain a `+` character.
+ ///
+ /// This parser does not allow a `+`, while the default parser does.
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn without_plus(input: ParseStream) -> Result<Self> {
+ let allow_plus = false;
+ let allow_group_generic = true;
+ ambig_ty(input, allow_plus, allow_group_generic)
+ }
+ }
+
+ pub(crate) fn ambig_ty(
+ input: ParseStream,
+ allow_plus: bool,
+ allow_group_generic: bool,
+ ) -> Result<Type> {
+ let begin = input.fork();
+
+ if input.peek(token::Group) {
+ let mut group: TypeGroup = input.parse()?;
+ if input.peek(Token![::]) && input.peek3(Ident::peek_any) {
+ if let Type::Path(mut ty) = *group.elem {
+ Path::parse_rest(input, &mut ty.path, false)?;
+ return Ok(Type::Path(ty));
+ } else {
+ return Ok(Type::Path(TypePath {
+ qself: Some(QSelf {
+ lt_token: Token,
+ position: 0,
+ as_token: None,
+ gt_token: Token,
+ ty: group.elem,
+ }),
+ path: Path::parse_helper(input, false)?,
+ }));
+ }
+ } else if input.peek(Token![<]) && allow_group_generic
+ || input.peek(Token![::]) && input.peek3(Token![<])
+ {
+ if let Type::Path(mut ty) = *group.elem {
+ let arguments = &mut ty.path.segments.last_mut().unwrap().arguments;
+ if arguments.is_none() {
+ *arguments = PathArguments::AngleBracketed(input.parse()?);
+ Path::parse_rest(input, &mut ty.path, false)?;
+ return Ok(Type::Path(ty));
+ } else {
+ group.elem = Box::new(Type::Path(ty));
+ }
+ }
+ }
+ return Ok(Type::Group(group));
+ }
+
+ let mut lifetimes = None::<BoundLifetimes>;
+ let mut lookahead = input.lookahead1();
+ if lookahead.peek(Token![for]) {
+ lifetimes = input.parse()?;
+ lookahead = input.lookahead1();
+ if !lookahead.peek(Ident)
+ && !lookahead.peek(Token![fn])
+ && !lookahead.peek(Token![unsafe])
+ && !lookahead.peek(Token![extern])
+ && !lookahead.peek(Token![super])
+ && !lookahead.peek(Token![self])
+ && !lookahead.peek(Token![Self])
+ && !lookahead.peek(Token![crate])
+ || input.peek(Token![dyn])
+ {
+ return Err(lookahead.error());
+ }
+ }
+
+ if lookahead.peek(token::Paren) {
+ let content;
+ let paren_token = parenthesized!(content in input);
+ if content.is_empty() {
+ return Ok(Type::Tuple(TypeTuple {
+ paren_token,
+ elems: Punctuated::new(),
+ }));
+ }
+ if content.peek(Lifetime) {
+ return Ok(Type::Paren(TypeParen {
+ paren_token,
+ elem: Box::new(Type::TraitObject(content.parse()?)),
+ }));
+ }
+ if content.peek(Token![?]) {
+ return Ok(Type::TraitObject(TypeTraitObject {
+ dyn_token: None,
+ bounds: {
+ let mut bounds = Punctuated::new();
+ bounds.push_value(TypeParamBound::Trait(TraitBound {
+ paren_token: Some(paren_token),
+ ..content.parse()?
+ }));
+ while let Some(plus) = input.parse()? {
+ bounds.push_punct(plus);
+ bounds.push_value(input.parse()?);
+ }
+ bounds
+ },
+ }));
+ }
+ let mut first: Type = content.parse()?;
+ if content.peek(Token![,]) {
+ return Ok(Type::Tuple(TypeTuple {
+ paren_token,
+ elems: {
+ let mut elems = Punctuated::new();
+ elems.push_value(first);
+ elems.push_punct(content.parse()?);
+ while !content.is_empty() {
+ elems.push_value(content.parse()?);
+ if content.is_empty() {
+ break;
+ }
+ elems.push_punct(content.parse()?);
+ }
+ elems
+ },
+ }));
+ }
+ if allow_plus && input.peek(Token![+]) {
+ loop {
+ let first = match first {
+ Type::Path(TypePath { qself: None, path }) => {
+ TypeParamBound::Trait(TraitBound {
+ paren_token: Some(paren_token),
+ modifier: TraitBoundModifier::None,
+ lifetimes: None,
+ path,
+ })
+ }
+ Type::TraitObject(TypeTraitObject {
+ dyn_token: None,
+ bounds,
+ }) => {
+ if bounds.len() > 1 || bounds.trailing_punct() {
+ first = Type::TraitObject(TypeTraitObject {
+ dyn_token: None,
+ bounds,
+ });
+ break;
+ }
+ match bounds.into_iter().next().unwrap() {
+ TypeParamBound::Trait(trait_bound) => {
+ TypeParamBound::Trait(TraitBound {
+ paren_token: Some(paren_token),
+ ..trait_bound
+ })
+ }
+ other @ (TypeParamBound::Lifetime(_)
+ | TypeParamBound::Verbatim(_)) => other,
+ }
+ }
+ _ => break,
+ };
+ return Ok(Type::TraitObject(TypeTraitObject {
+ dyn_token: None,
+ bounds: {
+ let mut bounds = Punctuated::new();
+ bounds.push_value(first);
+ while let Some(plus) = input.parse()? {
+ bounds.push_punct(plus);
+ bounds.push_value(input.parse()?);
+ }
+ bounds
+ },
+ }));
+ }
+ }
+ Ok(Type::Paren(TypeParen {
+ paren_token,
+ elem: Box::new(first),
+ }))
+ } else if lookahead.peek(Token![fn])
+ || lookahead.peek(Token![unsafe])
+ || lookahead.peek(Token![extern])
+ {
+ let mut bare_fn: TypeBareFn = input.parse()?;
+ bare_fn.lifetimes = lifetimes;
+ Ok(Type::BareFn(bare_fn))
+ } else if lookahead.peek(Ident)
+ || input.peek(Token![super])
+ || input.peek(Token![self])
+ || input.peek(Token![Self])
+ || input.peek(Token![crate])
+ || lookahead.peek(Token![::])
+ || lookahead.peek(Token![<])
+ {
+ let ty: TypePath = input.parse()?;
+ if ty.qself.is_some() {
+ return Ok(Type::Path(ty));
+ }
+
+ if input.peek(Token![!]) && !input.peek(Token![!=]) && ty.path.is_mod_style() {
+ let bang_token: Token![!] = input.parse()?;
+ let (delimiter, tokens) = mac::parse_delimiter(input)?;
+ return Ok(Type::Macro(TypeMacro {
+ mac: Macro {
+ path: ty.path,
+ bang_token,
+ delimiter,
+ tokens,
+ },
+ }));
+ }
+
+ if lifetimes.is_some() || allow_plus && input.peek(Token![+]) {
+ let mut bounds = Punctuated::new();
+ bounds.push_value(TypeParamBound::Trait(TraitBound {
+ paren_token: None,
+ modifier: TraitBoundModifier::None,
+ lifetimes,
+ path: ty.path,
+ }));
+ if allow_plus {
+ while input.peek(Token![+]) {
+ bounds.push_punct(input.parse()?);
+ if !(input.peek(Ident::peek_any)
+ || input.peek(Token![::])
+ || input.peek(Token![?])
+ || input.peek(Lifetime)
+ || input.peek(token::Paren))
+ {
+ break;
+ }
+ bounds.push_value(input.parse()?);
+ }
+ }
+ return Ok(Type::TraitObject(TypeTraitObject {
+ dyn_token: None,
+ bounds,
+ }));
+ }
+
+ Ok(Type::Path(ty))
+ } else if lookahead.peek(Token![dyn]) {
+ let dyn_token: Token![dyn] = input.parse()?;
+ let dyn_span = dyn_token.span;
+ let star_token: Option<Token![*]> = input.parse()?;
+ let bounds = TypeTraitObject::parse_bounds(dyn_span, input, allow_plus)?;
+ return Ok(if star_token.is_some() {
+ Type::Verbatim(verbatim::between(&begin, input))
+ } else {
+ Type::TraitObject(TypeTraitObject {
+ dyn_token: Some(dyn_token),
+ bounds,
+ })
+ });
+ } else if lookahead.peek(token::Bracket) {
+ let content;
+ let bracket_token = bracketed!(content in input);
+ let elem: Type = content.parse()?;
+ if content.peek(Token![;]) {
+ Ok(Type::Array(TypeArray {
+ bracket_token,
+ elem: Box::new(elem),
+ semi_token: content.parse()?,
+ len: content.parse()?,
+ }))
+ } else {
+ Ok(Type::Slice(TypeSlice {
+ bracket_token,
+ elem: Box::new(elem),
+ }))
+ }
+ } else if lookahead.peek(Token![*]) {
+ input.parse().map(Type::Ptr)
+ } else if lookahead.peek(Token![&]) {
+ input.parse().map(Type::Reference)
+ } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
+ input.parse().map(Type::Never)
+ } else if lookahead.peek(Token![impl]) {
+ TypeImplTrait::parse(input, allow_plus).map(Type::ImplTrait)
+ } else if lookahead.peek(Token![_]) {
+ input.parse().map(Type::Infer)
+ } else if lookahead.peek(Lifetime) {
+ input.parse().map(Type::TraitObject)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeSlice {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(TypeSlice {
+ bracket_token: bracketed!(content in input),
+ elem: content.parse()?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeArray {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ Ok(TypeArray {
+ bracket_token: bracketed!(content in input),
+ elem: content.parse()?,
+ semi_token: content.parse()?,
+ len: content.parse()?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypePtr {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let star_token: Token![*] = input.parse()?;
+
+ let lookahead = input.lookahead1();
+ let (const_token, mutability) = if lookahead.peek(Token![const]) {
+ (Some(input.parse()?), None)
+ } else if lookahead.peek(Token![mut]) {
+ (None, Some(input.parse()?))
+ } else {
+ return Err(lookahead.error());
+ };
+
+ Ok(TypePtr {
+ star_token,
+ const_token,
+ mutability,
+ elem: Box::new(input.call(Type::without_plus)?),
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeReference {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(TypeReference {
+ and_token: input.parse()?,
+ lifetime: input.parse()?,
+ mutability: input.parse()?,
+ // & binds tighter than +, so we don't allow + here.
+ elem: Box::new(input.call(Type::without_plus)?),
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeBareFn {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let args;
+ let mut variadic = None;
+
+ Ok(TypeBareFn {
+ lifetimes: input.parse()?,
+ unsafety: input.parse()?,
+ abi: input.parse()?,
+ fn_token: input.parse()?,
+ paren_token: parenthesized!(args in input),
+ inputs: {
+ let mut inputs = Punctuated::new();
+
+ while !args.is_empty() {
+ let attrs = args.call(Attribute::parse_outer)?;
+
+ if inputs.empty_or_trailing()
+ && (args.peek(Token![...])
+ || args.peek(Ident)
+ && args.peek2(Token![:])
+ && args.peek3(Token![...]))
+ {
+ variadic = Some(parse_bare_variadic(&args, attrs)?);
+ break;
+ }
+
+ let allow_self = inputs.is_empty();
+ let arg = parse_bare_fn_arg(&args, allow_self)?;
+ inputs.push_value(BareFnArg { attrs, ..arg });
+ if args.is_empty() {
+ break;
+ }
+
+ let comma = args.parse()?;
+ inputs.push_punct(comma);
+ }
+
+ inputs
+ },
+ variadic,
+ output: input.call(ReturnType::without_plus)?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeNever {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(TypeNever {
+ bang_token: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeInfer {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(TypeInfer {
+ underscore_token: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeTuple {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let content;
+ let paren_token = parenthesized!(content in input);
+
+ if content.is_empty() {
+ return Ok(TypeTuple {
+ paren_token,
+ elems: Punctuated::new(),
+ });
+ }
+
+ let first: Type = content.parse()?;
+ Ok(TypeTuple {
+ paren_token,
+ elems: {
+ let mut elems = Punctuated::new();
+ elems.push_value(first);
+ elems.push_punct(content.parse()?);
+ while !content.is_empty() {
+ elems.push_value(content.parse()?);
+ if content.is_empty() {
+ break;
+ }
+ elems.push_punct(content.parse()?);
+ }
+ elems
+ },
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeMacro {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(TypeMacro {
+ mac: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypePath {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let expr_style = false;
+ let (qself, path) = path::parsing::qpath(input, expr_style)?;
+ Ok(TypePath { qself, path })
+ }
+ }
+
+ impl ReturnType {
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn without_plus(input: ParseStream) -> Result<Self> {
+ let allow_plus = false;
+ Self::parse(input, allow_plus)
+ }
+
+ pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
+ if input.peek(Token![->]) {
+ let arrow = input.parse()?;
+ let allow_group_generic = true;
+ let ty = ambig_ty(input, allow_plus, allow_group_generic)?;
+ Ok(ReturnType::Type(arrow, Box::new(ty)))
+ } else {
+ Ok(ReturnType::Default)
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for ReturnType {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_plus = true;
+ Self::parse(input, allow_plus)
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeTraitObject {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_plus = true;
+ Self::parse(input, allow_plus)
+ }
+ }
+
+ impl TypeTraitObject {
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn without_plus(input: ParseStream) -> Result<Self> {
+ let allow_plus = false;
+ Self::parse(input, allow_plus)
+ }
+
+ // Only allow multiple trait references if allow_plus is true.
+ pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
+ let dyn_token: Option<Token![dyn]> = input.parse()?;
+ let dyn_span = match &dyn_token {
+ Some(token) => token.span,
+ None => input.span(),
+ };
+ let bounds = Self::parse_bounds(dyn_span, input, allow_plus)?;
+ Ok(TypeTraitObject { dyn_token, bounds })
+ }
+
+ fn parse_bounds(
+ dyn_span: Span,
+ input: ParseStream,
+ allow_plus: bool,
+ ) -> Result<Punctuated<TypeParamBound, Token![+]>> {
+ let bounds = TypeParamBound::parse_multiple(input, allow_plus)?;
+ let mut last_lifetime_span = None;
+ let mut at_least_one_trait = false;
+ for bound in &bounds {
+ match bound {
+ TypeParamBound::Trait(_) | TypeParamBound::Verbatim(_) => {
+ at_least_one_trait = true;
+ break;
+ }
+ TypeParamBound::Lifetime(lifetime) => {
+ last_lifetime_span = Some(lifetime.ident.span());
+ }
+ }
+ }
+ // Just lifetimes like `'a + 'b` is not a TraitObject.
+ if !at_least_one_trait {
+ let msg = "at least one trait is required for an object type";
+ return Err(error::new2(dyn_span, last_lifetime_span.unwrap(), msg));
+ }
+ Ok(bounds)
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeImplTrait {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_plus = true;
+ Self::parse(input, allow_plus)
+ }
+ }
+
+ impl TypeImplTrait {
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ pub fn without_plus(input: ParseStream) -> Result<Self> {
+ let allow_plus = false;
+ Self::parse(input, allow_plus)
+ }
+
+ pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
+ let impl_token: Token![impl] = input.parse()?;
+ let bounds = TypeParamBound::parse_multiple(input, allow_plus)?;
+ let mut last_lifetime_span = None;
+ let mut at_least_one_trait = false;
+ for bound in &bounds {
+ match bound {
+ TypeParamBound::Trait(_) | TypeParamBound::Verbatim(_) => {
+ at_least_one_trait = true;
+ break;
+ }
+ TypeParamBound::Lifetime(lifetime) => {
+ last_lifetime_span = Some(lifetime.ident.span());
+ }
+ }
+ }
+ if !at_least_one_trait {
+ let msg = "at least one trait must be specified";
+ return Err(error::new2(
+ impl_token.span,
+ last_lifetime_span.unwrap(),
+ msg,
+ ));
+ }
+ Ok(TypeImplTrait { impl_token, bounds })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeGroup {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let group = crate::group::parse_group(input)?;
+ Ok(TypeGroup {
+ group_token: group.token,
+ elem: group.content.parse()?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for TypeParen {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_plus = false;
+ Self::parse(input, allow_plus)
+ }
+ }
+
+ impl TypeParen {
+ fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
+ let content;
+ Ok(TypeParen {
+ paren_token: parenthesized!(content in input),
+ elem: Box::new({
+ let allow_group_generic = true;
+ ambig_ty(&content, allow_plus, allow_group_generic)?
+ }),
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for BareFnArg {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let allow_self = false;
+ parse_bare_fn_arg(input, allow_self)
+ }
+ }
+
+ fn parse_bare_fn_arg(input: ParseStream, allow_self: bool) -> Result<BareFnArg> {
+ let attrs = input.call(Attribute::parse_outer)?;
+
+ let begin = input.fork();
+
+ let has_mut_self = allow_self && input.peek(Token![mut]) && input.peek2(Token![self]);
+ if has_mut_self {
+ input.parse::<Token![mut]>()?;
+ }
+
+ let mut has_self = false;
+ let mut name = if (input.peek(Ident) || input.peek(Token![_]) || {
+ has_self = allow_self && input.peek(Token![self]);
+ has_self
+ }) && input.peek2(Token![:])
+ && !input.peek2(Token![::])
+ {
+ let name = input.call(Ident::parse_any)?;
+ let colon: Token![:] = input.parse()?;
+ Some((name, colon))
+ } else {
+ has_self = false;
+ None
+ };
+
+ let ty = if allow_self && !has_self && input.peek(Token![mut]) && input.peek2(Token![self])
+ {
+ input.parse::<Token![mut]>()?;
+ input.parse::<Token![self]>()?;
+ None
+ } else if has_mut_self && name.is_none() {
+ input.parse::<Token![self]>()?;
+ None
+ } else {
+ Some(input.parse()?)
+ };
+
+ let ty = match ty {
+ Some(ty) if !has_mut_self => ty,
+ _ => {
+ name = None;
+ Type::Verbatim(verbatim::between(&begin, input))
+ }
+ };
+
+ Ok(BareFnArg { attrs, name, ty })
+ }
+
+ fn parse_bare_variadic(input: ParseStream, attrs: Vec<Attribute>) -> Result<BareVariadic> {
+ Ok(BareVariadic {
+ attrs,
+ name: if input.peek(Ident) || input.peek(Token![_]) {
+ let name = input.call(Ident::parse_any)?;
+ let colon: Token![:] = input.parse()?;
+ Some((name, colon))
+ } else {
+ None
+ },
+ dots: input.parse()?,
+ comma: input.parse()?,
+ })
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Abi {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(Abi {
+ extern_token: input.parse()?,
+ name: input.parse()?,
+ })
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
+ impl Parse for Option<Abi> {
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![extern]) {
+ input.parse().map(Some)
+ } else {
+ Ok(None)
+ }
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use crate::attr::FilterAttrs;
+ use crate::path;
+ use crate::print::TokensOrDefault;
+ use crate::ty::{
+ Abi, BareFnArg, BareVariadic, ReturnType, TypeArray, TypeBareFn, TypeGroup, TypeImplTrait,
+ TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr, TypeReference, TypeSlice,
+ TypeTraitObject, TypeTuple,
+ };
+ use proc_macro2::TokenStream;
+ use quote::{ToTokens, TokenStreamExt};
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeSlice {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.bracket_token.surround(tokens, |tokens| {
+ self.elem.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeArray {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.bracket_token.surround(tokens, |tokens| {
+ self.elem.to_tokens(tokens);
+ self.semi_token.to_tokens(tokens);
+ self.len.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypePtr {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.star_token.to_tokens(tokens);
+ match &self.mutability {
+ Some(tok) => tok.to_tokens(tokens),
+ None => {
+ TokensOrDefault(&self.const_token).to_tokens(tokens);
+ }
+ }
+ self.elem.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeReference {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.and_token.to_tokens(tokens);
+ self.lifetime.to_tokens(tokens);
+ self.mutability.to_tokens(tokens);
+ self.elem.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeBareFn {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.lifetimes.to_tokens(tokens);
+ self.unsafety.to_tokens(tokens);
+ self.abi.to_tokens(tokens);
+ self.fn_token.to_tokens(tokens);
+ self.paren_token.surround(tokens, |tokens| {
+ self.inputs.to_tokens(tokens);
+ if let Some(variadic) = &self.variadic {
+ if !self.inputs.empty_or_trailing() {
+ let span = variadic.dots.spans[0];
+ Token.to_tokens(tokens);
+ }
+ variadic.to_tokens(tokens);
+ }
+ });
+ self.output.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeNever {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.bang_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeTuple {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.paren_token.surround(tokens, |tokens| {
+ self.elems.to_tokens(tokens);
+ // If we only have one argument, we need a trailing comma to
+ // distinguish TypeTuple from TypeParen.
+ if self.elems.len() == 1 && !self.elems.trailing_punct() {
+ <Token![,]>::default().to_tokens(tokens);
+ }
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypePath {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ path::printing::print_path(tokens, &self.qself, &self.path);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeTraitObject {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.dyn_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeImplTrait {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.impl_token.to_tokens(tokens);
+ self.bounds.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeGroup {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.group_token.surround(tokens, |tokens| {
+ self.elem.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeParen {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.paren_token.surround(tokens, |tokens| {
+ self.elem.to_tokens(tokens);
+ });
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeInfer {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.underscore_token.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for TypeMacro {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.mac.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for ReturnType {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ ReturnType::Default => {}
+ ReturnType::Type(arrow, ty) => {
+ arrow.to_tokens(tokens);
+ ty.to_tokens(tokens);
+ }
+ }
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for BareFnArg {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ if let Some((name, colon)) = &self.name {
+ name.to_tokens(tokens);
+ colon.to_tokens(tokens);
+ }
+ self.ty.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for BareVariadic {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.append_all(self.attrs.outer());
+ if let Some((name, colon)) = &self.name {
+ name.to_tokens(tokens);
+ colon.to_tokens(tokens);
+ }
+ self.dots.to_tokens(tokens);
+ self.comma.to_tokens(tokens);
+ }
+ }
+
+ #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
+ impl ToTokens for Abi {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.extern_token.to_tokens(tokens);
+ self.name.to_tokens(tokens);
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/verbatim.rs b/rust/hw/char/pl011/vendor/syn/src/verbatim.rs
new file mode 100644
index 0000000000..54dc1cfa0d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/verbatim.rs
@@ -0,0 +1,33 @@
+use crate::parse::ParseStream;
+use proc_macro2::{Delimiter, TokenStream};
+use std::cmp::Ordering;
+use std::iter;
+
+pub(crate) fn between<'a>(begin: ParseStream<'a>, end: ParseStream<'a>) -> TokenStream {
+ let end = end.cursor();
+ let mut cursor = begin.cursor();
+ assert!(crate::buffer::same_buffer(end, cursor));
+
+ let mut tokens = TokenStream::new();
+ while cursor != end {
+ let (tt, next) = cursor.token_tree().unwrap();
+
+ if crate::buffer::cmp_assuming_same_buffer(end, next) == Ordering::Less {
+ // A syntax node can cross the boundary of a None-delimited group
+ // due to such groups being transparent to the parser in most cases.
+ // Any time this occurs the group is known to be semantically
+ // irrelevant. https://github.com/dtolnay/syn/issues/1235
+ if let Some((inside, _span, after)) = cursor.group(Delimiter::None) {
+ assert!(next == after);
+ cursor = inside;
+ continue;
+ } else {
+ panic!("verbatim end must not be inside a delimited group");
+ }
+ }
+
+ tokens.extend(iter::once(tt));
+ cursor = next;
+ }
+ tokens
+}
diff --git a/rust/hw/char/pl011/vendor/syn/src/whitespace.rs b/rust/hw/char/pl011/vendor/syn/src/whitespace.rs
new file mode 100644
index 0000000000..a50b5069a6
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/src/whitespace.rs
@@ -0,0 +1,65 @@
+pub(crate) fn skip(mut s: &str) -> &str {
+ 'skip: while !s.is_empty() {
+ let byte = s.as_bytes()[0];
+ if byte == b'/' {
+ if s.starts_with("//")
+ && (!s.starts_with("///") || s.starts_with("////"))
+ && !s.starts_with("//!")
+ {
+ if let Some(i) = s.find('\n') {
+ s = &s[i + 1..];
+ continue;
+ } else {
+ return "";
+ }
+ } else if s.starts_with("/**/") {
+ s = &s[4..];
+ continue;
+ } else if s.starts_with("/*")
+ && (!s.starts_with("/**") || s.starts_with("/***"))
+ && !s.starts_with("/*!")
+ {
+ let mut depth = 0;
+ let bytes = s.as_bytes();
+ let mut i = 0;
+ let upper = bytes.len() - 1;
+ while i < upper {
+ if bytes[i] == b'/' && bytes[i + 1] == b'*' {
+ depth += 1;
+ i += 1; // eat '*'
+ } else if bytes[i] == b'*' && bytes[i + 1] == b'/' {
+ depth -= 1;
+ if depth == 0 {
+ s = &s[i + 2..];
+ continue 'skip;
+ }
+ i += 1; // eat '/'
+ }
+ i += 1;
+ }
+ return s;
+ }
+ }
+ match byte {
+ b' ' | 0x09..=0x0D => {
+ s = &s[1..];
+ continue;
+ }
+ b if b <= 0x7F => {}
+ _ => {
+ let ch = s.chars().next().unwrap();
+ if is_whitespace(ch) {
+ s = &s[ch.len_utf8()..];
+ continue;
+ }
+ }
+ }
+ return s;
+ }
+ s
+}
+
+fn is_whitespace(ch: char) -> bool {
+ // Rust treats left-to-right mark and right-to-left mark as whitespace
+ ch.is_whitespace() || ch == '\u{200e}' || ch == '\u{200f}'
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/common/eq.rs b/rust/hw/char/pl011/vendor/syn/tests/common/eq.rs
new file mode 100644
index 0000000000..b44ea3660d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/common/eq.rs
@@ -0,0 +1,900 @@
+#![allow(unused_macro_rules)]
+
+extern crate rustc_ast;
+extern crate rustc_data_structures;
+extern crate rustc_driver;
+extern crate rustc_span;
+extern crate thin_vec;
+
+use rustc_ast::ast::AngleBracketedArg;
+use rustc_ast::ast::AngleBracketedArgs;
+use rustc_ast::ast::AnonConst;
+use rustc_ast::ast::Arm;
+use rustc_ast::ast::AssocConstraint;
+use rustc_ast::ast::AssocConstraintKind;
+use rustc_ast::ast::AssocItemKind;
+use rustc_ast::ast::AttrArgs;
+use rustc_ast::ast::AttrArgsEq;
+use rustc_ast::ast::AttrId;
+use rustc_ast::ast::AttrItem;
+use rustc_ast::ast::AttrKind;
+use rustc_ast::ast::AttrStyle;
+use rustc_ast::ast::Attribute;
+use rustc_ast::ast::BareFnTy;
+use rustc_ast::ast::BinOpKind;
+use rustc_ast::ast::BindingMode;
+use rustc_ast::ast::Block;
+use rustc_ast::ast::BlockCheckMode;
+use rustc_ast::ast::BorrowKind;
+use rustc_ast::ast::BoundAsyncness;
+use rustc_ast::ast::BoundConstness;
+use rustc_ast::ast::BoundPolarity;
+use rustc_ast::ast::ByRef;
+use rustc_ast::ast::CaptureBy;
+use rustc_ast::ast::Closure;
+use rustc_ast::ast::ClosureBinder;
+use rustc_ast::ast::Const;
+use rustc_ast::ast::ConstItem;
+use rustc_ast::ast::CoroutineKind;
+use rustc_ast::ast::Crate;
+use rustc_ast::ast::Defaultness;
+use rustc_ast::ast::Delegation;
+use rustc_ast::ast::DelegationMac;
+use rustc_ast::ast::DelimArgs;
+use rustc_ast::ast::EnumDef;
+use rustc_ast::ast::Expr;
+use rustc_ast::ast::ExprField;
+use rustc_ast::ast::ExprKind;
+use rustc_ast::ast::Extern;
+use rustc_ast::ast::FieldDef;
+use rustc_ast::ast::FloatTy;
+use rustc_ast::ast::Fn;
+use rustc_ast::ast::FnDecl;
+use rustc_ast::ast::FnHeader;
+use rustc_ast::ast::FnRetTy;
+use rustc_ast::ast::FnSig;
+use rustc_ast::ast::ForLoopKind;
+use rustc_ast::ast::ForeignItemKind;
+use rustc_ast::ast::ForeignMod;
+use rustc_ast::ast::FormatAlignment;
+use rustc_ast::ast::FormatArgPosition;
+use rustc_ast::ast::FormatArgPositionKind;
+use rustc_ast::ast::FormatArgs;
+use rustc_ast::ast::FormatArgsPiece;
+use rustc_ast::ast::FormatArgument;
+use rustc_ast::ast::FormatArgumentKind;
+use rustc_ast::ast::FormatArguments;
+use rustc_ast::ast::FormatCount;
+use rustc_ast::ast::FormatDebugHex;
+use rustc_ast::ast::FormatOptions;
+use rustc_ast::ast::FormatPlaceholder;
+use rustc_ast::ast::FormatSign;
+use rustc_ast::ast::FormatTrait;
+use rustc_ast::ast::GenBlockKind;
+use rustc_ast::ast::GenericArg;
+use rustc_ast::ast::GenericArgs;
+use rustc_ast::ast::GenericBound;
+use rustc_ast::ast::GenericParam;
+use rustc_ast::ast::GenericParamKind;
+use rustc_ast::ast::Generics;
+use rustc_ast::ast::Impl;
+use rustc_ast::ast::ImplPolarity;
+use rustc_ast::ast::Inline;
+use rustc_ast::ast::InlineAsm;
+use rustc_ast::ast::InlineAsmOperand;
+use rustc_ast::ast::InlineAsmOptions;
+use rustc_ast::ast::InlineAsmRegOrRegClass;
+use rustc_ast::ast::InlineAsmSym;
+use rustc_ast::ast::InlineAsmTemplatePiece;
+use rustc_ast::ast::IntTy;
+use rustc_ast::ast::IsAuto;
+use rustc_ast::ast::Item;
+use rustc_ast::ast::ItemKind;
+use rustc_ast::ast::Label;
+use rustc_ast::ast::Lifetime;
+use rustc_ast::ast::LitFloatType;
+use rustc_ast::ast::LitIntType;
+use rustc_ast::ast::LitKind;
+use rustc_ast::ast::Local;
+use rustc_ast::ast::LocalKind;
+use rustc_ast::ast::MacCall;
+use rustc_ast::ast::MacCallStmt;
+use rustc_ast::ast::MacStmtStyle;
+use rustc_ast::ast::MacroDef;
+use rustc_ast::ast::MatchKind;
+use rustc_ast::ast::MetaItemLit;
+use rustc_ast::ast::MethodCall;
+use rustc_ast::ast::ModKind;
+use rustc_ast::ast::ModSpans;
+use rustc_ast::ast::Movability;
+use rustc_ast::ast::MutTy;
+use rustc_ast::ast::Mutability;
+use rustc_ast::ast::NodeId;
+use rustc_ast::ast::NormalAttr;
+use rustc_ast::ast::Param;
+use rustc_ast::ast::ParenthesizedArgs;
+use rustc_ast::ast::Pat;
+use rustc_ast::ast::PatField;
+use rustc_ast::ast::PatFieldsRest;
+use rustc_ast::ast::PatKind;
+use rustc_ast::ast::Path;
+use rustc_ast::ast::PathSegment;
+use rustc_ast::ast::PolyTraitRef;
+use rustc_ast::ast::PreciseCapturingArg;
+use rustc_ast::ast::QSelf;
+use rustc_ast::ast::RangeEnd;
+use rustc_ast::ast::RangeLimits;
+use rustc_ast::ast::RangeSyntax;
+use rustc_ast::ast::Recovered;
+use rustc_ast::ast::Safety;
+use rustc_ast::ast::StaticForeignItem;
+use rustc_ast::ast::StaticItem;
+use rustc_ast::ast::Stmt;
+use rustc_ast::ast::StmtKind;
+use rustc_ast::ast::StrLit;
+use rustc_ast::ast::StrStyle;
+use rustc_ast::ast::StructExpr;
+use rustc_ast::ast::StructRest;
+use rustc_ast::ast::Term;
+use rustc_ast::ast::Trait;
+use rustc_ast::ast::TraitBoundModifiers;
+use rustc_ast::ast::TraitObjectSyntax;
+use rustc_ast::ast::TraitRef;
+use rustc_ast::ast::Ty;
+use rustc_ast::ast::TyAlias;
+use rustc_ast::ast::TyAliasWhereClause;
+use rustc_ast::ast::TyAliasWhereClauses;
+use rustc_ast::ast::TyKind;
+use rustc_ast::ast::UintTy;
+use rustc_ast::ast::UnOp;
+use rustc_ast::ast::UnsafeSource;
+use rustc_ast::ast::UseTree;
+use rustc_ast::ast::UseTreeKind;
+use rustc_ast::ast::Variant;
+use rustc_ast::ast::VariantData;
+use rustc_ast::ast::Visibility;
+use rustc_ast::ast::VisibilityKind;
+use rustc_ast::ast::WhereBoundPredicate;
+use rustc_ast::ast::WhereClause;
+use rustc_ast::ast::WhereEqPredicate;
+use rustc_ast::ast::WherePredicate;
+use rustc_ast::ast::WhereRegionPredicate;
+use rustc_ast::ptr::P;
+use rustc_ast::token::{
+ self, CommentKind, Delimiter, IdentIsRaw, Lit, Nonterminal, Token, TokenKind,
+};
+use rustc_ast::tokenstream::{
+ AttrTokenStream, AttrTokenTree, AttributesData, DelimSpacing, DelimSpan, LazyAttrTokenStream,
+ Spacing, TokenStream, TokenTree,
+};
+use rustc_data_structures::packed::Pu128;
+use rustc_data_structures::sync::Lrc;
+use rustc_span::source_map::Spanned;
+use rustc_span::symbol::{sym, Ident};
+use rustc_span::{ErrorGuaranteed, Span, Symbol, SyntaxContext, DUMMY_SP};
+use std::collections::HashMap;
+use std::hash::{BuildHasher, Hash};
+use thin_vec::ThinVec;
+
+pub trait SpanlessEq {
+ fn eq(&self, other: &Self) -> bool;
+}
+
+impl<T: ?Sized + SpanlessEq> SpanlessEq for Box<T> {
+ fn eq(&self, other: &Self) -> bool {
+ SpanlessEq::eq(&**self, &**other)
+ }
+}
+
+impl<T: ?Sized + SpanlessEq> SpanlessEq for P<T> {
+ fn eq(&self, other: &Self) -> bool {
+ SpanlessEq::eq(&**self, &**other)
+ }
+}
+
+impl<T: ?Sized + SpanlessEq> SpanlessEq for Lrc<T> {
+ fn eq(&self, other: &Self) -> bool {
+ SpanlessEq::eq(&**self, &**other)
+ }
+}
+
+impl<T: SpanlessEq> SpanlessEq for Option<T> {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (None, None) => true,
+ (Some(this), Some(other)) => SpanlessEq::eq(this, other),
+ _ => false,
+ }
+ }
+}
+
+impl<T: SpanlessEq, E: SpanlessEq> SpanlessEq for Result<T, E> {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (Ok(this), Ok(other)) => SpanlessEq::eq(this, other),
+ (Err(this), Err(other)) => SpanlessEq::eq(this, other),
+ _ => false,
+ }
+ }
+}
+
+impl<T: SpanlessEq> SpanlessEq for [T] {
+ fn eq(&self, other: &Self) -> bool {
+ self.len() == other.len() && self.iter().zip(other).all(|(a, b)| SpanlessEq::eq(a, b))
+ }
+}
+
+impl<T: SpanlessEq> SpanlessEq for Vec<T> {
+ fn eq(&self, other: &Self) -> bool {
+ <[T] as SpanlessEq>::eq(self, other)
+ }
+}
+
+impl<T: SpanlessEq> SpanlessEq for ThinVec<T> {
+ fn eq(&self, other: &Self) -> bool {
+ self.len() == other.len()
+ && self
+ .iter()
+ .zip(other.iter())
+ .all(|(a, b)| SpanlessEq::eq(a, b))
+ }
+}
+
+impl<K: Eq + Hash, V: SpanlessEq, S: BuildHasher> SpanlessEq for HashMap<K, V, S> {
+ fn eq(&self, other: &Self) -> bool {
+ self.len() == other.len()
+ && self.iter().all(|(key, this_v)| {
+ other
+ .get(key)
+ .map_or(false, |other_v| SpanlessEq::eq(this_v, other_v))
+ })
+ }
+}
+
+impl<T: SpanlessEq> SpanlessEq for Spanned<T> {
+ fn eq(&self, other: &Self) -> bool {
+ SpanlessEq::eq(&self.node, &other.node)
+ }
+}
+
+impl<A: SpanlessEq, B: SpanlessEq> SpanlessEq for (A, B) {
+ fn eq(&self, other: &Self) -> bool {
+ SpanlessEq::eq(&self.0, &other.0) && SpanlessEq::eq(&self.1, &other.1)
+ }
+}
+
+impl<A: SpanlessEq, B: SpanlessEq, C: SpanlessEq> SpanlessEq for (A, B, C) {
+ fn eq(&self, other: &Self) -> bool {
+ SpanlessEq::eq(&self.0, &other.0)
+ && SpanlessEq::eq(&self.1, &other.1)
+ && SpanlessEq::eq(&self.2, &other.2)
+ }
+}
+
+macro_rules! spanless_eq_true {
+ ($name:ty) => {
+ impl SpanlessEq for $name {
+ fn eq(&self, _other: &Self) -> bool {
+ true
+ }
+ }
+ };
+}
+
+spanless_eq_true!(Span);
+spanless_eq_true!(DelimSpan);
+spanless_eq_true!(AttrId);
+spanless_eq_true!(NodeId);
+spanless_eq_true!(SyntaxContext);
+spanless_eq_true!(Spacing);
+
+macro_rules! spanless_eq_partial_eq {
+ ($name:ty) => {
+ impl SpanlessEq for $name {
+ fn eq(&self, other: &Self) -> bool {
+ PartialEq::eq(self, other)
+ }
+ }
+ };
+}
+
+spanless_eq_partial_eq!(bool);
+spanless_eq_partial_eq!(u8);
+spanless_eq_partial_eq!(u16);
+spanless_eq_partial_eq!(u32);
+spanless_eq_partial_eq!(u128);
+spanless_eq_partial_eq!(usize);
+spanless_eq_partial_eq!(char);
+spanless_eq_partial_eq!(String);
+spanless_eq_partial_eq!(Pu128);
+spanless_eq_partial_eq!(Symbol);
+spanless_eq_partial_eq!(CommentKind);
+spanless_eq_partial_eq!(Delimiter);
+spanless_eq_partial_eq!(InlineAsmOptions);
+spanless_eq_partial_eq!(token::LitKind);
+spanless_eq_partial_eq!(ErrorGuaranteed);
+
+macro_rules! spanless_eq_struct {
+ {
+ $($name:ident)::+ $(<$param:ident>)?
+ $([$field:tt $this:ident $other:ident])*
+ $(![$ignore:tt])*;
+ } => {
+ impl $(<$param: SpanlessEq>)* SpanlessEq for $($name)::+ $(<$param>)* {
+ fn eq(&self, other: &Self) -> bool {
+ let $($name)::+ { $($field: $this,)* $($ignore: _,)* } = self;
+ let $($name)::+ { $($field: $other,)* $($ignore: _,)* } = other;
+ true $(&& SpanlessEq::eq($this, $other))*
+ }
+ }
+ };
+
+ {
+ $($name:ident)::+ $(<$param:ident>)?
+ $([$field:tt $this:ident $other:ident])*
+ $(![$ignore:tt])*;
+ !$next:tt
+ $($rest:tt)*
+ } => {
+ spanless_eq_struct! {
+ $($name)::+ $(<$param>)*
+ $([$field $this $other])*
+ $(![$ignore])*
+ ![$next];
+ $($rest)*
+ }
+ };
+
+ {
+ $($name:ident)::+ $(<$param:ident>)?
+ $([$field:tt $this:ident $other:ident])*
+ $(![$ignore:tt])*;
+ $next:tt
+ $($rest:tt)*
+ } => {
+ spanless_eq_struct! {
+ $($name)::+ $(<$param>)*
+ $([$field $this $other])*
+ [$next this other]
+ $(![$ignore])*;
+ $($rest)*
+ }
+ };
+}
+
+macro_rules! spanless_eq_enum {
+ {
+ $($name:ident)::+;
+ $([$($variant:ident)::+; $([$field:tt $this:ident $other:ident])* $(![$ignore:tt])*])*
+ } => {
+ impl SpanlessEq for $($name)::+ {
+ fn eq(&self, other: &Self) -> bool {
+ match self {
+ $(
+ $($variant)::+ { .. } => {}
+ )*
+ }
+ #[allow(unreachable_patterns)]
+ match (self, other) {
+ $(
+ (
+ $($variant)::+ { $($field: $this,)* $($ignore: _,)* },
+ $($variant)::+ { $($field: $other,)* $($ignore: _,)* },
+ ) => {
+ true $(&& SpanlessEq::eq($this, $other))*
+ }
+ )*
+ _ => false,
+ }
+ }
+ }
+ };
+
+ {
+ $($name:ident)::+;
+ $([$($variant:ident)::+; $($fields:tt)*])*
+ $next:ident [$([$($named:tt)*])* $(![$ignore:tt])*] (!$i:tt $($field:tt)*)
+ $($rest:tt)*
+ } => {
+ spanless_eq_enum! {
+ $($name)::+;
+ $([$($variant)::+; $($fields)*])*
+ $next [$([$($named)*])* $(![$ignore])* ![$i]] ($($field)*)
+ $($rest)*
+ }
+ };
+
+ {
+ $($name:ident)::+;
+ $([$($variant:ident)::+; $($fields:tt)*])*
+ $next:ident [$([$($named:tt)*])* $(![$ignore:tt])*] ($i:tt $($field:tt)*)
+ $($rest:tt)*
+ } => {
+ spanless_eq_enum! {
+ $($name)::+;
+ $([$($variant)::+; $($fields)*])*
+ $next [$([$($named)*])* [$i this other] $(![$ignore])*] ($($field)*)
+ $($rest)*
+ }
+ };
+
+ {
+ $($name:ident)::+;
+ $([$($variant:ident)::+; $($fields:tt)*])*
+ $next:ident [$($named:tt)*] ()
+ $($rest:tt)*
+ } => {
+ spanless_eq_enum! {
+ $($name)::+;
+ $([$($variant)::+; $($fields)*])*
+ [$($name)::+::$next; $($named)*]
+ $($rest)*
+ }
+ };
+
+ {
+ $($name:ident)::+;
+ $([$($variant:ident)::+; $($fields:tt)*])*
+ $next:ident ($($field:tt)*)
+ $($rest:tt)*
+ } => {
+ spanless_eq_enum! {
+ $($name)::+;
+ $([$($variant)::+; $($fields)*])*
+ $next [] ($($field)*)
+ $($rest)*
+ }
+ };
+
+ {
+ $($name:ident)::+;
+ $([$($variant:ident)::+; $($fields:tt)*])*
+ $next:ident
+ $($rest:tt)*
+ } => {
+ spanless_eq_enum! {
+ $($name)::+;
+ $([$($variant)::+; $($fields)*])*
+ [$($name)::+::$next;]
+ $($rest)*
+ }
+ };
+}
+
+spanless_eq_struct!(AngleBracketedArgs; span args);
+spanless_eq_struct!(AnonConst; id value);
+spanless_eq_struct!(Arm; attrs pat guard body span id is_placeholder);
+spanless_eq_struct!(AssocConstraint; id ident gen_args kind span);
+spanless_eq_struct!(AttrItem; path args tokens);
+spanless_eq_struct!(AttrTokenStream; 0);
+spanless_eq_struct!(Attribute; kind id style span);
+spanless_eq_struct!(AttributesData; attrs tokens);
+spanless_eq_struct!(BareFnTy; safety ext generic_params decl decl_span);
+spanless_eq_struct!(BindingMode; 0 1);
+spanless_eq_struct!(Block; stmts id rules span tokens could_be_bare_literal);
+spanless_eq_struct!(Closure; binder capture_clause constness coroutine_kind movability fn_decl body !fn_decl_span !fn_arg_span);
+spanless_eq_struct!(ConstItem; defaultness generics ty expr);
+spanless_eq_struct!(Crate; attrs items spans id is_placeholder);
+spanless_eq_struct!(Delegation; id qself path rename body);
+spanless_eq_struct!(DelegationMac; qself prefix suffixes body);
+spanless_eq_struct!(DelimArgs; dspan delim tokens);
+spanless_eq_struct!(DelimSpacing; open close);
+spanless_eq_struct!(EnumDef; variants);
+spanless_eq_struct!(Expr; id kind span attrs !tokens);
+spanless_eq_struct!(ExprField; attrs id span ident expr is_shorthand is_placeholder);
+spanless_eq_struct!(FieldDef; attrs id span vis ident ty is_placeholder);
+spanless_eq_struct!(Fn; defaultness generics sig body);
+spanless_eq_struct!(FnDecl; inputs output);
+spanless_eq_struct!(FnHeader; constness coroutine_kind safety ext);
+spanless_eq_struct!(FnSig; header decl span);
+spanless_eq_struct!(ForeignMod; safety abi items);
+spanless_eq_struct!(FormatArgPosition; index kind span);
+spanless_eq_struct!(FormatArgs; span template arguments);
+spanless_eq_struct!(FormatArgument; kind expr);
+spanless_eq_struct!(FormatOptions; width precision alignment fill sign alternate zero_pad debug_hex);
+spanless_eq_struct!(FormatPlaceholder; argument span format_trait format_options);
+spanless_eq_struct!(GenericParam; id ident attrs bounds is_placeholder kind !colon_span);
+spanless_eq_struct!(Generics; params where_clause span);
+spanless_eq_struct!(Impl; defaultness safety generics constness polarity of_trait self_ty items);
+spanless_eq_struct!(InlineAsm; template template_strs operands clobber_abis options line_spans);
+spanless_eq_struct!(InlineAsmSym; id qself path);
+spanless_eq_struct!(Item<K>; attrs id span vis ident kind !tokens);
+spanless_eq_struct!(Label; ident);
+spanless_eq_struct!(Lifetime; id ident);
+spanless_eq_struct!(Lit; kind symbol suffix);
+spanless_eq_struct!(Local; id pat ty kind span colon_sp attrs !tokens);
+spanless_eq_struct!(MacCall; path args);
+spanless_eq_struct!(MacCallStmt; mac style attrs tokens);
+spanless_eq_struct!(MacroDef; body macro_rules);
+spanless_eq_struct!(MetaItemLit; symbol suffix kind span);
+spanless_eq_struct!(MethodCall; seg receiver args !span);
+spanless_eq_struct!(ModSpans; !inner_span !inject_use_span);
+spanless_eq_struct!(MutTy; ty mutbl);
+spanless_eq_struct!(NormalAttr; item tokens);
+spanless_eq_struct!(ParenthesizedArgs; span inputs inputs_span output);
+spanless_eq_struct!(Pat; id kind span tokens);
+spanless_eq_struct!(PatField; ident pat is_shorthand attrs id span is_placeholder);
+spanless_eq_struct!(Path; span segments tokens);
+spanless_eq_struct!(PathSegment; ident id args);
+spanless_eq_struct!(PolyTraitRef; bound_generic_params trait_ref span);
+spanless_eq_struct!(QSelf; ty path_span position);
+spanless_eq_struct!(StaticForeignItem; ty mutability expr);
+spanless_eq_struct!(StaticItem; ty mutability expr);
+spanless_eq_struct!(Stmt; id kind span);
+spanless_eq_struct!(StrLit; symbol suffix symbol_unescaped style span);
+spanless_eq_struct!(StructExpr; qself path fields rest);
+spanless_eq_struct!(Token; kind span);
+spanless_eq_struct!(Trait; safety is_auto generics bounds items);
+spanless_eq_struct!(TraitBoundModifiers; constness asyncness polarity);
+spanless_eq_struct!(TraitRef; path ref_id);
+spanless_eq_struct!(Ty; id kind span tokens);
+spanless_eq_struct!(TyAlias; defaultness generics where_clauses bounds ty);
+spanless_eq_struct!(TyAliasWhereClause; !has_where_token span);
+spanless_eq_struct!(TyAliasWhereClauses; before after !split);
+spanless_eq_struct!(UseTree; prefix kind span);
+spanless_eq_struct!(Variant; attrs id span !vis ident data disr_expr is_placeholder);
+spanless_eq_struct!(Visibility; kind span tokens);
+spanless_eq_struct!(WhereBoundPredicate; span bound_generic_params bounded_ty bounds);
+spanless_eq_struct!(WhereClause; has_where_token predicates span);
+spanless_eq_struct!(WhereEqPredicate; span lhs_ty rhs_ty);
+spanless_eq_struct!(WhereRegionPredicate; span lifetime bounds);
+spanless_eq_enum!(AngleBracketedArg; Arg(0) Constraint(0));
+spanless_eq_enum!(AssocConstraintKind; Equality(term) Bound(bounds));
+spanless_eq_enum!(AssocItemKind; Const(0) Fn(0) Type(0) MacCall(0) Delegation(0) DelegationMac(0));
+spanless_eq_enum!(AttrArgs; Empty Delimited(0) Eq(0 1));
+spanless_eq_enum!(AttrArgsEq; Ast(0) Hir(0));
+spanless_eq_enum!(AttrStyle; Outer Inner);
+spanless_eq_enum!(AttrTokenTree; Token(0 1) Delimited(0 1 2 3) Attributes(0));
+spanless_eq_enum!(BinOpKind; Add Sub Mul Div Rem And Or BitXor BitAnd BitOr Shl Shr Eq Lt Le Ne Ge Gt);
+spanless_eq_enum!(BlockCheckMode; Default Unsafe(0));
+spanless_eq_enum!(BorrowKind; Ref Raw);
+spanless_eq_enum!(BoundAsyncness; Normal Async(0));
+spanless_eq_enum!(BoundConstness; Never Always(0) Maybe(0));
+spanless_eq_enum!(BoundPolarity; Positive Negative(0) Maybe(0));
+spanless_eq_enum!(ByRef; Yes(0) No);
+spanless_eq_enum!(CaptureBy; Value(move_kw) Ref);
+spanless_eq_enum!(ClosureBinder; NotPresent For(span generic_params));
+spanless_eq_enum!(Const; Yes(0) No);
+spanless_eq_enum!(Defaultness; Default(0) Final);
+spanless_eq_enum!(Extern; None Implicit(0) Explicit(0 1));
+spanless_eq_enum!(FloatTy; F16 F32 F64 F128);
+spanless_eq_enum!(FnRetTy; Default(0) Ty(0));
+spanless_eq_enum!(ForLoopKind; For ForAwait);
+spanless_eq_enum!(ForeignItemKind; Static(0) Fn(0) TyAlias(0) MacCall(0));
+spanless_eq_enum!(FormatAlignment; Left Right Center);
+spanless_eq_enum!(FormatArgPositionKind; Implicit Number Named);
+spanless_eq_enum!(FormatArgsPiece; Literal(0) Placeholder(0));
+spanless_eq_enum!(FormatArgumentKind; Normal Named(0) Captured(0));
+spanless_eq_enum!(FormatCount; Literal(0) Argument(0));
+spanless_eq_enum!(FormatDebugHex; Lower Upper);
+spanless_eq_enum!(FormatSign; Plus Minus);
+spanless_eq_enum!(FormatTrait; Display Debug LowerExp UpperExp Octal Pointer Binary LowerHex UpperHex);
+spanless_eq_enum!(GenBlockKind; Async Gen AsyncGen);
+spanless_eq_enum!(GenericArg; Lifetime(0) Type(0) Const(0));
+spanless_eq_enum!(GenericArgs; AngleBracketed(0) Parenthesized(0));
+spanless_eq_enum!(GenericBound; Trait(0 1) Outlives(0));
+spanless_eq_enum!(GenericParamKind; Lifetime Type(default) Const(ty kw_span default));
+spanless_eq_enum!(ImplPolarity; Positive Negative(0));
+spanless_eq_enum!(Inline; Yes No);
+spanless_eq_enum!(InlineAsmRegOrRegClass; Reg(0) RegClass(0));
+spanless_eq_enum!(InlineAsmTemplatePiece; String(0) Placeholder(operand_idx modifier span));
+spanless_eq_enum!(IntTy; Isize I8 I16 I32 I64 I128);
+spanless_eq_enum!(IsAuto; Yes No);
+spanless_eq_enum!(LitFloatType; Suffixed(0) Unsuffixed);
+spanless_eq_enum!(LitIntType; Signed(0) Unsigned(0) Unsuffixed);
+spanless_eq_enum!(LocalKind; Decl Init(0) InitElse(0 1));
+spanless_eq_enum!(MacStmtStyle; Semicolon Braces NoBraces);
+spanless_eq_enum!(MatchKind; Prefix Postfix);
+spanless_eq_enum!(ModKind; Loaded(0 1 2) Unloaded);
+spanless_eq_enum!(Movability; Static Movable);
+spanless_eq_enum!(Mutability; Mut Not);
+spanless_eq_enum!(PatFieldsRest; Rest None);
+spanless_eq_enum!(PreciseCapturingArg; Lifetime(0) Arg(0 1));
+spanless_eq_enum!(RangeEnd; Included(0) Excluded);
+spanless_eq_enum!(RangeLimits; HalfOpen Closed);
+spanless_eq_enum!(Recovered; No Yes(0));
+spanless_eq_enum!(Safety; Unsafe(0) Default);
+spanless_eq_enum!(StmtKind; Let(0) Item(0) Expr(0) Semi(0) Empty MacCall(0));
+spanless_eq_enum!(StrStyle; Cooked Raw(0));
+spanless_eq_enum!(StructRest; Base(0) Rest(0) None);
+spanless_eq_enum!(Term; Ty(0) Const(0));
+spanless_eq_enum!(TokenTree; Token(0 1) Delimited(0 1 2 3));
+spanless_eq_enum!(TraitObjectSyntax; Dyn DynStar None);
+spanless_eq_enum!(UintTy; Usize U8 U16 U32 U64 U128);
+spanless_eq_enum!(UnOp; Deref Not Neg);
+spanless_eq_enum!(UnsafeSource; CompilerGenerated UserProvided);
+spanless_eq_enum!(UseTreeKind; Simple(0) Nested(items span) Glob);
+spanless_eq_enum!(VariantData; Struct(fields recovered) Tuple(0 1) Unit(0));
+spanless_eq_enum!(VisibilityKind; Public Restricted(path id shorthand) Inherited);
+spanless_eq_enum!(WherePredicate; BoundPredicate(0) RegionPredicate(0) EqPredicate(0));
+spanless_eq_enum!(CoroutineKind; Async(span closure_id return_impl_trait_id)
+ Gen(span closure_id return_impl_trait_id)
+ AsyncGen(span closure_id return_impl_trait_id));
+spanless_eq_enum!(ExprKind; Array(0) ConstBlock(0) Call(0 1) MethodCall(0)
+ Tup(0) Binary(0 1 2) Unary(0 1) Lit(0) Cast(0 1) Type(0 1) Let(0 1 2 3)
+ If(0 1 2) While(0 1 2) ForLoop(pat iter body label kind) Loop(0 1 2)
+ Match(0 1 2) Closure(0) Block(0 1) Gen(0 1 2) Await(0 1) TryBlock(0)
+ Assign(0 1 2) AssignOp(0 1 2) Field(0 1) Index(0 1 2) Underscore
+ Range(0 1 2) Path(0 1) AddrOf(0 1 2) Break(0 1) Continue(0) Ret(0)
+ InlineAsm(0) OffsetOf(0 1) MacCall(0) Struct(0) Repeat(0 1) Paren(0) Try(0)
+ Yield(0) Yeet(0) Become(0) IncludedBytes(0) FormatArgs(0) Err(0) Dummy);
+spanless_eq_enum!(InlineAsmOperand; In(reg expr) Out(reg late expr)
+ InOut(reg late expr) SplitInOut(reg late in_expr out_expr) Const(anon_const)
+ Sym(sym) Label(block));
+spanless_eq_enum!(ItemKind; ExternCrate(0) Use(0) Static(0) Const(0) Fn(0)
+ Mod(0 1) ForeignMod(0) GlobalAsm(0) TyAlias(0) Enum(0 1) Struct(0 1)
+ Union(0 1) Trait(0) TraitAlias(0 1) Impl(0) MacCall(0) MacroDef(0)
+ Delegation(0) DelegationMac(0));
+spanless_eq_enum!(LitKind; Str(0 1) ByteStr(0 1) CStr(0 1) Byte(0) Char(0)
+ Int(0 1) Float(0 1) Bool(0) Err(0));
+spanless_eq_enum!(PatKind; Wild Ident(0 1 2) Struct(0 1 2 3) TupleStruct(0 1 2)
+ Or(0) Path(0 1) Tuple(0) Box(0) Deref(0) Ref(0 1) Lit(0) Range(0 1 2)
+ Slice(0) Rest Never Paren(0) MacCall(0) Err(0));
+spanless_eq_enum!(TyKind; Slice(0) Array(0 1) Ptr(0) Ref(0 1) BareFn(0) Never
+ Tup(0) AnonStruct(0 1) AnonUnion(0 1) Path(0 1) TraitObject(0 1)
+ ImplTrait(0 1 2) Paren(0) Typeof(0) Infer ImplicitSelf MacCall(0) CVarArgs
+ Pat(0 1) Dummy Err(0));
+
+impl SpanlessEq for Ident {
+ fn eq(&self, other: &Self) -> bool {
+ self.as_str() == other.as_str()
+ }
+}
+
+impl SpanlessEq for RangeSyntax {
+ fn eq(&self, _other: &Self) -> bool {
+ match self {
+ RangeSyntax::DotDotDot | RangeSyntax::DotDotEq => true,
+ }
+ }
+}
+
+impl SpanlessEq for Param {
+ fn eq(&self, other: &Self) -> bool {
+ let Param {
+ attrs,
+ ty,
+ pat,
+ id,
+ span: _,
+ is_placeholder,
+ } = self;
+ let Param {
+ attrs: attrs2,
+ ty: ty2,
+ pat: pat2,
+ id: id2,
+ span: _,
+ is_placeholder: is_placeholder2,
+ } = other;
+ SpanlessEq::eq(id, id2)
+ && SpanlessEq::eq(is_placeholder, is_placeholder2)
+ && (matches!(ty.kind, TyKind::Err(_))
+ || matches!(ty2.kind, TyKind::Err(_))
+ || SpanlessEq::eq(attrs, attrs2)
+ && SpanlessEq::eq(ty, ty2)
+ && SpanlessEq::eq(pat, pat2))
+ }
+}
+
+impl SpanlessEq for TokenKind {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (TokenKind::Literal(this), TokenKind::Literal(other)) => SpanlessEq::eq(this, other),
+ (TokenKind::DotDotEq | TokenKind::DotDotDot, _) => match other {
+ TokenKind::DotDotEq | TokenKind::DotDotDot => true,
+ _ => false,
+ },
+ (TokenKind::Interpolated(this), TokenKind::Interpolated(other)) => {
+ let this = this.as_ref();
+ let other = other.as_ref();
+ match (this, other) {
+ (Nonterminal::NtExpr(this), Nonterminal::NtExpr(other)) => {
+ SpanlessEq::eq(this, other)
+ }
+ _ => this == other,
+ }
+ }
+ _ => self == other,
+ }
+ }
+}
+
+impl SpanlessEq for TokenStream {
+ fn eq(&self, other: &Self) -> bool {
+ let mut this_trees = self.trees();
+ let mut other_trees = other.trees();
+ loop {
+ let this = match this_trees.next() {
+ None => return other_trees.next().is_none(),
+ Some(tree) => tree,
+ };
+ let other = match other_trees.next() {
+ None => return false,
+ Some(tree) => tree,
+ };
+ if SpanlessEq::eq(this, other) {
+ continue;
+ }
+ if let (TokenTree::Token(this, _), TokenTree::Token(other, _)) = (this, other) {
+ if match (&this.kind, &other.kind) {
+ (TokenKind::Literal(this), TokenKind::Literal(other)) => {
+ SpanlessEq::eq(this, other)
+ }
+ (TokenKind::DocComment(_kind, style, symbol), TokenKind::Pound) => {
+ doc_comment(*style, *symbol, &mut other_trees)
+ }
+ (TokenKind::Pound, TokenKind::DocComment(_kind, style, symbol)) => {
+ doc_comment(*style, *symbol, &mut this_trees)
+ }
+ _ => false,
+ } {
+ continue;
+ }
+ }
+ return false;
+ }
+ }
+}
+
+fn doc_comment<'a>(
+ style: AttrStyle,
+ unescaped: Symbol,
+ trees: &mut impl Iterator<Item = &'a TokenTree>,
+) -> bool {
+ if match style {
+ AttrStyle::Outer => false,
+ AttrStyle::Inner => true,
+ } {
+ match trees.next() {
+ Some(TokenTree::Token(
+ Token {
+ kind: TokenKind::Not,
+ span: _,
+ },
+ _spacing,
+ )) => {}
+ _ => return false,
+ }
+ }
+ let stream = match trees.next() {
+ Some(TokenTree::Delimited(_span, _spacing, Delimiter::Bracket, stream)) => stream,
+ _ => return false,
+ };
+ let mut trees = stream.trees();
+ match trees.next() {
+ Some(TokenTree::Token(
+ Token {
+ kind: TokenKind::Ident(symbol, IdentIsRaw::No),
+ span: _,
+ },
+ _spacing,
+ )) if *symbol == sym::doc => {}
+ _ => return false,
+ }
+ match trees.next() {
+ Some(TokenTree::Token(
+ Token {
+ kind: TokenKind::Eq,
+ span: _,
+ },
+ _spacing,
+ )) => {}
+ _ => return false,
+ }
+ match trees.next() {
+ Some(TokenTree::Token(token, _spacing)) => {
+ is_escaped_literal_token(token, unescaped) && trees.next().is_none()
+ }
+ _ => false,
+ }
+}
+
+fn is_escaped_literal_token(token: &Token, unescaped: Symbol) -> bool {
+ match token {
+ Token {
+ kind: TokenKind::Literal(lit),
+ span: _,
+ } => match MetaItemLit::from_token_lit(*lit, DUMMY_SP) {
+ Ok(lit) => is_escaped_literal_meta_item_lit(&lit, unescaped),
+ Err(_) => false,
+ },
+ Token {
+ kind: TokenKind::Interpolated(nonterminal),
+ span: _,
+ } => match nonterminal.as_ref() {
+ Nonterminal::NtExpr(expr) => match &expr.kind {
+ ExprKind::Lit(lit) => is_escaped_lit(lit, unescaped),
+ _ => false,
+ },
+ _ => false,
+ },
+ _ => false,
+ }
+}
+
+fn is_escaped_literal_attr_args(value: &AttrArgsEq, unescaped: Symbol) -> bool {
+ match value {
+ AttrArgsEq::Ast(expr) => match &expr.kind {
+ ExprKind::Lit(lit) => is_escaped_lit(lit, unescaped),
+ _ => false,
+ },
+ AttrArgsEq::Hir(lit) => is_escaped_literal_meta_item_lit(lit, unescaped),
+ }
+}
+
+fn is_escaped_literal_meta_item_lit(lit: &MetaItemLit, unescaped: Symbol) -> bool {
+ match lit {
+ MetaItemLit {
+ symbol: _,
+ suffix: None,
+ kind,
+ span: _,
+ } => is_escaped_lit_kind(kind, unescaped),
+ _ => false,
+ }
+}
+
+fn is_escaped_lit(lit: &Lit, unescaped: Symbol) -> bool {
+ match lit {
+ Lit {
+ kind: token::LitKind::Str,
+ symbol: _,
+ suffix: None,
+ } => match LitKind::from_token_lit(*lit) {
+ Ok(lit_kind) => is_escaped_lit_kind(&lit_kind, unescaped),
+ _ => false,
+ },
+ _ => false,
+ }
+}
+
+fn is_escaped_lit_kind(kind: &LitKind, unescaped: Symbol) -> bool {
+ match kind {
+ LitKind::Str(symbol, StrStyle::Cooked) => {
+ symbol.as_str().replace('\r', "") == unescaped.as_str().replace('\r', "")
+ }
+ _ => false,
+ }
+}
+
+impl SpanlessEq for LazyAttrTokenStream {
+ fn eq(&self, other: &Self) -> bool {
+ let this = self.to_attr_token_stream();
+ let other = other.to_attr_token_stream();
+ SpanlessEq::eq(&this, &other)
+ }
+}
+
+impl SpanlessEq for AttrKind {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (AttrKind::Normal(normal), AttrKind::Normal(normal2)) => {
+ SpanlessEq::eq(normal, normal2)
+ }
+ (AttrKind::DocComment(kind, symbol), AttrKind::DocComment(kind2, symbol2)) => {
+ SpanlessEq::eq(kind, kind2) && SpanlessEq::eq(symbol, symbol2)
+ }
+ (AttrKind::DocComment(kind, unescaped), AttrKind::Normal(normal2)) => {
+ match kind {
+ CommentKind::Line | CommentKind::Block => {}
+ }
+ let path = Path::from_ident(Ident::with_dummy_span(sym::doc));
+ SpanlessEq::eq(&path, &normal2.item.path)
+ && match &normal2.item.args {
+ AttrArgs::Empty | AttrArgs::Delimited(_) => false,
+ AttrArgs::Eq(_span, value) => {
+ is_escaped_literal_attr_args(value, *unescaped)
+ }
+ }
+ }
+ (AttrKind::Normal(_), AttrKind::DocComment(..)) => SpanlessEq::eq(other, self),
+ }
+ }
+}
+
+impl SpanlessEq for FormatArguments {
+ fn eq(&self, other: &Self) -> bool {
+ SpanlessEq::eq(self.all_args(), other.all_args())
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/common/mod.rs b/rust/hw/char/pl011/vendor/syn/tests/common/mod.rs
new file mode 100644
index 0000000000..f29d800c72
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/common/mod.rs
@@ -0,0 +1,28 @@
+#![allow(dead_code)]
+#![allow(clippy::module_name_repetitions, clippy::shadow_unrelated)]
+
+use rayon::ThreadPoolBuilder;
+use std::env;
+
+pub mod eq;
+pub mod parse;
+
+/// Read the `ABORT_AFTER_FAILURE` environment variable, and parse it.
+pub fn abort_after() -> usize {
+ match env::var("ABORT_AFTER_FAILURE") {
+ Ok(s) => s.parse().expect("failed to parse ABORT_AFTER_FAILURE"),
+ Err(_) => usize::MAX,
+ }
+}
+
+/// Configure Rayon threadpool.
+pub fn rayon_init() {
+ let stack_size = match env::var("RUST_MIN_STACK") {
+ Ok(s) => s.parse().expect("failed to parse RUST_MIN_STACK"),
+ Err(_) => 1024 * 1024 * if cfg!(debug_assertions) { 40 } else { 20 },
+ };
+ ThreadPoolBuilder::new()
+ .stack_size(stack_size)
+ .build_global()
+ .unwrap();
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/common/parse.rs b/rust/hw/char/pl011/vendor/syn/tests/common/parse.rs
new file mode 100644
index 0000000000..2d00a62f46
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/common/parse.rs
@@ -0,0 +1,49 @@
+extern crate rustc_ast;
+extern crate rustc_driver;
+extern crate rustc_expand;
+extern crate rustc_parse as parse;
+extern crate rustc_session;
+extern crate rustc_span;
+
+use rustc_ast::ast;
+use rustc_ast::ptr::P;
+use rustc_session::parse::ParseSess;
+use rustc_span::FileName;
+use std::panic;
+
+pub fn librustc_expr(input: &str) -> Option<P<ast::Expr>> {
+ match panic::catch_unwind(|| {
+ let locale_resources = rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec();
+ let sess = ParseSess::new(locale_resources);
+ let e = parse::new_parser_from_source_str(
+ &sess,
+ FileName::Custom("test_precedence".to_string()),
+ input.to_string(),
+ )
+ .parse_expr();
+ match e {
+ Ok(expr) => Some(expr),
+ Err(diagnostic) => {
+ diagnostic.emit();
+ None
+ }
+ }
+ }) {
+ Ok(Some(e)) => Some(e),
+ Ok(None) => None,
+ Err(_) => {
+ errorf!("librustc panicked\n");
+ None
+ }
+ }
+}
+
+pub fn syn_expr(input: &str) -> Option<syn::Expr> {
+ match syn::parse_str(input) {
+ Ok(e) => Some(e),
+ Err(msg) => {
+ errorf!("syn failed to parse\n{:?}\n", msg);
+ None
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/debug/gen.rs b/rust/hw/char/pl011/vendor/syn/tests/debug/gen.rs
new file mode 100644
index 0000000000..9f726683a2
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/debug/gen.rs
@@ -0,0 +1,5163 @@
+// This file is @generated by syn-internal-codegen.
+// It is not intended for manual editing.
+
+#![allow(repr_transparent_external_private_fields)]
+#![allow(clippy::match_wildcard_for_single_variants)]
+use super::{Lite, Present};
+use ref_cast::RefCast;
+use std::fmt::{self, Debug, Display};
+impl Debug for Lite<syn::Abi> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Abi");
+ if let Some(val) = &self.value.name {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::LitStr);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("name", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::AngleBracketedGenericArguments> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("AngleBracketedGenericArguments");
+ if self.value.colon2_token.is_some() {
+ formatter.field("colon2_token", &Present);
+ }
+ if !self.value.args.is_empty() {
+ formatter.field("args", Lite(&self.value.args));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Arm> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Arm");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("pat", Lite(&self.value.pat));
+ if let Some(val) = &self.value.guard {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::If, Box<syn::Expr>));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("guard", Print::ref_cast(val));
+ }
+ formatter.field("body", Lite(&self.value.body));
+ if self.value.comma.is_some() {
+ formatter.field("comma", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::AssocConst> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("AssocConst");
+ formatter.field("ident", Lite(&self.value.ident));
+ if let Some(val) = &self.value.generics {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::AngleBracketedGenericArguments);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("generics", Print::ref_cast(val));
+ }
+ formatter.field("value", Lite(&self.value.value));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::AssocType> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("AssocType");
+ formatter.field("ident", Lite(&self.value.ident));
+ if let Some(val) = &self.value.generics {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::AngleBracketedGenericArguments);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("generics", Print::ref_cast(val));
+ }
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::AttrStyle> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::AttrStyle::Outer => formatter.write_str("AttrStyle::Outer"),
+ syn::AttrStyle::Inner(_val) => {
+ formatter.write_str("AttrStyle::Inner")?;
+ Ok(())
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::Attribute> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Attribute");
+ formatter.field("style", Lite(&self.value.style));
+ formatter.field("meta", Lite(&self.value.meta));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::BareFnArg> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("BareFnArg");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.name {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((proc_macro2::Ident, syn::token::Colon));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("name", Print::ref_cast(val));
+ }
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::BareVariadic> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("BareVariadic");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.name {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((proc_macro2::Ident, syn::token::Colon));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("name", Print::ref_cast(val));
+ }
+ if self.value.comma.is_some() {
+ formatter.field("comma", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::BinOp> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::BinOp::Add(_val) => {
+ formatter.write_str("BinOp::Add")?;
+ Ok(())
+ }
+ syn::BinOp::Sub(_val) => {
+ formatter.write_str("BinOp::Sub")?;
+ Ok(())
+ }
+ syn::BinOp::Mul(_val) => {
+ formatter.write_str("BinOp::Mul")?;
+ Ok(())
+ }
+ syn::BinOp::Div(_val) => {
+ formatter.write_str("BinOp::Div")?;
+ Ok(())
+ }
+ syn::BinOp::Rem(_val) => {
+ formatter.write_str("BinOp::Rem")?;
+ Ok(())
+ }
+ syn::BinOp::And(_val) => {
+ formatter.write_str("BinOp::And")?;
+ Ok(())
+ }
+ syn::BinOp::Or(_val) => {
+ formatter.write_str("BinOp::Or")?;
+ Ok(())
+ }
+ syn::BinOp::BitXor(_val) => {
+ formatter.write_str("BinOp::BitXor")?;
+ Ok(())
+ }
+ syn::BinOp::BitAnd(_val) => {
+ formatter.write_str("BinOp::BitAnd")?;
+ Ok(())
+ }
+ syn::BinOp::BitOr(_val) => {
+ formatter.write_str("BinOp::BitOr")?;
+ Ok(())
+ }
+ syn::BinOp::Shl(_val) => {
+ formatter.write_str("BinOp::Shl")?;
+ Ok(())
+ }
+ syn::BinOp::Shr(_val) => {
+ formatter.write_str("BinOp::Shr")?;
+ Ok(())
+ }
+ syn::BinOp::Eq(_val) => {
+ formatter.write_str("BinOp::Eq")?;
+ Ok(())
+ }
+ syn::BinOp::Lt(_val) => {
+ formatter.write_str("BinOp::Lt")?;
+ Ok(())
+ }
+ syn::BinOp::Le(_val) => {
+ formatter.write_str("BinOp::Le")?;
+ Ok(())
+ }
+ syn::BinOp::Ne(_val) => {
+ formatter.write_str("BinOp::Ne")?;
+ Ok(())
+ }
+ syn::BinOp::Ge(_val) => {
+ formatter.write_str("BinOp::Ge")?;
+ Ok(())
+ }
+ syn::BinOp::Gt(_val) => {
+ formatter.write_str("BinOp::Gt")?;
+ Ok(())
+ }
+ syn::BinOp::AddAssign(_val) => {
+ formatter.write_str("BinOp::AddAssign")?;
+ Ok(())
+ }
+ syn::BinOp::SubAssign(_val) => {
+ formatter.write_str("BinOp::SubAssign")?;
+ Ok(())
+ }
+ syn::BinOp::MulAssign(_val) => {
+ formatter.write_str("BinOp::MulAssign")?;
+ Ok(())
+ }
+ syn::BinOp::DivAssign(_val) => {
+ formatter.write_str("BinOp::DivAssign")?;
+ Ok(())
+ }
+ syn::BinOp::RemAssign(_val) => {
+ formatter.write_str("BinOp::RemAssign")?;
+ Ok(())
+ }
+ syn::BinOp::BitXorAssign(_val) => {
+ formatter.write_str("BinOp::BitXorAssign")?;
+ Ok(())
+ }
+ syn::BinOp::BitAndAssign(_val) => {
+ formatter.write_str("BinOp::BitAndAssign")?;
+ Ok(())
+ }
+ syn::BinOp::BitOrAssign(_val) => {
+ formatter.write_str("BinOp::BitOrAssign")?;
+ Ok(())
+ }
+ syn::BinOp::ShlAssign(_val) => {
+ formatter.write_str("BinOp::ShlAssign")?;
+ Ok(())
+ }
+ syn::BinOp::ShrAssign(_val) => {
+ formatter.write_str("BinOp::ShrAssign")?;
+ Ok(())
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::Block> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Block");
+ formatter.field("stmts", Lite(&self.value.stmts));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::BoundLifetimes> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("BoundLifetimes");
+ if !self.value.lifetimes.is_empty() {
+ formatter.field("lifetimes", Lite(&self.value.lifetimes));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ConstParam> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ConstParam");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("ty", Lite(&self.value.ty));
+ if self.value.eq_token.is_some() {
+ formatter.field("eq_token", &Present);
+ }
+ if let Some(val) = &self.value.default {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Expr);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("default", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Constraint> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Constraint");
+ formatter.field("ident", Lite(&self.value.ident));
+ if let Some(val) = &self.value.generics {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::AngleBracketedGenericArguments);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("generics", Print::ref_cast(val));
+ }
+ if !self.value.bounds.is_empty() {
+ formatter.field("bounds", Lite(&self.value.bounds));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Data> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::Data::Struct(_val) => {
+ let mut formatter = formatter.debug_struct("Data::Struct");
+ formatter.field("fields", Lite(&_val.fields));
+ if _val.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+ syn::Data::Enum(_val) => {
+ let mut formatter = formatter.debug_struct("Data::Enum");
+ if !_val.variants.is_empty() {
+ formatter.field("variants", Lite(&_val.variants));
+ }
+ formatter.finish()
+ }
+ syn::Data::Union(_val) => {
+ let mut formatter = formatter.debug_struct("Data::Union");
+ formatter.field("fields", Lite(&_val.fields));
+ formatter.finish()
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::DataEnum> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("DataEnum");
+ if !self.value.variants.is_empty() {
+ formatter.field("variants", Lite(&self.value.variants));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::DataStruct> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("DataStruct");
+ formatter.field("fields", Lite(&self.value.fields));
+ if self.value.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::DataUnion> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("DataUnion");
+ formatter.field("fields", Lite(&self.value.fields));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::DeriveInput> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("DeriveInput");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ formatter.field("data", Lite(&self.value.data));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Expr> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::Expr::Array(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Array");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if !_val.elems.is_empty() {
+ formatter.field("elems", Lite(&_val.elems));
+ }
+ formatter.finish()
+ }
+ syn::Expr::Assign(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Assign");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("left", Lite(&_val.left));
+ formatter.field("right", Lite(&_val.right));
+ formatter.finish()
+ }
+ syn::Expr::Async(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Async");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if _val.capture.is_some() {
+ formatter.field("capture", &Present);
+ }
+ formatter.field("block", Lite(&_val.block));
+ formatter.finish()
+ }
+ syn::Expr::Await(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Await");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("base", Lite(&_val.base));
+ formatter.finish()
+ }
+ syn::Expr::Binary(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Binary");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("left", Lite(&_val.left));
+ formatter.field("op", Lite(&_val.op));
+ formatter.field("right", Lite(&_val.right));
+ formatter.finish()
+ }
+ syn::Expr::Block(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Block");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.label {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Label);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("label", Print::ref_cast(val));
+ }
+ formatter.field("block", Lite(&_val.block));
+ formatter.finish()
+ }
+ syn::Expr::Break(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Break");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.label {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Lifetime);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("label", Print::ref_cast(val));
+ }
+ if let Some(val) = &_val.expr {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Box<syn::Expr>);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("expr", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ syn::Expr::Call(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Call");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("func", Lite(&_val.func));
+ if !_val.args.is_empty() {
+ formatter.field("args", Lite(&_val.args));
+ }
+ formatter.finish()
+ }
+ syn::Expr::Cast(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Cast");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.field("ty", Lite(&_val.ty));
+ formatter.finish()
+ }
+ syn::Expr::Closure(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Closure");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.lifetimes {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::BoundLifetimes);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("lifetimes", Print::ref_cast(val));
+ }
+ if _val.constness.is_some() {
+ formatter.field("constness", &Present);
+ }
+ if _val.movability.is_some() {
+ formatter.field("movability", &Present);
+ }
+ if _val.asyncness.is_some() {
+ formatter.field("asyncness", &Present);
+ }
+ if _val.capture.is_some() {
+ formatter.field("capture", &Present);
+ }
+ if !_val.inputs.is_empty() {
+ formatter.field("inputs", Lite(&_val.inputs));
+ }
+ formatter.field("output", Lite(&_val.output));
+ formatter.field("body", Lite(&_val.body));
+ formatter.finish()
+ }
+ syn::Expr::Const(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Const");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("block", Lite(&_val.block));
+ formatter.finish()
+ }
+ syn::Expr::Continue(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Continue");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.label {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Lifetime);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("label", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ syn::Expr::Field(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Field");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("base", Lite(&_val.base));
+ formatter.field("member", Lite(&_val.member));
+ formatter.finish()
+ }
+ syn::Expr::ForLoop(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::ForLoop");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.label {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Label);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("label", Print::ref_cast(val));
+ }
+ formatter.field("pat", Lite(&_val.pat));
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.field("body", Lite(&_val.body));
+ formatter.finish()
+ }
+ syn::Expr::Group(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Group");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.finish()
+ }
+ syn::Expr::If(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::If");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("cond", Lite(&_val.cond));
+ formatter.field("then_branch", Lite(&_val.then_branch));
+ if let Some(val) = &_val.else_branch {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::Else, Box<syn::Expr>));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("else_branch", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ syn::Expr::Index(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Index");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.field("index", Lite(&_val.index));
+ formatter.finish()
+ }
+ syn::Expr::Infer(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Infer");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.finish()
+ }
+ syn::Expr::Let(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Let");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("pat", Lite(&_val.pat));
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.finish()
+ }
+ syn::Expr::Lit(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Lit");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("lit", Lite(&_val.lit));
+ formatter.finish()
+ }
+ syn::Expr::Loop(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Loop");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.label {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Label);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("label", Print::ref_cast(val));
+ }
+ formatter.field("body", Lite(&_val.body));
+ formatter.finish()
+ }
+ syn::Expr::Macro(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Macro");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("mac", Lite(&_val.mac));
+ formatter.finish()
+ }
+ syn::Expr::Match(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Match");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("expr", Lite(&_val.expr));
+ if !_val.arms.is_empty() {
+ formatter.field("arms", Lite(&_val.arms));
+ }
+ formatter.finish()
+ }
+ syn::Expr::MethodCall(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::MethodCall");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("receiver", Lite(&_val.receiver));
+ formatter.field("method", Lite(&_val.method));
+ if let Some(val) = &_val.turbofish {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::AngleBracketedGenericArguments);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("turbofish", Print::ref_cast(val));
+ }
+ if !_val.args.is_empty() {
+ formatter.field("args", Lite(&_val.args));
+ }
+ formatter.finish()
+ }
+ syn::Expr::Paren(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Paren");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.finish()
+ }
+ syn::Expr::Path(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Path");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.qself {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::QSelf);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("qself", Print::ref_cast(val));
+ }
+ formatter.field("path", Lite(&_val.path));
+ formatter.finish()
+ }
+ syn::Expr::Range(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Range");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.start {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Box<syn::Expr>);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("start", Print::ref_cast(val));
+ }
+ formatter.field("limits", Lite(&_val.limits));
+ if let Some(val) = &_val.end {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Box<syn::Expr>);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("end", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ syn::Expr::Reference(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Reference");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if _val.mutability.is_some() {
+ formatter.field("mutability", &Present);
+ }
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.finish()
+ }
+ syn::Expr::Repeat(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Repeat");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.field("len", Lite(&_val.len));
+ formatter.finish()
+ }
+ syn::Expr::Return(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Return");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.expr {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Box<syn::Expr>);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("expr", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ syn::Expr::Struct(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Struct");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.qself {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::QSelf);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("qself", Print::ref_cast(val));
+ }
+ formatter.field("path", Lite(&_val.path));
+ if !_val.fields.is_empty() {
+ formatter.field("fields", Lite(&_val.fields));
+ }
+ if _val.dot2_token.is_some() {
+ formatter.field("dot2_token", &Present);
+ }
+ if let Some(val) = &_val.rest {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Box<syn::Expr>);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("rest", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ syn::Expr::Try(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Try");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.finish()
+ }
+ syn::Expr::TryBlock(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::TryBlock");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("block", Lite(&_val.block));
+ formatter.finish()
+ }
+ syn::Expr::Tuple(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Tuple");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if !_val.elems.is_empty() {
+ formatter.field("elems", Lite(&_val.elems));
+ }
+ formatter.finish()
+ }
+ syn::Expr::Unary(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Unary");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("op", Lite(&_val.op));
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.finish()
+ }
+ syn::Expr::Unsafe(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Unsafe");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("block", Lite(&_val.block));
+ formatter.finish()
+ }
+ syn::Expr::Verbatim(_val) => {
+ formatter.write_str("Expr::Verbatim")?;
+ formatter.write_str("(`")?;
+ Display::fmt(_val, formatter)?;
+ formatter.write_str("`)")?;
+ Ok(())
+ }
+ syn::Expr::While(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::While");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.label {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Label);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("label", Print::ref_cast(val));
+ }
+ formatter.field("cond", Lite(&_val.cond));
+ formatter.field("body", Lite(&_val.body));
+ formatter.finish()
+ }
+ syn::Expr::Yield(_val) => {
+ let mut formatter = formatter.debug_struct("Expr::Yield");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.expr {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Box<syn::Expr>);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("expr", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::ExprArray> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprArray");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if !self.value.elems.is_empty() {
+ formatter.field("elems", Lite(&self.value.elems));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprAssign> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprAssign");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("left", Lite(&self.value.left));
+ formatter.field("right", Lite(&self.value.right));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprAsync> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprAsync");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if self.value.capture.is_some() {
+ formatter.field("capture", &Present);
+ }
+ formatter.field("block", Lite(&self.value.block));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprAwait> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprAwait");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("base", Lite(&self.value.base));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprBinary> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprBinary");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("left", Lite(&self.value.left));
+ formatter.field("op", Lite(&self.value.op));
+ formatter.field("right", Lite(&self.value.right));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprBlock> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprBlock");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.label {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Label);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("label", Print::ref_cast(val));
+ }
+ formatter.field("block", Lite(&self.value.block));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprBreak> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprBreak");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.label {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Lifetime);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("label", Print::ref_cast(val));
+ }
+ if let Some(val) = &self.value.expr {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Box<syn::Expr>);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("expr", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprCall> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprCall");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("func", Lite(&self.value.func));
+ if !self.value.args.is_empty() {
+ formatter.field("args", Lite(&self.value.args));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprCast> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprCast");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprClosure> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprClosure");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.lifetimes {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::BoundLifetimes);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("lifetimes", Print::ref_cast(val));
+ }
+ if self.value.constness.is_some() {
+ formatter.field("constness", &Present);
+ }
+ if self.value.movability.is_some() {
+ formatter.field("movability", &Present);
+ }
+ if self.value.asyncness.is_some() {
+ formatter.field("asyncness", &Present);
+ }
+ if self.value.capture.is_some() {
+ formatter.field("capture", &Present);
+ }
+ if !self.value.inputs.is_empty() {
+ formatter.field("inputs", Lite(&self.value.inputs));
+ }
+ formatter.field("output", Lite(&self.value.output));
+ formatter.field("body", Lite(&self.value.body));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprConst> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprConst");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("block", Lite(&self.value.block));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprContinue> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprContinue");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.label {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Lifetime);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("label", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprField> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprField");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("base", Lite(&self.value.base));
+ formatter.field("member", Lite(&self.value.member));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprForLoop> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprForLoop");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.label {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Label);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("label", Print::ref_cast(val));
+ }
+ formatter.field("pat", Lite(&self.value.pat));
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.field("body", Lite(&self.value.body));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprGroup> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprGroup");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprIf> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprIf");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("cond", Lite(&self.value.cond));
+ formatter.field("then_branch", Lite(&self.value.then_branch));
+ if let Some(val) = &self.value.else_branch {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::Else, Box<syn::Expr>));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("else_branch", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprIndex> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprIndex");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.field("index", Lite(&self.value.index));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprInfer> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprInfer");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprLet> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprLet");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("pat", Lite(&self.value.pat));
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprLit> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprLit");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("lit", Lite(&self.value.lit));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprLoop> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprLoop");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.label {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Label);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("label", Print::ref_cast(val));
+ }
+ formatter.field("body", Lite(&self.value.body));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprMacro> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprMacro");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("mac", Lite(&self.value.mac));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprMatch> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprMatch");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("expr", Lite(&self.value.expr));
+ if !self.value.arms.is_empty() {
+ formatter.field("arms", Lite(&self.value.arms));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprMethodCall> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprMethodCall");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("receiver", Lite(&self.value.receiver));
+ formatter.field("method", Lite(&self.value.method));
+ if let Some(val) = &self.value.turbofish {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::AngleBracketedGenericArguments);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("turbofish", Print::ref_cast(val));
+ }
+ if !self.value.args.is_empty() {
+ formatter.field("args", Lite(&self.value.args));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprParen> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprParen");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprPath> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprPath");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.qself {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::QSelf);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("qself", Print::ref_cast(val));
+ }
+ formatter.field("path", Lite(&self.value.path));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprRange> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprRange");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.start {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Box<syn::Expr>);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("start", Print::ref_cast(val));
+ }
+ formatter.field("limits", Lite(&self.value.limits));
+ if let Some(val) = &self.value.end {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Box<syn::Expr>);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("end", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprReference> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprReference");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if self.value.mutability.is_some() {
+ formatter.field("mutability", &Present);
+ }
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprRepeat> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprRepeat");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.field("len", Lite(&self.value.len));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprReturn> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprReturn");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.expr {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Box<syn::Expr>);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("expr", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprStruct> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprStruct");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.qself {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::QSelf);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("qself", Print::ref_cast(val));
+ }
+ formatter.field("path", Lite(&self.value.path));
+ if !self.value.fields.is_empty() {
+ formatter.field("fields", Lite(&self.value.fields));
+ }
+ if self.value.dot2_token.is_some() {
+ formatter.field("dot2_token", &Present);
+ }
+ if let Some(val) = &self.value.rest {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Box<syn::Expr>);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("rest", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprTry> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprTry");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprTryBlock> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprTryBlock");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("block", Lite(&self.value.block));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprTuple> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprTuple");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if !self.value.elems.is_empty() {
+ formatter.field("elems", Lite(&self.value.elems));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprUnary> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprUnary");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("op", Lite(&self.value.op));
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprUnsafe> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprUnsafe");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("block", Lite(&self.value.block));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprWhile> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprWhile");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.label {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Label);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("label", Print::ref_cast(val));
+ }
+ formatter.field("cond", Lite(&self.value.cond));
+ formatter.field("body", Lite(&self.value.body));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ExprYield> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ExprYield");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.expr {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Box<syn::Expr>);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("expr", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Field> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Field");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ match self.value.mutability {
+ syn::FieldMutability::None => {}
+ _ => {
+ formatter.field("mutability", Lite(&self.value.mutability));
+ }
+ }
+ if let Some(val) = &self.value.ident {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(proc_macro2::Ident);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("ident", Print::ref_cast(val));
+ }
+ if self.value.colon_token.is_some() {
+ formatter.field("colon_token", &Present);
+ }
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::FieldMutability> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::FieldMutability::None => formatter.write_str("FieldMutability::None"),
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::FieldPat> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("FieldPat");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("member", Lite(&self.value.member));
+ if self.value.colon_token.is_some() {
+ formatter.field("colon_token", &Present);
+ }
+ formatter.field("pat", Lite(&self.value.pat));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::FieldValue> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("FieldValue");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("member", Lite(&self.value.member));
+ if self.value.colon_token.is_some() {
+ formatter.field("colon_token", &Present);
+ }
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Fields> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::Fields::Named(_val) => {
+ let mut formatter = formatter.debug_struct("Fields::Named");
+ if !_val.named.is_empty() {
+ formatter.field("named", Lite(&_val.named));
+ }
+ formatter.finish()
+ }
+ syn::Fields::Unnamed(_val) => {
+ let mut formatter = formatter.debug_struct("Fields::Unnamed");
+ if !_val.unnamed.is_empty() {
+ formatter.field("unnamed", Lite(&_val.unnamed));
+ }
+ formatter.finish()
+ }
+ syn::Fields::Unit => formatter.write_str("Fields::Unit"),
+ }
+ }
+}
+impl Debug for Lite<syn::FieldsNamed> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("FieldsNamed");
+ if !self.value.named.is_empty() {
+ formatter.field("named", Lite(&self.value.named));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::FieldsUnnamed> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("FieldsUnnamed");
+ if !self.value.unnamed.is_empty() {
+ formatter.field("unnamed", Lite(&self.value.unnamed));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::File> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("File");
+ if let Some(val) = &self.value.shebang {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(String);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("shebang", Print::ref_cast(val));
+ }
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if !self.value.items.is_empty() {
+ formatter.field("items", Lite(&self.value.items));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::FnArg> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::FnArg::Receiver(_val) => {
+ formatter.write_str("FnArg::Receiver")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::FnArg::Typed(_val) => {
+ formatter.write_str("FnArg::Typed")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::ForeignItem> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::ForeignItem::Fn(_val) => {
+ let mut formatter = formatter.debug_struct("ForeignItem::Fn");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ formatter.field("sig", Lite(&_val.sig));
+ formatter.finish()
+ }
+ syn::ForeignItem::Static(_val) => {
+ let mut formatter = formatter.debug_struct("ForeignItem::Static");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ match _val.mutability {
+ syn::StaticMutability::None => {}
+ _ => {
+ formatter.field("mutability", Lite(&_val.mutability));
+ }
+ }
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("ty", Lite(&_val.ty));
+ formatter.finish()
+ }
+ syn::ForeignItem::Type(_val) => {
+ let mut formatter = formatter.debug_struct("ForeignItem::Type");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("generics", Lite(&_val.generics));
+ formatter.finish()
+ }
+ syn::ForeignItem::Macro(_val) => {
+ let mut formatter = formatter.debug_struct("ForeignItem::Macro");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("mac", Lite(&_val.mac));
+ if _val.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+ syn::ForeignItem::Verbatim(_val) => {
+ formatter.write_str("ForeignItem::Verbatim")?;
+ formatter.write_str("(`")?;
+ Display::fmt(_val, formatter)?;
+ formatter.write_str("`)")?;
+ Ok(())
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::ForeignItemFn> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ForeignItemFn");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ formatter.field("sig", Lite(&self.value.sig));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ForeignItemMacro> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ForeignItemMacro");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("mac", Lite(&self.value.mac));
+ if self.value.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ForeignItemStatic> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ForeignItemStatic");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ match self.value.mutability {
+ syn::StaticMutability::None => {}
+ _ => {
+ formatter.field("mutability", Lite(&self.value.mutability));
+ }
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ForeignItemType> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ForeignItemType");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::GenericArgument> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::GenericArgument::Lifetime(_val) => {
+ formatter.write_str("GenericArgument::Lifetime")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::GenericArgument::Type(_val) => {
+ formatter.write_str("GenericArgument::Type")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::GenericArgument::Const(_val) => {
+ formatter.write_str("GenericArgument::Const")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::GenericArgument::AssocType(_val) => {
+ formatter.write_str("GenericArgument::AssocType")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::GenericArgument::AssocConst(_val) => {
+ formatter.write_str("GenericArgument::AssocConst")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::GenericArgument::Constraint(_val) => {
+ formatter.write_str("GenericArgument::Constraint")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::GenericParam> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::GenericParam::Lifetime(_val) => {
+ formatter.write_str("GenericParam::Lifetime")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::GenericParam::Type(_val) => {
+ formatter.write_str("GenericParam::Type")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::GenericParam::Const(_val) => {
+ formatter.write_str("GenericParam::Const")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::Generics> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Generics");
+ if self.value.lt_token.is_some() {
+ formatter.field("lt_token", &Present);
+ }
+ if !self.value.params.is_empty() {
+ formatter.field("params", Lite(&self.value.params));
+ }
+ if self.value.gt_token.is_some() {
+ formatter.field("gt_token", &Present);
+ }
+ if let Some(val) = &self.value.where_clause {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::WhereClause);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("where_clause", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ImplItem> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::ImplItem::Const(_val) => {
+ let mut formatter = formatter.debug_struct("ImplItem::Const");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ if _val.defaultness.is_some() {
+ formatter.field("defaultness", &Present);
+ }
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("generics", Lite(&_val.generics));
+ formatter.field("ty", Lite(&_val.ty));
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.finish()
+ }
+ syn::ImplItem::Fn(_val) => {
+ let mut formatter = formatter.debug_struct("ImplItem::Fn");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ if _val.defaultness.is_some() {
+ formatter.field("defaultness", &Present);
+ }
+ formatter.field("sig", Lite(&_val.sig));
+ formatter.field("block", Lite(&_val.block));
+ formatter.finish()
+ }
+ syn::ImplItem::Type(_val) => {
+ let mut formatter = formatter.debug_struct("ImplItem::Type");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ if _val.defaultness.is_some() {
+ formatter.field("defaultness", &Present);
+ }
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("generics", Lite(&_val.generics));
+ formatter.field("ty", Lite(&_val.ty));
+ formatter.finish()
+ }
+ syn::ImplItem::Macro(_val) => {
+ let mut formatter = formatter.debug_struct("ImplItem::Macro");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("mac", Lite(&_val.mac));
+ if _val.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+ syn::ImplItem::Verbatim(_val) => {
+ formatter.write_str("ImplItem::Verbatim")?;
+ formatter.write_str("(`")?;
+ Display::fmt(_val, formatter)?;
+ formatter.write_str("`)")?;
+ Ok(())
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::ImplItemConst> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ImplItemConst");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ if self.value.defaultness.is_some() {
+ formatter.field("defaultness", &Present);
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ImplItemFn> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ImplItemFn");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ if self.value.defaultness.is_some() {
+ formatter.field("defaultness", &Present);
+ }
+ formatter.field("sig", Lite(&self.value.sig));
+ formatter.field("block", Lite(&self.value.block));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ImplItemMacro> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ImplItemMacro");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("mac", Lite(&self.value.mac));
+ if self.value.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ImplItemType> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ImplItemType");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ if self.value.defaultness.is_some() {
+ formatter.field("defaultness", &Present);
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ImplRestriction> {
+ fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
+ unreachable!()
+ }
+}
+impl Debug for Lite<syn::Index> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Index");
+ formatter.field("index", Lite(&self.value.index));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Item> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::Item::Const(_val) => {
+ let mut formatter = formatter.debug_struct("Item::Const");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("generics", Lite(&_val.generics));
+ formatter.field("ty", Lite(&_val.ty));
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.finish()
+ }
+ syn::Item::Enum(_val) => {
+ let mut formatter = formatter.debug_struct("Item::Enum");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("generics", Lite(&_val.generics));
+ if !_val.variants.is_empty() {
+ formatter.field("variants", Lite(&_val.variants));
+ }
+ formatter.finish()
+ }
+ syn::Item::ExternCrate(_val) => {
+ let mut formatter = formatter.debug_struct("Item::ExternCrate");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ formatter.field("ident", Lite(&_val.ident));
+ if let Some(val) = &_val.rename {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::As, proc_macro2::Ident));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("rename", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ syn::Item::Fn(_val) => {
+ let mut formatter = formatter.debug_struct("Item::Fn");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ formatter.field("sig", Lite(&_val.sig));
+ formatter.field("block", Lite(&_val.block));
+ formatter.finish()
+ }
+ syn::Item::ForeignMod(_val) => {
+ let mut formatter = formatter.debug_struct("Item::ForeignMod");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if _val.unsafety.is_some() {
+ formatter.field("unsafety", &Present);
+ }
+ formatter.field("abi", Lite(&_val.abi));
+ if !_val.items.is_empty() {
+ formatter.field("items", Lite(&_val.items));
+ }
+ formatter.finish()
+ }
+ syn::Item::Impl(_val) => {
+ let mut formatter = formatter.debug_struct("Item::Impl");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if _val.defaultness.is_some() {
+ formatter.field("defaultness", &Present);
+ }
+ if _val.unsafety.is_some() {
+ formatter.field("unsafety", &Present);
+ }
+ formatter.field("generics", Lite(&_val.generics));
+ if let Some(val) = &_val.trait_ {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((Option<syn::token::Not>, syn::Path, syn::token::For));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(
+ &(
+ &super::Option {
+ present: self.0.0.is_some(),
+ },
+ Lite(&self.0.1),
+ ),
+ formatter,
+ )?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("trait_", Print::ref_cast(val));
+ }
+ formatter.field("self_ty", Lite(&_val.self_ty));
+ if !_val.items.is_empty() {
+ formatter.field("items", Lite(&_val.items));
+ }
+ formatter.finish()
+ }
+ syn::Item::Macro(_val) => {
+ let mut formatter = formatter.debug_struct("Item::Macro");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.ident {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(proc_macro2::Ident);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("ident", Print::ref_cast(val));
+ }
+ formatter.field("mac", Lite(&_val.mac));
+ if _val.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+ syn::Item::Mod(_val) => {
+ let mut formatter = formatter.debug_struct("Item::Mod");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ if _val.unsafety.is_some() {
+ formatter.field("unsafety", &Present);
+ }
+ formatter.field("ident", Lite(&_val.ident));
+ if let Some(val) = &_val.content {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::Brace, Vec<syn::Item>));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("content", Print::ref_cast(val));
+ }
+ if _val.semi.is_some() {
+ formatter.field("semi", &Present);
+ }
+ formatter.finish()
+ }
+ syn::Item::Static(_val) => {
+ let mut formatter = formatter.debug_struct("Item::Static");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ match _val.mutability {
+ syn::StaticMutability::None => {}
+ _ => {
+ formatter.field("mutability", Lite(&_val.mutability));
+ }
+ }
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("ty", Lite(&_val.ty));
+ formatter.field("expr", Lite(&_val.expr));
+ formatter.finish()
+ }
+ syn::Item::Struct(_val) => {
+ let mut formatter = formatter.debug_struct("Item::Struct");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("generics", Lite(&_val.generics));
+ formatter.field("fields", Lite(&_val.fields));
+ if _val.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+ syn::Item::Trait(_val) => {
+ let mut formatter = formatter.debug_struct("Item::Trait");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ if _val.unsafety.is_some() {
+ formatter.field("unsafety", &Present);
+ }
+ if _val.auto_token.is_some() {
+ formatter.field("auto_token", &Present);
+ }
+ if let Some(val) = &_val.restriction {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::ImplRestriction);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("restriction", Print::ref_cast(val));
+ }
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("generics", Lite(&_val.generics));
+ if _val.colon_token.is_some() {
+ formatter.field("colon_token", &Present);
+ }
+ if !_val.supertraits.is_empty() {
+ formatter.field("supertraits", Lite(&_val.supertraits));
+ }
+ if !_val.items.is_empty() {
+ formatter.field("items", Lite(&_val.items));
+ }
+ formatter.finish()
+ }
+ syn::Item::TraitAlias(_val) => {
+ let mut formatter = formatter.debug_struct("Item::TraitAlias");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("generics", Lite(&_val.generics));
+ if !_val.bounds.is_empty() {
+ formatter.field("bounds", Lite(&_val.bounds));
+ }
+ formatter.finish()
+ }
+ syn::Item::Type(_val) => {
+ let mut formatter = formatter.debug_struct("Item::Type");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("generics", Lite(&_val.generics));
+ formatter.field("ty", Lite(&_val.ty));
+ formatter.finish()
+ }
+ syn::Item::Union(_val) => {
+ let mut formatter = formatter.debug_struct("Item::Union");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("generics", Lite(&_val.generics));
+ formatter.field("fields", Lite(&_val.fields));
+ formatter.finish()
+ }
+ syn::Item::Use(_val) => {
+ let mut formatter = formatter.debug_struct("Item::Use");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("vis", Lite(&_val.vis));
+ if _val.leading_colon.is_some() {
+ formatter.field("leading_colon", &Present);
+ }
+ formatter.field("tree", Lite(&_val.tree));
+ formatter.finish()
+ }
+ syn::Item::Verbatim(_val) => {
+ formatter.write_str("Item::Verbatim")?;
+ formatter.write_str("(`")?;
+ Display::fmt(_val, formatter)?;
+ formatter.write_str("`)")?;
+ Ok(())
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::ItemConst> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemConst");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemEnum> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemEnum");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ if !self.value.variants.is_empty() {
+ formatter.field("variants", Lite(&self.value.variants));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemExternCrate> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemExternCrate");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ formatter.field("ident", Lite(&self.value.ident));
+ if let Some(val) = &self.value.rename {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::As, proc_macro2::Ident));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("rename", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemFn> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemFn");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ formatter.field("sig", Lite(&self.value.sig));
+ formatter.field("block", Lite(&self.value.block));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemForeignMod> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemForeignMod");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if self.value.unsafety.is_some() {
+ formatter.field("unsafety", &Present);
+ }
+ formatter.field("abi", Lite(&self.value.abi));
+ if !self.value.items.is_empty() {
+ formatter.field("items", Lite(&self.value.items));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemImpl> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemImpl");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if self.value.defaultness.is_some() {
+ formatter.field("defaultness", &Present);
+ }
+ if self.value.unsafety.is_some() {
+ formatter.field("unsafety", &Present);
+ }
+ formatter.field("generics", Lite(&self.value.generics));
+ if let Some(val) = &self.value.trait_ {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((Option<syn::token::Not>, syn::Path, syn::token::For));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(
+ &(
+ &super::Option {
+ present: self.0.0.is_some(),
+ },
+ Lite(&self.0.1),
+ ),
+ formatter,
+ )?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("trait_", Print::ref_cast(val));
+ }
+ formatter.field("self_ty", Lite(&self.value.self_ty));
+ if !self.value.items.is_empty() {
+ formatter.field("items", Lite(&self.value.items));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemMacro> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemMacro");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.ident {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(proc_macro2::Ident);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("ident", Print::ref_cast(val));
+ }
+ formatter.field("mac", Lite(&self.value.mac));
+ if self.value.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemMod> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemMod");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ if self.value.unsafety.is_some() {
+ formatter.field("unsafety", &Present);
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ if let Some(val) = &self.value.content {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::Brace, Vec<syn::Item>));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("content", Print::ref_cast(val));
+ }
+ if self.value.semi.is_some() {
+ formatter.field("semi", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemStatic> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemStatic");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ match self.value.mutability {
+ syn::StaticMutability::None => {}
+ _ => {
+ formatter.field("mutability", Lite(&self.value.mutability));
+ }
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.field("expr", Lite(&self.value.expr));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemStruct> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemStruct");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ formatter.field("fields", Lite(&self.value.fields));
+ if self.value.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemTrait> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemTrait");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ if self.value.unsafety.is_some() {
+ formatter.field("unsafety", &Present);
+ }
+ if self.value.auto_token.is_some() {
+ formatter.field("auto_token", &Present);
+ }
+ if let Some(val) = &self.value.restriction {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::ImplRestriction);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("restriction", Print::ref_cast(val));
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ if self.value.colon_token.is_some() {
+ formatter.field("colon_token", &Present);
+ }
+ if !self.value.supertraits.is_empty() {
+ formatter.field("supertraits", Lite(&self.value.supertraits));
+ }
+ if !self.value.items.is_empty() {
+ formatter.field("items", Lite(&self.value.items));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemTraitAlias> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemTraitAlias");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ if !self.value.bounds.is_empty() {
+ formatter.field("bounds", Lite(&self.value.bounds));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemType> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemType");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemUnion> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemUnion");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ formatter.field("fields", Lite(&self.value.fields));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ItemUse> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ItemUse");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("vis", Lite(&self.value.vis));
+ if self.value.leading_colon.is_some() {
+ formatter.field("leading_colon", &Present);
+ }
+ formatter.field("tree", Lite(&self.value.tree));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Label> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Label");
+ formatter.field("name", Lite(&self.value.name));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Lifetime> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Lifetime");
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::LifetimeParam> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("LifetimeParam");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("lifetime", Lite(&self.value.lifetime));
+ if self.value.colon_token.is_some() {
+ formatter.field("colon_token", &Present);
+ }
+ if !self.value.bounds.is_empty() {
+ formatter.field("bounds", Lite(&self.value.bounds));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Lit> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::Lit::Str(_val) => write!(formatter, "{:?}", _val.value()),
+ syn::Lit::ByteStr(_val) => write!(formatter, "{:?}", _val.value()),
+ syn::Lit::CStr(_val) => write!(formatter, "{:?}", _val.value()),
+ syn::Lit::Byte(_val) => write!(formatter, "{:?}", _val.value()),
+ syn::Lit::Char(_val) => write!(formatter, "{:?}", _val.value()),
+ syn::Lit::Int(_val) => write!(formatter, "{}", _val),
+ syn::Lit::Float(_val) => write!(formatter, "{}", _val),
+ syn::Lit::Bool(_val) => {
+ let mut formatter = formatter.debug_struct("Lit::Bool");
+ formatter.field("value", Lite(&_val.value));
+ formatter.finish()
+ }
+ syn::Lit::Verbatim(_val) => {
+ formatter.write_str("Lit::Verbatim")?;
+ formatter.write_str("(`")?;
+ Display::fmt(_val, formatter)?;
+ formatter.write_str("`)")?;
+ Ok(())
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::LitBool> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("LitBool");
+ formatter.field("value", Lite(&self.value.value));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::LitByte> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{:?}", self.value.value())
+ }
+}
+impl Debug for Lite<syn::LitByteStr> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{:?}", self.value.value())
+ }
+}
+impl Debug for Lite<syn::LitCStr> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{:?}", self.value.value())
+ }
+}
+impl Debug for Lite<syn::LitChar> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{:?}", self.value.value())
+ }
+}
+impl Debug for Lite<syn::LitFloat> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{}", & self.value)
+ }
+}
+impl Debug for Lite<syn::LitInt> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{}", & self.value)
+ }
+}
+impl Debug for Lite<syn::LitStr> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{:?}", self.value.value())
+ }
+}
+impl Debug for Lite<syn::Local> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Local");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("pat", Lite(&self.value.pat));
+ if let Some(val) = &self.value.init {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::LocalInit);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("init", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::LocalInit> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("LocalInit");
+ formatter.field("expr", Lite(&self.value.expr));
+ if let Some(val) = &self.value.diverge {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::Else, Box<syn::Expr>));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("diverge", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Macro> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Macro");
+ formatter.field("path", Lite(&self.value.path));
+ formatter.field("delimiter", Lite(&self.value.delimiter));
+ formatter.field("tokens", Lite(&self.value.tokens));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::MacroDelimiter> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::MacroDelimiter::Paren(_val) => {
+ formatter.write_str("MacroDelimiter::Paren")?;
+ Ok(())
+ }
+ syn::MacroDelimiter::Brace(_val) => {
+ formatter.write_str("MacroDelimiter::Brace")?;
+ Ok(())
+ }
+ syn::MacroDelimiter::Bracket(_val) => {
+ formatter.write_str("MacroDelimiter::Bracket")?;
+ Ok(())
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::Member> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::Member::Named(_val) => {
+ formatter.write_str("Member::Named")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::Member::Unnamed(_val) => {
+ formatter.write_str("Member::Unnamed")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::Meta> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::Meta::Path(_val) => {
+ let mut formatter = formatter.debug_struct("Meta::Path");
+ if _val.leading_colon.is_some() {
+ formatter.field("leading_colon", &Present);
+ }
+ if !_val.segments.is_empty() {
+ formatter.field("segments", Lite(&_val.segments));
+ }
+ formatter.finish()
+ }
+ syn::Meta::List(_val) => {
+ let mut formatter = formatter.debug_struct("Meta::List");
+ formatter.field("path", Lite(&_val.path));
+ formatter.field("delimiter", Lite(&_val.delimiter));
+ formatter.field("tokens", Lite(&_val.tokens));
+ formatter.finish()
+ }
+ syn::Meta::NameValue(_val) => {
+ let mut formatter = formatter.debug_struct("Meta::NameValue");
+ formatter.field("path", Lite(&_val.path));
+ formatter.field("value", Lite(&_val.value));
+ formatter.finish()
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::MetaList> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("MetaList");
+ formatter.field("path", Lite(&self.value.path));
+ formatter.field("delimiter", Lite(&self.value.delimiter));
+ formatter.field("tokens", Lite(&self.value.tokens));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::MetaNameValue> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("MetaNameValue");
+ formatter.field("path", Lite(&self.value.path));
+ formatter.field("value", Lite(&self.value.value));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ParenthesizedGenericArguments> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("ParenthesizedGenericArguments");
+ if !self.value.inputs.is_empty() {
+ formatter.field("inputs", Lite(&self.value.inputs));
+ }
+ formatter.field("output", Lite(&self.value.output));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Pat> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::Pat::Const(_val) => {
+ formatter.write_str("Pat::Const")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::Pat::Ident(_val) => {
+ let mut formatter = formatter.debug_struct("Pat::Ident");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if _val.by_ref.is_some() {
+ formatter.field("by_ref", &Present);
+ }
+ if _val.mutability.is_some() {
+ formatter.field("mutability", &Present);
+ }
+ formatter.field("ident", Lite(&_val.ident));
+ if let Some(val) = &_val.subpat {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::At, Box<syn::Pat>));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("subpat", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ syn::Pat::Lit(_val) => {
+ formatter.write_str("Pat::Lit")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::Pat::Macro(_val) => {
+ formatter.write_str("Pat::Macro")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::Pat::Or(_val) => {
+ let mut formatter = formatter.debug_struct("Pat::Or");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if _val.leading_vert.is_some() {
+ formatter.field("leading_vert", &Present);
+ }
+ if !_val.cases.is_empty() {
+ formatter.field("cases", Lite(&_val.cases));
+ }
+ formatter.finish()
+ }
+ syn::Pat::Paren(_val) => {
+ let mut formatter = formatter.debug_struct("Pat::Paren");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("pat", Lite(&_val.pat));
+ formatter.finish()
+ }
+ syn::Pat::Path(_val) => {
+ formatter.write_str("Pat::Path")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::Pat::Range(_val) => {
+ formatter.write_str("Pat::Range")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::Pat::Reference(_val) => {
+ let mut formatter = formatter.debug_struct("Pat::Reference");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if _val.mutability.is_some() {
+ formatter.field("mutability", &Present);
+ }
+ formatter.field("pat", Lite(&_val.pat));
+ formatter.finish()
+ }
+ syn::Pat::Rest(_val) => {
+ let mut formatter = formatter.debug_struct("Pat::Rest");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.finish()
+ }
+ syn::Pat::Slice(_val) => {
+ let mut formatter = formatter.debug_struct("Pat::Slice");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if !_val.elems.is_empty() {
+ formatter.field("elems", Lite(&_val.elems));
+ }
+ formatter.finish()
+ }
+ syn::Pat::Struct(_val) => {
+ let mut formatter = formatter.debug_struct("Pat::Struct");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.qself {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::QSelf);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("qself", Print::ref_cast(val));
+ }
+ formatter.field("path", Lite(&_val.path));
+ if !_val.fields.is_empty() {
+ formatter.field("fields", Lite(&_val.fields));
+ }
+ if let Some(val) = &_val.rest {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::PatRest);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("rest", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ syn::Pat::Tuple(_val) => {
+ let mut formatter = formatter.debug_struct("Pat::Tuple");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if !_val.elems.is_empty() {
+ formatter.field("elems", Lite(&_val.elems));
+ }
+ formatter.finish()
+ }
+ syn::Pat::TupleStruct(_val) => {
+ let mut formatter = formatter.debug_struct("Pat::TupleStruct");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ if let Some(val) = &_val.qself {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::QSelf);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("qself", Print::ref_cast(val));
+ }
+ formatter.field("path", Lite(&_val.path));
+ if !_val.elems.is_empty() {
+ formatter.field("elems", Lite(&_val.elems));
+ }
+ formatter.finish()
+ }
+ syn::Pat::Type(_val) => {
+ let mut formatter = formatter.debug_struct("Pat::Type");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("pat", Lite(&_val.pat));
+ formatter.field("ty", Lite(&_val.ty));
+ formatter.finish()
+ }
+ syn::Pat::Verbatim(_val) => {
+ formatter.write_str("Pat::Verbatim")?;
+ formatter.write_str("(`")?;
+ Display::fmt(_val, formatter)?;
+ formatter.write_str("`)")?;
+ Ok(())
+ }
+ syn::Pat::Wild(_val) => {
+ let mut formatter = formatter.debug_struct("Pat::Wild");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.finish()
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::PatIdent> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PatIdent");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if self.value.by_ref.is_some() {
+ formatter.field("by_ref", &Present);
+ }
+ if self.value.mutability.is_some() {
+ formatter.field("mutability", &Present);
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ if let Some(val) = &self.value.subpat {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::At, Box<syn::Pat>));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("subpat", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PatOr> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PatOr");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if self.value.leading_vert.is_some() {
+ formatter.field("leading_vert", &Present);
+ }
+ if !self.value.cases.is_empty() {
+ formatter.field("cases", Lite(&self.value.cases));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PatParen> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PatParen");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("pat", Lite(&self.value.pat));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PatReference> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PatReference");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if self.value.mutability.is_some() {
+ formatter.field("mutability", &Present);
+ }
+ formatter.field("pat", Lite(&self.value.pat));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PatRest> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PatRest");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PatSlice> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PatSlice");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if !self.value.elems.is_empty() {
+ formatter.field("elems", Lite(&self.value.elems));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PatStruct> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PatStruct");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.qself {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::QSelf);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("qself", Print::ref_cast(val));
+ }
+ formatter.field("path", Lite(&self.value.path));
+ if !self.value.fields.is_empty() {
+ formatter.field("fields", Lite(&self.value.fields));
+ }
+ if let Some(val) = &self.value.rest {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::PatRest);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("rest", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PatTuple> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PatTuple");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if !self.value.elems.is_empty() {
+ formatter.field("elems", Lite(&self.value.elems));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PatTupleStruct> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PatTupleStruct");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.qself {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::QSelf);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("qself", Print::ref_cast(val));
+ }
+ formatter.field("path", Lite(&self.value.path));
+ if !self.value.elems.is_empty() {
+ formatter.field("elems", Lite(&self.value.elems));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PatType> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PatType");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("pat", Lite(&self.value.pat));
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PatWild> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PatWild");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Path> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Path");
+ if self.value.leading_colon.is_some() {
+ formatter.field("leading_colon", &Present);
+ }
+ if !self.value.segments.is_empty() {
+ formatter.field("segments", Lite(&self.value.segments));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PathArguments> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::PathArguments::None => formatter.write_str("PathArguments::None"),
+ syn::PathArguments::AngleBracketed(_val) => {
+ let mut formatter = formatter
+ .debug_struct("PathArguments::AngleBracketed");
+ if _val.colon2_token.is_some() {
+ formatter.field("colon2_token", &Present);
+ }
+ if !_val.args.is_empty() {
+ formatter.field("args", Lite(&_val.args));
+ }
+ formatter.finish()
+ }
+ syn::PathArguments::Parenthesized(_val) => {
+ let mut formatter = formatter
+ .debug_struct("PathArguments::Parenthesized");
+ if !_val.inputs.is_empty() {
+ formatter.field("inputs", Lite(&_val.inputs));
+ }
+ formatter.field("output", Lite(&_val.output));
+ formatter.finish()
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::PathSegment> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PathSegment");
+ formatter.field("ident", Lite(&self.value.ident));
+ match self.value.arguments {
+ syn::PathArguments::None => {}
+ _ => {
+ formatter.field("arguments", Lite(&self.value.arguments));
+ }
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PredicateLifetime> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PredicateLifetime");
+ formatter.field("lifetime", Lite(&self.value.lifetime));
+ if !self.value.bounds.is_empty() {
+ formatter.field("bounds", Lite(&self.value.bounds));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::PredicateType> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("PredicateType");
+ if let Some(val) = &self.value.lifetimes {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::BoundLifetimes);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("lifetimes", Print::ref_cast(val));
+ }
+ formatter.field("bounded_ty", Lite(&self.value.bounded_ty));
+ if !self.value.bounds.is_empty() {
+ formatter.field("bounds", Lite(&self.value.bounds));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::QSelf> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("QSelf");
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.field("position", Lite(&self.value.position));
+ if self.value.as_token.is_some() {
+ formatter.field("as_token", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::RangeLimits> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::RangeLimits::HalfOpen(_val) => {
+ formatter.write_str("RangeLimits::HalfOpen")?;
+ Ok(())
+ }
+ syn::RangeLimits::Closed(_val) => {
+ formatter.write_str("RangeLimits::Closed")?;
+ Ok(())
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::Receiver> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Receiver");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.reference {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::And, Option<syn::Lifetime>));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(
+ {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(Option<syn::Lifetime>);
+ impl Debug for Print {
+ fn fmt(
+ &self,
+ formatter: &mut fmt::Formatter,
+ ) -> fmt::Result {
+ match &self.0 {
+ Some(_val) => {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ None => formatter.write_str("None"),
+ }
+ }
+ }
+ Print::ref_cast(&self.0.1)
+ },
+ formatter,
+ )?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("reference", Print::ref_cast(val));
+ }
+ if self.value.mutability.is_some() {
+ formatter.field("mutability", &Present);
+ }
+ if self.value.colon_token.is_some() {
+ formatter.field("colon_token", &Present);
+ }
+ formatter.field("ty", Lite(&self.value.ty));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::ReturnType> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::ReturnType::Default => formatter.write_str("ReturnType::Default"),
+ syn::ReturnType::Type(_v0, _v1) => {
+ let mut formatter = formatter.debug_tuple("ReturnType::Type");
+ formatter.field(Lite(_v1));
+ formatter.finish()
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::Signature> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Signature");
+ if self.value.constness.is_some() {
+ formatter.field("constness", &Present);
+ }
+ if self.value.asyncness.is_some() {
+ formatter.field("asyncness", &Present);
+ }
+ if self.value.unsafety.is_some() {
+ formatter.field("unsafety", &Present);
+ }
+ if let Some(val) = &self.value.abi {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Abi);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("abi", Print::ref_cast(val));
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ if !self.value.inputs.is_empty() {
+ formatter.field("inputs", Lite(&self.value.inputs));
+ }
+ if let Some(val) = &self.value.variadic {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Variadic);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("variadic", Print::ref_cast(val));
+ }
+ formatter.field("output", Lite(&self.value.output));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::StaticMutability> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::StaticMutability::Mut(_val) => {
+ formatter.write_str("StaticMutability::Mut")?;
+ Ok(())
+ }
+ syn::StaticMutability::None => formatter.write_str("StaticMutability::None"),
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::Stmt> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::Stmt::Local(_val) => {
+ let mut formatter = formatter.debug_struct("Stmt::Local");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("pat", Lite(&_val.pat));
+ if let Some(val) = &_val.init {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::LocalInit);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("init", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ syn::Stmt::Item(_val) => {
+ formatter.write_str("Stmt::Item")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::Stmt::Expr(_v0, _v1) => {
+ let mut formatter = formatter.debug_tuple("Stmt::Expr");
+ formatter.field(Lite(_v0));
+ formatter
+ .field(
+ &super::Option {
+ present: _v1.is_some(),
+ },
+ );
+ formatter.finish()
+ }
+ syn::Stmt::Macro(_val) => {
+ let mut formatter = formatter.debug_struct("Stmt::Macro");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("mac", Lite(&_val.mac));
+ if _val.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::StmtMacro> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("StmtMacro");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("mac", Lite(&self.value.mac));
+ if self.value.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TraitBound> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TraitBound");
+ if self.value.paren_token.is_some() {
+ formatter.field("paren_token", &Present);
+ }
+ match self.value.modifier {
+ syn::TraitBoundModifier::None => {}
+ _ => {
+ formatter.field("modifier", Lite(&self.value.modifier));
+ }
+ }
+ if let Some(val) = &self.value.lifetimes {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::BoundLifetimes);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("lifetimes", Print::ref_cast(val));
+ }
+ formatter.field("path", Lite(&self.value.path));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TraitBoundModifier> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::TraitBoundModifier::None => {
+ formatter.write_str("TraitBoundModifier::None")
+ }
+ syn::TraitBoundModifier::Maybe(_val) => {
+ formatter.write_str("TraitBoundModifier::Maybe")?;
+ Ok(())
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::TraitItem> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::TraitItem::Const(_val) => {
+ let mut formatter = formatter.debug_struct("TraitItem::Const");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("generics", Lite(&_val.generics));
+ formatter.field("ty", Lite(&_val.ty));
+ if let Some(val) = &_val.default {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::Eq, syn::Expr));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("default", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ syn::TraitItem::Fn(_val) => {
+ let mut formatter = formatter.debug_struct("TraitItem::Fn");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("sig", Lite(&_val.sig));
+ if let Some(val) = &_val.default {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Block);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("default", Print::ref_cast(val));
+ }
+ if _val.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+ syn::TraitItem::Type(_val) => {
+ let mut formatter = formatter.debug_struct("TraitItem::Type");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.field("generics", Lite(&_val.generics));
+ if _val.colon_token.is_some() {
+ formatter.field("colon_token", &Present);
+ }
+ if !_val.bounds.is_empty() {
+ formatter.field("bounds", Lite(&_val.bounds));
+ }
+ if let Some(val) = &_val.default {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::Eq, syn::Type));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("default", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+ syn::TraitItem::Macro(_val) => {
+ let mut formatter = formatter.debug_struct("TraitItem::Macro");
+ if !_val.attrs.is_empty() {
+ formatter.field("attrs", Lite(&_val.attrs));
+ }
+ formatter.field("mac", Lite(&_val.mac));
+ if _val.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+ syn::TraitItem::Verbatim(_val) => {
+ formatter.write_str("TraitItem::Verbatim")?;
+ formatter.write_str("(`")?;
+ Display::fmt(_val, formatter)?;
+ formatter.write_str("`)")?;
+ Ok(())
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::TraitItemConst> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TraitItemConst");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ formatter.field("ty", Lite(&self.value.ty));
+ if let Some(val) = &self.value.default {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::Eq, syn::Expr));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("default", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TraitItemFn> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TraitItemFn");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("sig", Lite(&self.value.sig));
+ if let Some(val) = &self.value.default {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Block);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("default", Print::ref_cast(val));
+ }
+ if self.value.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TraitItemMacro> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TraitItemMacro");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("mac", Lite(&self.value.mac));
+ if self.value.semi_token.is_some() {
+ formatter.field("semi_token", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TraitItemType> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TraitItemType");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("generics", Lite(&self.value.generics));
+ if self.value.colon_token.is_some() {
+ formatter.field("colon_token", &Present);
+ }
+ if !self.value.bounds.is_empty() {
+ formatter.field("bounds", Lite(&self.value.bounds));
+ }
+ if let Some(val) = &self.value.default {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::Eq, syn::Type));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("default", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Type> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::Type::Array(_val) => {
+ let mut formatter = formatter.debug_struct("Type::Array");
+ formatter.field("elem", Lite(&_val.elem));
+ formatter.field("len", Lite(&_val.len));
+ formatter.finish()
+ }
+ syn::Type::BareFn(_val) => {
+ let mut formatter = formatter.debug_struct("Type::BareFn");
+ if let Some(val) = &_val.lifetimes {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::BoundLifetimes);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("lifetimes", Print::ref_cast(val));
+ }
+ if _val.unsafety.is_some() {
+ formatter.field("unsafety", &Present);
+ }
+ if let Some(val) = &_val.abi {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Abi);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("abi", Print::ref_cast(val));
+ }
+ if !_val.inputs.is_empty() {
+ formatter.field("inputs", Lite(&_val.inputs));
+ }
+ if let Some(val) = &_val.variadic {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::BareVariadic);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("variadic", Print::ref_cast(val));
+ }
+ formatter.field("output", Lite(&_val.output));
+ formatter.finish()
+ }
+ syn::Type::Group(_val) => {
+ let mut formatter = formatter.debug_struct("Type::Group");
+ formatter.field("elem", Lite(&_val.elem));
+ formatter.finish()
+ }
+ syn::Type::ImplTrait(_val) => {
+ let mut formatter = formatter.debug_struct("Type::ImplTrait");
+ if !_val.bounds.is_empty() {
+ formatter.field("bounds", Lite(&_val.bounds));
+ }
+ formatter.finish()
+ }
+ syn::Type::Infer(_val) => {
+ let mut formatter = formatter.debug_struct("Type::Infer");
+ formatter.finish()
+ }
+ syn::Type::Macro(_val) => {
+ let mut formatter = formatter.debug_struct("Type::Macro");
+ formatter.field("mac", Lite(&_val.mac));
+ formatter.finish()
+ }
+ syn::Type::Never(_val) => {
+ let mut formatter = formatter.debug_struct("Type::Never");
+ formatter.finish()
+ }
+ syn::Type::Paren(_val) => {
+ let mut formatter = formatter.debug_struct("Type::Paren");
+ formatter.field("elem", Lite(&_val.elem));
+ formatter.finish()
+ }
+ syn::Type::Path(_val) => {
+ let mut formatter = formatter.debug_struct("Type::Path");
+ if let Some(val) = &_val.qself {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::QSelf);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("qself", Print::ref_cast(val));
+ }
+ formatter.field("path", Lite(&_val.path));
+ formatter.finish()
+ }
+ syn::Type::Ptr(_val) => {
+ let mut formatter = formatter.debug_struct("Type::Ptr");
+ if _val.const_token.is_some() {
+ formatter.field("const_token", &Present);
+ }
+ if _val.mutability.is_some() {
+ formatter.field("mutability", &Present);
+ }
+ formatter.field("elem", Lite(&_val.elem));
+ formatter.finish()
+ }
+ syn::Type::Reference(_val) => {
+ let mut formatter = formatter.debug_struct("Type::Reference");
+ if let Some(val) = &_val.lifetime {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Lifetime);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("lifetime", Print::ref_cast(val));
+ }
+ if _val.mutability.is_some() {
+ formatter.field("mutability", &Present);
+ }
+ formatter.field("elem", Lite(&_val.elem));
+ formatter.finish()
+ }
+ syn::Type::Slice(_val) => {
+ let mut formatter = formatter.debug_struct("Type::Slice");
+ formatter.field("elem", Lite(&_val.elem));
+ formatter.finish()
+ }
+ syn::Type::TraitObject(_val) => {
+ let mut formatter = formatter.debug_struct("Type::TraitObject");
+ if _val.dyn_token.is_some() {
+ formatter.field("dyn_token", &Present);
+ }
+ if !_val.bounds.is_empty() {
+ formatter.field("bounds", Lite(&_val.bounds));
+ }
+ formatter.finish()
+ }
+ syn::Type::Tuple(_val) => {
+ let mut formatter = formatter.debug_struct("Type::Tuple");
+ if !_val.elems.is_empty() {
+ formatter.field("elems", Lite(&_val.elems));
+ }
+ formatter.finish()
+ }
+ syn::Type::Verbatim(_val) => {
+ formatter.write_str("Type::Verbatim")?;
+ formatter.write_str("(`")?;
+ Display::fmt(_val, formatter)?;
+ formatter.write_str("`)")?;
+ Ok(())
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::TypeArray> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeArray");
+ formatter.field("elem", Lite(&self.value.elem));
+ formatter.field("len", Lite(&self.value.len));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypeBareFn> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeBareFn");
+ if let Some(val) = &self.value.lifetimes {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::BoundLifetimes);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("lifetimes", Print::ref_cast(val));
+ }
+ if self.value.unsafety.is_some() {
+ formatter.field("unsafety", &Present);
+ }
+ if let Some(val) = &self.value.abi {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Abi);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("abi", Print::ref_cast(val));
+ }
+ if !self.value.inputs.is_empty() {
+ formatter.field("inputs", Lite(&self.value.inputs));
+ }
+ if let Some(val) = &self.value.variadic {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::BareVariadic);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("variadic", Print::ref_cast(val));
+ }
+ formatter.field("output", Lite(&self.value.output));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypeGroup> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeGroup");
+ formatter.field("elem", Lite(&self.value.elem));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypeImplTrait> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeImplTrait");
+ if !self.value.bounds.is_empty() {
+ formatter.field("bounds", Lite(&self.value.bounds));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypeInfer> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeInfer");
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypeMacro> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeMacro");
+ formatter.field("mac", Lite(&self.value.mac));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypeNever> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeNever");
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypeParam> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeParam");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ if self.value.colon_token.is_some() {
+ formatter.field("colon_token", &Present);
+ }
+ if !self.value.bounds.is_empty() {
+ formatter.field("bounds", Lite(&self.value.bounds));
+ }
+ if self.value.eq_token.is_some() {
+ formatter.field("eq_token", &Present);
+ }
+ if let Some(val) = &self.value.default {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Type);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("default", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypeParamBound> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::TypeParamBound::Trait(_val) => {
+ formatter.write_str("TypeParamBound::Trait")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::TypeParamBound::Lifetime(_val) => {
+ let mut formatter = formatter.debug_struct("TypeParamBound::Lifetime");
+ formatter.field("ident", Lite(&_val.ident));
+ formatter.finish()
+ }
+ syn::TypeParamBound::Verbatim(_val) => {
+ formatter.write_str("TypeParamBound::Verbatim")?;
+ formatter.write_str("(`")?;
+ Display::fmt(_val, formatter)?;
+ formatter.write_str("`)")?;
+ Ok(())
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::TypeParen> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeParen");
+ formatter.field("elem", Lite(&self.value.elem));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypePath> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypePath");
+ if let Some(val) = &self.value.qself {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::QSelf);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("qself", Print::ref_cast(val));
+ }
+ formatter.field("path", Lite(&self.value.path));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypePtr> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypePtr");
+ if self.value.const_token.is_some() {
+ formatter.field("const_token", &Present);
+ }
+ if self.value.mutability.is_some() {
+ formatter.field("mutability", &Present);
+ }
+ formatter.field("elem", Lite(&self.value.elem));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypeReference> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeReference");
+ if let Some(val) = &self.value.lifetime {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print(syn::Lifetime);
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("lifetime", Print::ref_cast(val));
+ }
+ if self.value.mutability.is_some() {
+ formatter.field("mutability", &Present);
+ }
+ formatter.field("elem", Lite(&self.value.elem));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypeSlice> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeSlice");
+ formatter.field("elem", Lite(&self.value.elem));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypeTraitObject> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeTraitObject");
+ if self.value.dyn_token.is_some() {
+ formatter.field("dyn_token", &Present);
+ }
+ if !self.value.bounds.is_empty() {
+ formatter.field("bounds", Lite(&self.value.bounds));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::TypeTuple> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("TypeTuple");
+ if !self.value.elems.is_empty() {
+ formatter.field("elems", Lite(&self.value.elems));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::UnOp> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::UnOp::Deref(_val) => {
+ formatter.write_str("UnOp::Deref")?;
+ Ok(())
+ }
+ syn::UnOp::Not(_val) => {
+ formatter.write_str("UnOp::Not")?;
+ Ok(())
+ }
+ syn::UnOp::Neg(_val) => {
+ formatter.write_str("UnOp::Neg")?;
+ Ok(())
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::UseGlob> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("UseGlob");
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::UseGroup> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("UseGroup");
+ if !self.value.items.is_empty() {
+ formatter.field("items", Lite(&self.value.items));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::UseName> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("UseName");
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::UsePath> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("UsePath");
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("tree", Lite(&self.value.tree));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::UseRename> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("UseRename");
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("rename", Lite(&self.value.rename));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::UseTree> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::UseTree::Path(_val) => {
+ formatter.write_str("UseTree::Path")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::UseTree::Name(_val) => {
+ formatter.write_str("UseTree::Name")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::UseTree::Rename(_val) => {
+ formatter.write_str("UseTree::Rename")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::UseTree::Glob(_val) => {
+ formatter.write_str("UseTree::Glob")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::UseTree::Group(_val) => {
+ formatter.write_str("UseTree::Group")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ }
+}
+impl Debug for Lite<syn::Variadic> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Variadic");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ if let Some(val) = &self.value.pat {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((Box<syn::Pat>, syn::token::Colon));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.0), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("pat", Print::ref_cast(val));
+ }
+ if self.value.comma.is_some() {
+ formatter.field("comma", &Present);
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Variant> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("Variant");
+ if !self.value.attrs.is_empty() {
+ formatter.field("attrs", Lite(&self.value.attrs));
+ }
+ formatter.field("ident", Lite(&self.value.ident));
+ formatter.field("fields", Lite(&self.value.fields));
+ if let Some(val) = &self.value.discriminant {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct Print((syn::token::Eq, syn::Expr));
+ impl Debug for Print {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some(")?;
+ Debug::fmt(Lite(&self.0.1), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ }
+ formatter.field("discriminant", Print::ref_cast(val));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::VisRestricted> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("VisRestricted");
+ if self.value.in_token.is_some() {
+ formatter.field("in_token", &Present);
+ }
+ formatter.field("path", Lite(&self.value.path));
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::Visibility> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::Visibility::Public(_val) => {
+ formatter.write_str("Visibility::Public")?;
+ Ok(())
+ }
+ syn::Visibility::Restricted(_val) => {
+ let mut formatter = formatter.debug_struct("Visibility::Restricted");
+ if _val.in_token.is_some() {
+ formatter.field("in_token", &Present);
+ }
+ formatter.field("path", Lite(&_val.path));
+ formatter.finish()
+ }
+ syn::Visibility::Inherited => formatter.write_str("Visibility::Inherited"),
+ }
+ }
+}
+impl Debug for Lite<syn::WhereClause> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut formatter = formatter.debug_struct("WhereClause");
+ if !self.value.predicates.is_empty() {
+ formatter.field("predicates", Lite(&self.value.predicates));
+ }
+ formatter.finish()
+ }
+}
+impl Debug for Lite<syn::WherePredicate> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match &self.value {
+ syn::WherePredicate::Lifetime(_val) => {
+ formatter.write_str("WherePredicate::Lifetime")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ syn::WherePredicate::Type(_val) => {
+ formatter.write_str("WherePredicate::Type")?;
+ formatter.write_str("(")?;
+ Debug::fmt(Lite(_val), formatter)?;
+ formatter.write_str(")")?;
+ Ok(())
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+impl Debug for Lite<syn::token::Abstract> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![abstract]")
+ }
+}
+impl Debug for Lite<syn::token::And> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![&]")
+ }
+}
+impl Debug for Lite<syn::token::AndAnd> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![&&]")
+ }
+}
+impl Debug for Lite<syn::token::AndEq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![&=]")
+ }
+}
+impl Debug for Lite<syn::token::As> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![as]")
+ }
+}
+impl Debug for Lite<syn::token::Async> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![async]")
+ }
+}
+impl Debug for Lite<syn::token::At> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![@]")
+ }
+}
+impl Debug for Lite<syn::token::Auto> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![auto]")
+ }
+}
+impl Debug for Lite<syn::token::Await> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![await]")
+ }
+}
+impl Debug for Lite<syn::token::Become> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![become]")
+ }
+}
+impl Debug for Lite<syn::token::Box> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![box]")
+ }
+}
+impl Debug for Lite<syn::token::Break> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![break]")
+ }
+}
+impl Debug for Lite<syn::token::Caret> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![^]")
+ }
+}
+impl Debug for Lite<syn::token::CaretEq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![^=]")
+ }
+}
+impl Debug for Lite<syn::token::Colon> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![:]")
+ }
+}
+impl Debug for Lite<syn::token::Comma> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![,]")
+ }
+}
+impl Debug for Lite<syn::token::Const> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![const]")
+ }
+}
+impl Debug for Lite<syn::token::Continue> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![continue]")
+ }
+}
+impl Debug for Lite<syn::token::Crate> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![crate]")
+ }
+}
+impl Debug for Lite<syn::token::Default> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![default]")
+ }
+}
+impl Debug for Lite<syn::token::Do> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![do]")
+ }
+}
+impl Debug for Lite<syn::token::Dollar> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![$]")
+ }
+}
+impl Debug for Lite<syn::token::Dot> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![.]")
+ }
+}
+impl Debug for Lite<syn::token::DotDot> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![..]")
+ }
+}
+impl Debug for Lite<syn::token::DotDotDot> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![...]")
+ }
+}
+impl Debug for Lite<syn::token::DotDotEq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![..=]")
+ }
+}
+impl Debug for Lite<syn::token::Dyn> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![dyn]")
+ }
+}
+impl Debug for Lite<syn::token::Else> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![else]")
+ }
+}
+impl Debug for Lite<syn::token::Enum> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![enum]")
+ }
+}
+impl Debug for Lite<syn::token::Eq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![=]")
+ }
+}
+impl Debug for Lite<syn::token::EqEq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![==]")
+ }
+}
+impl Debug for Lite<syn::token::Extern> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![extern]")
+ }
+}
+impl Debug for Lite<syn::token::FatArrow> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![=>]")
+ }
+}
+impl Debug for Lite<syn::token::Final> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![final]")
+ }
+}
+impl Debug for Lite<syn::token::Fn> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![fn]")
+ }
+}
+impl Debug for Lite<syn::token::For> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![for]")
+ }
+}
+impl Debug for Lite<syn::token::Ge> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![>=]")
+ }
+}
+impl Debug for Lite<syn::token::Gt> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![>]")
+ }
+}
+impl Debug for Lite<syn::token::If> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![if]")
+ }
+}
+impl Debug for Lite<syn::token::Impl> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![impl]")
+ }
+}
+impl Debug for Lite<syn::token::In> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![in]")
+ }
+}
+impl Debug for Lite<syn::token::LArrow> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![<-]")
+ }
+}
+impl Debug for Lite<syn::token::Le> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![<=]")
+ }
+}
+impl Debug for Lite<syn::token::Let> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![let]")
+ }
+}
+impl Debug for Lite<syn::token::Loop> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![loop]")
+ }
+}
+impl Debug for Lite<syn::token::Lt> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![<]")
+ }
+}
+impl Debug for Lite<syn::token::Macro> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![macro]")
+ }
+}
+impl Debug for Lite<syn::token::Match> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![match]")
+ }
+}
+impl Debug for Lite<syn::token::Minus> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![-]")
+ }
+}
+impl Debug for Lite<syn::token::MinusEq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![-=]")
+ }
+}
+impl Debug for Lite<syn::token::Mod> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![mod]")
+ }
+}
+impl Debug for Lite<syn::token::Move> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![move]")
+ }
+}
+impl Debug for Lite<syn::token::Mut> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![mut]")
+ }
+}
+impl Debug for Lite<syn::token::Ne> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![!=]")
+ }
+}
+impl Debug for Lite<syn::token::Not> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![!]")
+ }
+}
+impl Debug for Lite<syn::token::Or> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![|]")
+ }
+}
+impl Debug for Lite<syn::token::OrEq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![|=]")
+ }
+}
+impl Debug for Lite<syn::token::OrOr> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![||]")
+ }
+}
+impl Debug for Lite<syn::token::Override> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![override]")
+ }
+}
+impl Debug for Lite<syn::token::PathSep> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![::]")
+ }
+}
+impl Debug for Lite<syn::token::Percent> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![%]")
+ }
+}
+impl Debug for Lite<syn::token::PercentEq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![%=]")
+ }
+}
+impl Debug for Lite<syn::token::Plus> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![+]")
+ }
+}
+impl Debug for Lite<syn::token::PlusEq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![+=]")
+ }
+}
+impl Debug for Lite<syn::token::Pound> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![#]")
+ }
+}
+impl Debug for Lite<syn::token::Priv> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![priv]")
+ }
+}
+impl Debug for Lite<syn::token::Pub> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![pub]")
+ }
+}
+impl Debug for Lite<syn::token::Question> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![?]")
+ }
+}
+impl Debug for Lite<syn::token::RArrow> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![->]")
+ }
+}
+impl Debug for Lite<syn::token::Ref> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![ref]")
+ }
+}
+impl Debug for Lite<syn::token::Return> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![return]")
+ }
+}
+impl Debug for Lite<syn::token::SelfType> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![Self]")
+ }
+}
+impl Debug for Lite<syn::token::SelfValue> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![self]")
+ }
+}
+impl Debug for Lite<syn::token::Semi> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![;]")
+ }
+}
+impl Debug for Lite<syn::token::Shl> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![<<]")
+ }
+}
+impl Debug for Lite<syn::token::ShlEq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![<<=]")
+ }
+}
+impl Debug for Lite<syn::token::Shr> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![>>]")
+ }
+}
+impl Debug for Lite<syn::token::ShrEq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![>>=]")
+ }
+}
+impl Debug for Lite<syn::token::Slash> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![/]")
+ }
+}
+impl Debug for Lite<syn::token::SlashEq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![/=]")
+ }
+}
+impl Debug for Lite<syn::token::Star> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![*]")
+ }
+}
+impl Debug for Lite<syn::token::StarEq> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![*=]")
+ }
+}
+impl Debug for Lite<syn::token::Static> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![static]")
+ }
+}
+impl Debug for Lite<syn::token::Struct> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![struct]")
+ }
+}
+impl Debug for Lite<syn::token::Super> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![super]")
+ }
+}
+impl Debug for Lite<syn::token::Tilde> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![~]")
+ }
+}
+impl Debug for Lite<syn::token::Trait> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![trait]")
+ }
+}
+impl Debug for Lite<syn::token::Try> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![try]")
+ }
+}
+impl Debug for Lite<syn::token::Type> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![type]")
+ }
+}
+impl Debug for Lite<syn::token::Typeof> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![typeof]")
+ }
+}
+impl Debug for Lite<syn::token::Underscore> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![_]")
+ }
+}
+impl Debug for Lite<syn::token::Union> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![union]")
+ }
+}
+impl Debug for Lite<syn::token::Unsafe> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![unsafe]")
+ }
+}
+impl Debug for Lite<syn::token::Unsized> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![unsized]")
+ }
+}
+impl Debug for Lite<syn::token::Use> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![use]")
+ }
+}
+impl Debug for Lite<syn::token::Virtual> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![virtual]")
+ }
+}
+impl Debug for Lite<syn::token::Where> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![where]")
+ }
+}
+impl Debug for Lite<syn::token::While> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![while]")
+ }
+}
+impl Debug for Lite<syn::token::Yield> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Token![yield]")
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/debug/mod.rs b/rust/hw/char/pl011/vendor/syn/tests/debug/mod.rs
new file mode 100644
index 0000000000..c9925a6d5c
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/debug/mod.rs
@@ -0,0 +1,147 @@
+#![allow(
+ clippy::no_effect_underscore_binding,
+ clippy::too_many_lines,
+ clippy::used_underscore_binding
+)]
+
+#[rustfmt::skip]
+mod gen;
+
+use proc_macro2::{Ident, Literal, TokenStream};
+use ref_cast::RefCast;
+use std::fmt::{self, Debug};
+use std::ops::Deref;
+use syn::punctuated::Punctuated;
+
+#[derive(RefCast)]
+#[repr(transparent)]
+pub struct Lite<T: ?Sized> {
+ value: T,
+}
+
+#[allow(non_snake_case)]
+pub fn Lite<T: ?Sized>(value: &T) -> &Lite<T> {
+ Lite::ref_cast(value)
+}
+
+impl<T: ?Sized> Deref for Lite<T> {
+ type Target = T;
+
+ fn deref(&self) -> &Self::Target {
+ &self.value
+ }
+}
+
+impl Debug for Lite<bool> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{}", self.value)
+ }
+}
+
+impl Debug for Lite<u32> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{}", self.value)
+ }
+}
+
+impl Debug for Lite<usize> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{}", self.value)
+ }
+}
+
+impl Debug for Lite<String> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{:?}", self.value)
+ }
+}
+
+impl Debug for Lite<Ident> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{:?}", self.value.to_string())
+ }
+}
+
+impl Debug for Lite<Literal> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{}", self.value)
+ }
+}
+
+impl Debug for Lite<TokenStream> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let string = self.value.to_string();
+ if string.len() <= 80 {
+ write!(formatter, "TokenStream(`{}`)", self.value)
+ } else {
+ formatter
+ .debug_tuple("TokenStream")
+ .field(&format_args!("`{}`", string))
+ .finish()
+ }
+ }
+}
+
+impl<'a, T> Debug for Lite<&'a T>
+where
+ Lite<T>: Debug,
+{
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(Lite(self.value), formatter)
+ }
+}
+
+impl<T> Debug for Lite<Box<T>>
+where
+ Lite<T>: Debug,
+{
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(Lite(&*self.value), formatter)
+ }
+}
+
+impl<T> Debug for Lite<Vec<T>>
+where
+ Lite<T>: Debug,
+{
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_list()
+ .entries(self.value.iter().map(Lite))
+ .finish()
+ }
+}
+
+impl<T, P> Debug for Lite<Punctuated<T, P>>
+where
+ Lite<T>: Debug,
+ Lite<P>: Debug,
+{
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut list = formatter.debug_list();
+ for pair in self.pairs() {
+ let (node, punct) = pair.into_tuple();
+ list.entry(Lite(node));
+ list.entries(punct.map(Lite));
+ }
+ list.finish()
+ }
+}
+
+struct Present;
+
+impl Debug for Present {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Some")
+ }
+}
+
+struct Option {
+ present: bool,
+}
+
+impl Debug for Option {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(if self.present { "Some" } else { "None" })
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/macros/mod.rs b/rust/hw/char/pl011/vendor/syn/tests/macros/mod.rs
new file mode 100644
index 0000000000..1c1bacf459
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/macros/mod.rs
@@ -0,0 +1,93 @@
+#![allow(unused_macros, unused_macro_rules)]
+
+#[path = "../debug/mod.rs"]
+pub mod debug;
+
+use std::str::FromStr;
+use syn::parse::Result;
+
+macro_rules! errorf {
+ ($($tt:tt)*) => {{
+ use ::std::io::Write;
+ let stderr = ::std::io::stderr();
+ write!(stderr.lock(), $($tt)*).unwrap();
+ }};
+}
+
+macro_rules! punctuated {
+ ($($e:expr,)+) => {{
+ let mut seq = ::syn::punctuated::Punctuated::new();
+ $(
+ seq.push($e);
+ )+
+ seq
+ }};
+
+ ($($e:expr),+) => {
+ punctuated!($($e,)+)
+ };
+}
+
+macro_rules! snapshot {
+ ($($args:tt)*) => {
+ snapshot_impl!(() $($args)*)
+ };
+}
+
+macro_rules! snapshot_impl {
+ (($expr:ident) as $t:ty, @$snapshot:literal) => {
+ let tokens = crate::macros::TryIntoTokens::try_into_tokens($expr).unwrap();
+ let $expr: $t = syn::parse_quote!(#tokens);
+ let debug = crate::macros::debug::Lite(&$expr);
+ if !cfg!(miri) {
+ #[allow(clippy::needless_raw_string_hashes)] // https://github.com/mitsuhiko/insta/issues/389
+ {
+ insta::assert_debug_snapshot!(debug, @$snapshot);
+ }
+ }
+ };
+ (($($expr:tt)*) as $t:ty, @$snapshot:literal) => {{
+ let tokens = crate::macros::TryIntoTokens::try_into_tokens($($expr)*).unwrap();
+ let syntax_tree: $t = syn::parse_quote!(#tokens);
+ let debug = crate::macros::debug::Lite(&syntax_tree);
+ if !cfg!(miri) {
+ #[allow(clippy::needless_raw_string_hashes)]
+ {
+ insta::assert_debug_snapshot!(debug, @$snapshot);
+ }
+ }
+ syntax_tree
+ }};
+ (($($expr:tt)*) , @$snapshot:literal) => {{
+ let syntax_tree = $($expr)*;
+ let debug = crate::macros::debug::Lite(&syntax_tree);
+ if !cfg!(miri) {
+ #[allow(clippy::needless_raw_string_hashes)]
+ {
+ insta::assert_debug_snapshot!(debug, @$snapshot);
+ }
+ }
+ syntax_tree
+ }};
+ (($($expr:tt)*) $next:tt $($rest:tt)*) => {
+ snapshot_impl!(($($expr)* $next) $($rest)*)
+ };
+}
+
+pub trait TryIntoTokens {
+ #[allow(dead_code)]
+ fn try_into_tokens(self) -> Result<proc_macro2::TokenStream>;
+}
+
+impl<'a> TryIntoTokens for &'a str {
+ fn try_into_tokens(self) -> Result<proc_macro2::TokenStream> {
+ let tokens = proc_macro2::TokenStream::from_str(self)?;
+ Ok(tokens)
+ }
+}
+
+impl TryIntoTokens for proc_macro2::TokenStream {
+ fn try_into_tokens(self) -> Result<proc_macro2::TokenStream> {
+ Ok(self)
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/regression.rs b/rust/hw/char/pl011/vendor/syn/tests/regression.rs
new file mode 100644
index 0000000000..5c7fcddc8d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/regression.rs
@@ -0,0 +1,5 @@
+#![allow(clippy::let_underscore_untyped, clippy::uninlined_format_args)]
+
+mod regression {
+ automod::dir!("tests/regression");
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/regression/issue1108.rs b/rust/hw/char/pl011/vendor/syn/tests/regression/issue1108.rs
new file mode 100644
index 0000000000..11a82adaad
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/regression/issue1108.rs
@@ -0,0 +1,5 @@
+#[test]
+fn issue1108() {
+ let data = "impl<x<>>::x for";
+ let _ = syn::parse_file(data);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/regression/issue1235.rs b/rust/hw/char/pl011/vendor/syn/tests/regression/issue1235.rs
new file mode 100644
index 0000000000..8836030664
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/regression/issue1235.rs
@@ -0,0 +1,32 @@
+use proc_macro2::{Delimiter, Group};
+use quote::quote;
+
+#[test]
+fn main() {
+ // Okay. Rustc allows top-level `static` with no value syntactically, but
+ // not semantically. Syn parses as Item::Verbatim.
+ let tokens = quote! {
+ pub static FOO: usize;
+ pub static BAR: usize;
+ };
+ let file = syn::parse2::<syn::File>(tokens).unwrap();
+ println!("{:#?}", file);
+
+ // Okay.
+ let inner = Group::new(
+ Delimiter::None,
+ quote!(static FOO: usize = 0; pub static BAR: usize = 0),
+ );
+ let tokens = quote!(pub #inner;);
+ let file = syn::parse2::<syn::File>(tokens).unwrap();
+ println!("{:#?}", file);
+
+ // Formerly parser crash.
+ let inner = Group::new(
+ Delimiter::None,
+ quote!(static FOO: usize; pub static BAR: usize),
+ );
+ let tokens = quote!(pub #inner;);
+ let file = syn::parse2::<syn::File>(tokens).unwrap();
+ println!("{:#?}", file);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/repo/mod.rs b/rust/hw/char/pl011/vendor/syn/tests/repo/mod.rs
new file mode 100644
index 0000000000..c8400288d9
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/repo/mod.rs
@@ -0,0 +1,461 @@
+#![allow(clippy::manual_assert)]
+
+mod progress;
+
+use self::progress::Progress;
+use anyhow::Result;
+use flate2::read::GzDecoder;
+use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
+use std::collections::BTreeSet;
+use std::ffi::OsStr;
+use std::fs;
+use std::path::{Path, PathBuf};
+use tar::Archive;
+use walkdir::{DirEntry, WalkDir};
+
+const REVISION: &str = "becebb3158149a115cad8a402612e25436a7e37b";
+
+#[rustfmt::skip]
+static EXCLUDE_FILES: &[&str] = &[
+ // TODO: explicit tail calls: `become _g()`
+ // https://github.com/dtolnay/syn/issues/1501
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0209_become_expr.rs",
+ "tests/ui/explicit-tail-calls/return-lifetime-sub.rs",
+
+ // TODO: non-lifetime binders: `where for<'a, T> &'a Struct<T>: Trait`
+ // https://github.com/dtolnay/syn/issues/1435
+ "src/tools/rustfmt/tests/source/issue_5721.rs",
+ "src/tools/rustfmt/tests/source/non-lifetime-binders.rs",
+ "src/tools/rustfmt/tests/target/issue_5721.rs",
+ "src/tools/rustfmt/tests/target/non-lifetime-binders.rs",
+ "tests/rustdoc-json/non_lifetime_binders.rs",
+ "tests/rustdoc/inline_cross/auxiliary/non_lifetime_binders.rs",
+ "tests/rustdoc/non_lifetime_binders.rs",
+
+ // TODO: return type notation: `where T: Trait<method(): Send>`
+ // https://github.com/dtolnay/syn/issues/1434
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_associated_return_type_bounds.rs",
+ "tests/ui/associated-type-bounds/return-type-notation/basic.rs",
+ "tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.rs",
+ "tests/ui/feature-gates/feature-gate-return_type_notation.rs",
+
+ // TODO: lazy type alias syntax with where-clause in trailing position
+ // https://github.com/dtolnay/syn/issues/1525
+ "tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs",
+
+ // TODO: gen blocks and functions
+ // https://github.com/dtolnay/syn/issues/1526
+ "compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs",
+ "tests/ui/coroutine/async-gen-deduce-yield.rs",
+ "tests/ui/coroutine/async-gen-yield-ty-is-unit.rs",
+ "tests/ui/coroutine/async_gen_fn_iter.rs",
+ "tests/ui/coroutine/gen_block_is_fused_iter.rs",
+ "tests/ui/coroutine/gen_block_is_iter.rs",
+ "tests/ui/coroutine/gen_block_iterate.rs",
+ "tests/ui/coroutine/gen_fn_iter.rs",
+ "tests/ui/coroutine/gen_fn_lifetime_capture.rs",
+ "tests/ui/coroutine/return-types-diverge.rs",
+ "tests/ui/higher-ranked/builtin-closure-like-bounds.rs",
+ "tests/ui/sanitizer/cfi-coroutine.rs",
+
+ // TODO: `!` as a pattern
+ // https://github.com/dtolnay/syn/issues/1546
+ "tests/ui/rfcs/rfc-0000-never_patterns/diverges.rs",
+
+ // TODO: async trait bounds: `impl async Fn()`
+ // https://github.com/dtolnay/syn/issues/1628
+ "src/tools/miri/tests/pass/async-closure-captures.rs",
+ "src/tools/miri/tests/pass/async-closure-drop.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0211_async_trait_bound.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0212_const_trait_bound.rs",
+ "src/tools/rustfmt/tests/target/asyncness.rs",
+ "tests/codegen/async-closure-debug.rs",
+ "tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs",
+ "tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs",
+ "tests/ui/async-await/async-closures/auxiliary/foreign.rs",
+ "tests/ui/async-await/async-closures/brand.rs",
+ "tests/ui/async-await/async-closures/captures.rs",
+ "tests/ui/async-await/async-closures/constrained-but-no-upvars-yet.rs",
+ "tests/ui/async-await/async-closures/drop.rs",
+ "tests/ui/async-await/async-closures/mangle.rs",
+ "tests/ui/async-await/async-closures/moro-example.rs",
+ "tests/ui/async-await/async-closures/move-is-async-fn.rs",
+ "tests/ui/async-await/async-closures/mut-ref-reborrow.rs",
+ "tests/ui/async-await/async-closures/no-borrow-from-env.rs",
+ "tests/ui/async-await/async-closures/overlapping-projs.rs",
+ "tests/ui/async-await/async-closures/precise-captures.rs",
+ "tests/ui/async-await/async-closures/refd.rs",
+ "tests/ui/async-await/async-closures/signature-deduction.rs",
+ "tests/ui/async-await/async-fn/edition-2015-not-async-bound.rs",
+ "tests/ui/async-await/async-fn/higher-ranked-async-fn.rs",
+ "tests/ui/async-await/async-fn/impl-trait.rs",
+ "tests/ui/async-await/async-fn/project.rs",
+ "tests/ui/async-await/async-fn/sugar.rs",
+
+ // TODO: mutable by-reference bindings (mut ref)
+ // https://github.com/dtolnay/syn/issues/1629
+ "src/tools/rustfmt/tests/source/mut_ref.rs",
+ "src/tools/rustfmt/tests/target/mut_ref.rs",
+ "tests/ui/mut/mut-ref.rs",
+
+ // TODO: postfix match
+ // https://github.com/dtolnay/syn/issues/1630
+ "src/tools/rustfmt/tests/source/postfix-match/pf-match.rs",
+ "src/tools/rustfmt/tests/target/postfix-match/pf-match.rs",
+ "tests/pretty/postfix-match.rs",
+ "tests/ui/match/postfix-match/no-unused-parens.rs",
+ "tests/ui/match/postfix-match/pf-match-chain.rs",
+ "tests/ui/match/postfix-match/postfix-match.rs",
+
+ // TODO: delegation
+ // https://github.com/dtolnay/syn/issues/1580
+ "tests/pretty/delegation.rs",
+ "tests/ui/delegation/explicit-paths-in-traits-pass.rs",
+ "tests/ui/delegation/explicit-paths-pass.rs",
+ "tests/ui/delegation/explicit-paths-signature-pass.rs",
+ "tests/ui/delegation/parse.rs",
+
+ // TODO: for await
+ // https://github.com/dtolnay/syn/issues/1631
+ "tests/ui/async-await/for-await-2015.rs",
+ "tests/ui/async-await/for-await-passthrough.rs",
+ "tests/ui/async-await/for-await.rs",
+
+ // TODO: const trait bound: `T: const Trait`
+ // https://github.com/dtolnay/syn/issues/1632
+ "tests/ui/generic-const-items/const-trait-impl.rs",
+ "tests/ui/rfcs/rfc-2632-const-trait-impl/const-fns-are-early-bound.rs",
+ "tests/ui/rfcs/rfc-2632-const-trait-impl/const-trait-bounds.rs",
+ "tests/ui/rfcs/rfc-2632-const-trait-impl/effects/minicore.rs",
+
+ // TODO: `|| .. .method()`
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_closure_range_method_call.rs",
+ "src/tools/rustfmt/tests/source/issue-4808.rs",
+
+ // Compile-fail expr parameter in const generic position: f::<1 + 2>()
+ "tests/ui/const-generics/early/closing-args-token.rs",
+ "tests/ui/const-generics/early/const-expression-parameter.rs",
+
+ // Compile-fail variadics in not the last position of a function parameter list
+ "tests/ui/parser/variadic-ffi-syntactic-pass.rs",
+
+ // Need at least one trait in impl Trait, no such type as impl 'static
+ "tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs",
+
+ // Negative polarity trait bound: `where T: !Copy`
+ "src/tools/rustfmt/tests/target/negative-bounds.rs",
+ "tests/ui/traits/negative-bounds/supertrait.rs",
+
+ // Lifetime bound inside for<>: `T: ~const ?for<'a: 'b> Trait<'a>`
+ "tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-syntax.rs",
+
+ // Const impl that is not a trait impl: `impl ~const T {}`
+ "tests/ui/rfcs/rfc-2632-const-trait-impl/syntax.rs",
+
+ // Lifetimes and types out of order in angle bracketed path arguments
+ "tests/ui/parser/constraints-before-generic-args-syntactic-pass.rs",
+
+ // Deprecated anonymous parameter syntax in traits
+ "src/tools/rustfmt/tests/source/trait.rs",
+ "src/tools/rustfmt/tests/target/trait.rs",
+ "tests/ui/issues/issue-13105.rs",
+ "tests/ui/issues/issue-13775.rs",
+ "tests/ui/issues/issue-34074.rs",
+ "tests/ui/proc-macro/trait-fn-args-2015.rs",
+
+ // Deprecated where-clause location
+ "src/tools/rustfmt/tests/source/issue_4257.rs",
+ "src/tools/rustfmt/tests/source/issue_4911.rs",
+ "src/tools/rustfmt/tests/target/issue_4257.rs",
+ "src/tools/rustfmt/tests/target/issue_4911.rs",
+ "tests/pretty/gat-bounds.rs",
+ "tests/rustdoc/generic-associated-types/gats.rs",
+
+ // Deprecated trait object syntax with parenthesized generic arguments and no dyn keyword
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0104_path_fn_trait_args.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0209_bare_dyn_types_with_paren_as_generic_args.rs",
+ "src/tools/rustfmt/tests/source/attrib.rs",
+ "src/tools/rustfmt/tests/source/closure.rs",
+ "src/tools/rustfmt/tests/source/existential_type.rs",
+ "src/tools/rustfmt/tests/source/fn-simple.rs",
+ "src/tools/rustfmt/tests/source/fn_args_layout-vertical.rs",
+ "src/tools/rustfmt/tests/source/issue-4689/one.rs",
+ "src/tools/rustfmt/tests/source/issue-4689/two.rs",
+ "src/tools/rustfmt/tests/source/paths.rs",
+ "src/tools/rustfmt/tests/source/structs.rs",
+ "src/tools/rustfmt/tests/target/attrib.rs",
+ "src/tools/rustfmt/tests/target/closure.rs",
+ "src/tools/rustfmt/tests/target/existential_type.rs",
+ "src/tools/rustfmt/tests/target/fn-simple.rs",
+ "src/tools/rustfmt/tests/target/fn.rs",
+ "src/tools/rustfmt/tests/target/fn_args_layout-vertical.rs",
+ "src/tools/rustfmt/tests/target/issue-4689/one.rs",
+ "src/tools/rustfmt/tests/target/issue-4689/two.rs",
+ "src/tools/rustfmt/tests/target/paths.rs",
+ "src/tools/rustfmt/tests/target/structs.rs",
+ "tests/codegen-units/item-collection/non-generic-closures.rs",
+ "tests/debuginfo/recursive-enum.rs",
+ "tests/pretty/closure-reform-pretty.rs",
+ "tests/run-make/reproducible-build-2/reproducible-build.rs",
+ "tests/run-make/reproducible-build/reproducible-build.rs",
+ "tests/ui/auxiliary/typeid-intrinsic-aux1.rs",
+ "tests/ui/auxiliary/typeid-intrinsic-aux2.rs",
+ "tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs",
+ "tests/ui/lifetimes/auxiliary/lifetime_bound_will_change_warning_lib.rs",
+ "tests/ui/lifetimes/bare-trait-object-borrowck.rs",
+ "tests/ui/lifetimes/bare-trait-object.rs",
+ "tests/ui/parser/bounds-obj-parens.rs",
+
+ // Invalid unparenthesized range pattern inside slice pattern: `[1..]`
+ "tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs",
+
+ // Various extensions to Rust syntax made up by rust-analyzer
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0012_type_item_where_clause.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0123_param_list_vararg.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_fn_def_param.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0179_use_tree_abs_star.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0015_use_tree.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0029_range_forms.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0051_parameter_attrs.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0055_dot_dot_dot.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0068_item_modifiers.rs",
+ "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rs",
+ "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0038_endless_inclusive_range.rs",
+ "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0045_ambiguous_trait_object.rs",
+ "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0046_mutable_const_item.rs",
+
+ // Placeholder syntax for "throw expressions"
+ "compiler/rustc_errors/src/translation.rs",
+ "compiler/rustc_expand/src/module.rs",
+ "compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs",
+ "src/tools/clippy/tests/ui/needless_return.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0204_yeet_expr.rs",
+ "tests/pretty/yeet-expr.rs",
+ "tests/ui/try-trait/yeet-for-option.rs",
+ "tests/ui/try-trait/yeet-for-result.rs",
+
+ // Edition 2015 code using identifiers that are now keywords
+ // TODO: some of these we should probably parse
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0159_try_macro_fallback.rs",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0160_try_macro_rules.rs",
+ "src/tools/rustfmt/tests/source/configs/indent_style/block_call.rs",
+ "src/tools/rustfmt/tests/source/configs/use_try_shorthand/false.rs",
+ "src/tools/rustfmt/tests/source/configs/use_try_shorthand/true.rs",
+ "src/tools/rustfmt/tests/source/issue_1306.rs",
+ "src/tools/rustfmt/tests/source/try-conversion.rs",
+ "src/tools/rustfmt/tests/target/configs/indent_style/block_call.rs",
+ "src/tools/rustfmt/tests/target/configs/use_try_shorthand/false.rs",
+ "src/tools/rustfmt/tests/target/issue-1681.rs",
+ "src/tools/rustfmt/tests/target/issue_1306.rs",
+ "tests/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs",
+ "tests/ui/editions/edition-keywords-2015-2015.rs",
+ "tests/ui/editions/edition-keywords-2015-2018.rs",
+ "tests/ui/lint/lint_pre_expansion_extern_module_aux.rs",
+ "tests/ui/macros/macro-comma-support-rpass.rs",
+ "tests/ui/macros/try-macro.rs",
+ "tests/ui/parser/extern-crate-async.rs",
+ "tests/ui/try-block/try-is-identifier-edition2015.rs",
+
+ // Excessive nesting
+ "tests/ui/issues/issue-74564-if-expr-stack-overflow.rs",
+
+ // Testing tools on invalid syntax
+ "src/tools/rustfmt/tests/coverage/target/comments.rs",
+ "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs",
+ "src/tools/rustfmt/tests/parser/issue_4418.rs",
+ "src/tools/rustfmt/tests/parser/stashed-diag.rs",
+ "src/tools/rustfmt/tests/parser/stashed-diag2.rs",
+ "src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs",
+ "src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs",
+ "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs",
+ "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs",
+ "src/tools/rustfmt/tests/source/type.rs",
+ "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs",
+ "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs",
+ "src/tools/rustfmt/tests/target/type.rs",
+ "tests/run-make/translation/test.rs",
+ "tests/ui/generics/issue-94432-garbage-ice.rs",
+
+ // Generated file containing a top-level expression, used with `include!`
+ "compiler/rustc_codegen_gcc/src/intrinsic/archs.rs",
+
+ // Clippy lint lists represented as expressions
+ "src/tools/clippy/clippy_lints/src/lib.deprecated.rs",
+
+ // Not actually test cases
+ "tests/ui/lint/expansion-time-include.rs",
+ "tests/ui/macros/auxiliary/macro-comma-support.rs",
+ "tests/ui/macros/auxiliary/macro-include-items-expr.rs",
+ "tests/ui/macros/include-single-expr-helper.rs",
+ "tests/ui/macros/include-single-expr-helper-1.rs",
+ "tests/ui/parser/issues/auxiliary/issue-21146-inc.rs",
+];
+
+#[rustfmt::skip]
+static EXCLUDE_DIRS: &[&str] = &[
+ // Inputs that intentionally do not parse
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/err",
+ "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err",
+
+ // Inputs that lex but do not necessarily parse
+ "src/tools/rust-analyzer/crates/parser/test_data/lexer",
+
+ // Inputs that used to crash rust-analyzer, but aren't necessarily supposed to parse
+ "src/tools/rust-analyzer/crates/syntax/test_data/parser/fuzz-failures",
+ "src/tools/rust-analyzer/crates/syntax/test_data/reparse/fuzz-failures",
+
+ // Inputs that crash rustc, making no claim about whether they are valid Rust
+ "tests/crashes",
+];
+
+// Directories in which a .stderr implies the corresponding .rs is not expected
+// to work.
+static UI_TEST_DIRS: &[&str] = &["tests/ui", "tests/rustdoc-ui"];
+
+pub fn for_each_rust_file(for_each: impl Fn(&Path) + Sync + Send) {
+ let mut rs_files = BTreeSet::new();
+
+ let repo_dir = Path::new("tests/rust");
+ for entry in WalkDir::new(repo_dir)
+ .into_iter()
+ .filter_entry(base_dir_filter)
+ {
+ let entry = entry.unwrap();
+ if !entry.file_type().is_dir() {
+ rs_files.insert(entry.into_path());
+ }
+ }
+
+ for ui_test_dir in UI_TEST_DIRS {
+ for entry in WalkDir::new(repo_dir.join(ui_test_dir)) {
+ let mut path = entry.unwrap().into_path();
+ if path.extension() == Some(OsStr::new("stderr")) {
+ loop {
+ rs_files.remove(&path.with_extension("rs"));
+ path = path.with_extension("");
+ if path.extension().is_none() {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ rs_files.par_iter().map(PathBuf::as_path).for_each(for_each);
+}
+
+pub fn base_dir_filter(entry: &DirEntry) -> bool {
+ let path = entry.path();
+
+ let mut path_string = path.to_string_lossy();
+ if cfg!(windows) {
+ path_string = path_string.replace('\\', "/").into();
+ }
+ let path_string = if path_string == "tests/rust" {
+ return true;
+ } else if let Some(path) = path_string.strip_prefix("tests/rust/") {
+ path
+ } else {
+ panic!("unexpected path in Rust dist: {}", path_string);
+ };
+
+ if path.is_dir() {
+ return !EXCLUDE_DIRS.contains(&path_string);
+ }
+
+ if path.extension() != Some(OsStr::new("rs")) {
+ return false;
+ }
+
+ !EXCLUDE_FILES.contains(&path_string)
+}
+
+#[allow(dead_code)]
+pub fn edition(path: &Path) -> &'static str {
+ if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
+ "2015"
+ } else {
+ "2021"
+ }
+}
+
+pub fn clone_rust() {
+ let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
+ Err(_) => true,
+ Ok(contents) => contents.trim() != REVISION,
+ };
+ if needs_clone {
+ download_and_unpack().unwrap();
+ }
+
+ let mut missing = String::new();
+ let test_src = Path::new("tests/rust");
+
+ let mut exclude_files_set = BTreeSet::new();
+ for exclude in EXCLUDE_FILES {
+ if !exclude_files_set.insert(exclude) {
+ panic!("duplicate path in EXCLUDE_FILES: {}", exclude);
+ }
+ for dir in EXCLUDE_DIRS {
+ if Path::new(exclude).starts_with(dir) {
+ panic!("excluded file {} is inside an excluded dir", exclude);
+ }
+ }
+ if !test_src.join(exclude).is_file() {
+ missing += "\ntests/rust/";
+ missing += exclude;
+ }
+ }
+
+ let mut exclude_dirs_set = BTreeSet::new();
+ for exclude in EXCLUDE_DIRS {
+ if !exclude_dirs_set.insert(exclude) {
+ panic!("duplicate path in EXCLUDE_DIRS: {}", exclude);
+ }
+ if !test_src.join(exclude).is_dir() {
+ missing += "\ntests/rust/";
+ missing += exclude;
+ missing += "/";
+ }
+ }
+
+ if !missing.is_empty() {
+ panic!("excluded test file does not exist:{}\n", missing);
+ }
+}
+
+fn download_and_unpack() -> Result<()> {
+ let url = format!(
+ "https://github.com/rust-lang/rust/archive/{}.tar.gz",
+ REVISION
+ );
+ let response = reqwest::blocking::get(url)?.error_for_status()?;
+ let progress = Progress::new(response);
+ let decoder = GzDecoder::new(progress);
+ let mut archive = Archive::new(decoder);
+ let prefix = format!("rust-{}", REVISION);
+
+ let tests_rust = Path::new("tests/rust");
+ if tests_rust.exists() {
+ fs::remove_dir_all(tests_rust)?;
+ }
+
+ for entry in archive.entries()? {
+ let mut entry = entry?;
+ let path = entry.path()?;
+ if path == Path::new("pax_global_header") {
+ continue;
+ }
+ let relative = path.strip_prefix(&prefix)?;
+ let out = tests_rust.join(relative);
+ entry.unpack(&out)?;
+ }
+
+ fs::write("tests/rust/COMMIT", REVISION)?;
+ Ok(())
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/repo/progress.rs b/rust/hw/char/pl011/vendor/syn/tests/repo/progress.rs
new file mode 100644
index 0000000000..28c8a44b12
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/repo/progress.rs
@@ -0,0 +1,37 @@
+use std::io::{Read, Result};
+use std::time::{Duration, Instant};
+
+pub struct Progress<R> {
+ bytes: usize,
+ tick: Instant,
+ stream: R,
+}
+
+impl<R> Progress<R> {
+ pub fn new(stream: R) -> Self {
+ Progress {
+ bytes: 0,
+ tick: Instant::now() + Duration::from_millis(2000),
+ stream,
+ }
+ }
+}
+
+impl<R: Read> Read for Progress<R> {
+ fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
+ let num = self.stream.read(buf)?;
+ self.bytes += num;
+ let now = Instant::now();
+ if now > self.tick {
+ self.tick = now + Duration::from_millis(500);
+ errorf!("downloading... {} bytes\n", self.bytes);
+ }
+ Ok(num)
+ }
+}
+
+impl<R> Drop for Progress<R> {
+ fn drop(&mut self) {
+ errorf!("done ({} bytes)\n", self.bytes);
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_asyncness.rs b/rust/hw/char/pl011/vendor/syn/tests/test_asyncness.rs
new file mode 100644
index 0000000000..9968934490
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_asyncness.rs
@@ -0,0 +1,43 @@
+#![allow(clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+use syn::{Expr, Item};
+
+#[test]
+fn test_async_fn() {
+ let input = "async fn process() {}";
+
+ snapshot!(input as Item, @r###"
+ Item::Fn {
+ vis: Visibility::Inherited,
+ sig: Signature {
+ asyncness: Some,
+ ident: "process",
+ generics: Generics,
+ output: ReturnType::Default,
+ },
+ block: Block {
+ stmts: [],
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_async_closure() {
+ let input = "async || {}";
+
+ snapshot!(input as Expr, @r###"
+ Expr::Closure {
+ asyncness: Some,
+ output: ReturnType::Default,
+ body: Expr::Block {
+ block: Block {
+ stmts: [],
+ },
+ },
+ }
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_attribute.rs b/rust/hw/char/pl011/vendor/syn/tests/test_attribute.rs
new file mode 100644
index 0000000000..597ae3adc8
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_attribute.rs
@@ -0,0 +1,225 @@
+#![allow(clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+use syn::parse::Parser;
+use syn::{Attribute, Meta};
+
+#[test]
+fn test_meta_item_word() {
+ let meta = test("#[foo]");
+
+ snapshot!(meta, @r###"
+ Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ }
+ "###);
+}
+
+#[test]
+fn test_meta_item_name_value() {
+ let meta = test("#[foo = 5]");
+
+ snapshot!(meta, @r###"
+ Meta::NameValue {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ value: Expr::Lit {
+ lit: 5,
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_meta_item_bool_value() {
+ let meta = test("#[foo = true]");
+
+ snapshot!(meta, @r###"
+ Meta::NameValue {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ value: Expr::Lit {
+ lit: Lit::Bool {
+ value: true,
+ },
+ },
+ }
+ "###);
+
+ let meta = test("#[foo = false]");
+
+ snapshot!(meta, @r###"
+ Meta::NameValue {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ value: Expr::Lit {
+ lit: Lit::Bool {
+ value: false,
+ },
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_meta_item_list_lit() {
+ let meta = test("#[foo(5)]");
+
+ snapshot!(meta, @r###"
+ Meta::List {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`5`),
+ }
+ "###);
+}
+
+#[test]
+fn test_meta_item_list_word() {
+ let meta = test("#[foo(bar)]");
+
+ snapshot!(meta, @r###"
+ Meta::List {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`bar`),
+ }
+ "###);
+}
+
+#[test]
+fn test_meta_item_list_name_value() {
+ let meta = test("#[foo(bar = 5)]");
+
+ snapshot!(meta, @r###"
+ Meta::List {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`bar = 5`),
+ }
+ "###);
+}
+
+#[test]
+fn test_meta_item_list_bool_value() {
+ let meta = test("#[foo(bar = true)]");
+
+ snapshot!(meta, @r###"
+ Meta::List {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`bar = true`),
+ }
+ "###);
+}
+
+#[test]
+fn test_meta_item_multiple() {
+ let meta = test("#[foo(word, name = 5, list(name2 = 6), word2)]");
+
+ snapshot!(meta, @r###"
+ Meta::List {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`word , name = 5 , list (name2 = 6) , word2`),
+ }
+ "###);
+}
+
+#[test]
+fn test_bool_lit() {
+ let meta = test("#[foo(true)]");
+
+ snapshot!(meta, @r###"
+ Meta::List {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`true`),
+ }
+ "###);
+}
+
+#[test]
+fn test_negative_lit() {
+ let meta = test("#[form(min = -1, max = 200)]");
+
+ snapshot!(meta, @r###"
+ Meta::List {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "form",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`min = - 1 , max = 200`),
+ }
+ "###);
+}
+
+fn test(input: &str) -> Meta {
+ let attrs = Attribute::parse_outer.parse_str(input).unwrap();
+
+ assert_eq!(attrs.len(), 1);
+ let attr = attrs.into_iter().next().unwrap();
+
+ attr.meta
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_derive_input.rs b/rust/hw/char/pl011/vendor/syn/tests/test_derive_input.rs
new file mode 100644
index 0000000000..c3d31eb0e9
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_derive_input.rs
@@ -0,0 +1,781 @@
+#![allow(
+ clippy::assertions_on_result_states,
+ clippy::manual_let_else,
+ clippy::too_many_lines,
+ clippy::uninlined_format_args
+)]
+
+#[macro_use]
+mod macros;
+
+use quote::quote;
+use syn::{Data, DeriveInput};
+
+#[test]
+fn test_unit() {
+ let input = quote! {
+ struct Unit;
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Inherited,
+ ident: "Unit",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Unit,
+ semi_token: Some,
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_struct() {
+ let input = quote! {
+ #[derive(Debug, Clone)]
+ pub struct Item {
+ pub ident: Ident,
+ pub attrs: Vec<Attribute>
+ }
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ attrs: [
+ Attribute {
+ style: AttrStyle::Outer,
+ meta: Meta::List {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "derive",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`Debug , Clone`),
+ },
+ },
+ ],
+ vis: Visibility::Public,
+ ident: "Item",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Named {
+ named: [
+ Field {
+ vis: Visibility::Public,
+ ident: Some("ident"),
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Ident",
+ },
+ ],
+ },
+ },
+ },
+ Token![,],
+ Field {
+ vis: Visibility::Public,
+ ident: Some("attrs"),
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Vec",
+ arguments: PathArguments::AngleBracketed {
+ args: [
+ GenericArgument::Type(Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Attribute",
+ },
+ ],
+ },
+ }),
+ ],
+ },
+ },
+ ],
+ },
+ },
+ },
+ ],
+ },
+ },
+ }
+ "###);
+
+ snapshot!(&input.attrs[0].meta, @r###"
+ Meta::List {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "derive",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`Debug , Clone`),
+ }
+ "###);
+}
+
+#[test]
+fn test_union() {
+ let input = quote! {
+ union MaybeUninit<T> {
+ uninit: (),
+ value: T
+ }
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Inherited,
+ ident: "MaybeUninit",
+ generics: Generics {
+ lt_token: Some,
+ params: [
+ GenericParam::Type(TypeParam {
+ ident: "T",
+ }),
+ ],
+ gt_token: Some,
+ },
+ data: Data::Union {
+ fields: FieldsNamed {
+ named: [
+ Field {
+ vis: Visibility::Inherited,
+ ident: Some("uninit"),
+ colon_token: Some,
+ ty: Type::Tuple,
+ },
+ Token![,],
+ Field {
+ vis: Visibility::Inherited,
+ ident: Some("value"),
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "T",
+ },
+ ],
+ },
+ },
+ },
+ ],
+ },
+ },
+ }
+ "###);
+}
+
+#[test]
+#[cfg(feature = "full")]
+fn test_enum() {
+ let input = quote! {
+ /// See the std::result module documentation for details.
+ #[must_use]
+ pub enum Result<T, E> {
+ Ok(T),
+ Err(E),
+ Surprise = 0isize,
+
+ // Smuggling data into a proc_macro_derive,
+ // in the style of https://github.com/dtolnay/proc-macro-hack
+ ProcMacroHack = (0, "data").0
+ }
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ attrs: [
+ Attribute {
+ style: AttrStyle::Outer,
+ meta: Meta::NameValue {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "doc",
+ },
+ ],
+ },
+ value: Expr::Lit {
+ lit: " See the std::result module documentation for details.",
+ },
+ },
+ },
+ Attribute {
+ style: AttrStyle::Outer,
+ meta: Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "must_use",
+ },
+ ],
+ },
+ },
+ ],
+ vis: Visibility::Public,
+ ident: "Result",
+ generics: Generics {
+ lt_token: Some,
+ params: [
+ GenericParam::Type(TypeParam {
+ ident: "T",
+ }),
+ Token![,],
+ GenericParam::Type(TypeParam {
+ ident: "E",
+ }),
+ ],
+ gt_token: Some,
+ },
+ data: Data::Enum {
+ variants: [
+ Variant {
+ ident: "Ok",
+ fields: Fields::Unnamed {
+ unnamed: [
+ Field {
+ vis: Visibility::Inherited,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "T",
+ },
+ ],
+ },
+ },
+ },
+ ],
+ },
+ },
+ Token![,],
+ Variant {
+ ident: "Err",
+ fields: Fields::Unnamed {
+ unnamed: [
+ Field {
+ vis: Visibility::Inherited,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "E",
+ },
+ ],
+ },
+ },
+ },
+ ],
+ },
+ },
+ Token![,],
+ Variant {
+ ident: "Surprise",
+ fields: Fields::Unit,
+ discriminant: Some(Expr::Lit {
+ lit: 0isize,
+ }),
+ },
+ Token![,],
+ Variant {
+ ident: "ProcMacroHack",
+ fields: Fields::Unit,
+ discriminant: Some(Expr::Field {
+ base: Expr::Tuple {
+ elems: [
+ Expr::Lit {
+ lit: 0,
+ },
+ Token![,],
+ Expr::Lit {
+ lit: "data",
+ },
+ ],
+ },
+ member: Member::Unnamed(Index {
+ index: 0,
+ }),
+ }),
+ },
+ ],
+ },
+ }
+ "###);
+
+ let meta_items: Vec<_> = input.attrs.into_iter().map(|attr| attr.meta).collect();
+
+ snapshot!(meta_items, @r###"
+ [
+ Meta::NameValue {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "doc",
+ },
+ ],
+ },
+ value: Expr::Lit {
+ lit: " See the std::result module documentation for details.",
+ },
+ },
+ Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "must_use",
+ },
+ ],
+ },
+ ]
+ "###);
+}
+
+#[test]
+fn test_attr_with_non_mod_style_path() {
+ let input = quote! {
+ #[inert <T>]
+ struct S;
+ };
+
+ syn::parse2::<DeriveInput>(input).unwrap_err();
+}
+
+#[test]
+fn test_attr_with_mod_style_path_with_self() {
+ let input = quote! {
+ #[foo::self]
+ struct S;
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ attrs: [
+ Attribute {
+ style: AttrStyle::Outer,
+ meta: Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ Token![::],
+ PathSegment {
+ ident: "self",
+ },
+ ],
+ },
+ },
+ ],
+ vis: Visibility::Inherited,
+ ident: "S",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Unit,
+ semi_token: Some,
+ },
+ }
+ "###);
+
+ snapshot!(&input.attrs[0].meta, @r###"
+ Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ Token![::],
+ PathSegment {
+ ident: "self",
+ },
+ ],
+ }
+ "###);
+}
+
+#[test]
+fn test_pub_restricted() {
+ // Taken from tests/rust/src/test/ui/resolve/auxiliary/privacy-struct-ctor.rs
+ let input = quote! {
+ pub(in m) struct Z(pub(in m::n) u8);
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Restricted {
+ in_token: Some,
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "m",
+ },
+ ],
+ },
+ },
+ ident: "Z",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Unnamed {
+ unnamed: [
+ Field {
+ vis: Visibility::Restricted {
+ in_token: Some,
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "m",
+ },
+ Token![::],
+ PathSegment {
+ ident: "n",
+ },
+ ],
+ },
+ },
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "u8",
+ },
+ ],
+ },
+ },
+ },
+ ],
+ },
+ semi_token: Some,
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_pub_restricted_crate() {
+ let input = quote! {
+ pub(crate) struct S;
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Restricted {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "crate",
+ },
+ ],
+ },
+ },
+ ident: "S",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Unit,
+ semi_token: Some,
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_pub_restricted_super() {
+ let input = quote! {
+ pub(super) struct S;
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Restricted {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "super",
+ },
+ ],
+ },
+ },
+ ident: "S",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Unit,
+ semi_token: Some,
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_pub_restricted_in_super() {
+ let input = quote! {
+ pub(in super) struct S;
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Restricted {
+ in_token: Some,
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "super",
+ },
+ ],
+ },
+ },
+ ident: "S",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Unit,
+ semi_token: Some,
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_fields_on_unit_struct() {
+ let input = quote! {
+ struct S;
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Inherited,
+ ident: "S",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Unit,
+ semi_token: Some,
+ },
+ }
+ "###);
+
+ let data = match input.data {
+ Data::Struct(data) => data,
+ _ => panic!("expected a struct"),
+ };
+
+ assert_eq!(0, data.fields.iter().count());
+}
+
+#[test]
+fn test_fields_on_named_struct() {
+ let input = quote! {
+ struct S {
+ foo: i32,
+ pub bar: String,
+ }
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Inherited,
+ ident: "S",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Named {
+ named: [
+ Field {
+ vis: Visibility::Inherited,
+ ident: Some("foo"),
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "i32",
+ },
+ ],
+ },
+ },
+ },
+ Token![,],
+ Field {
+ vis: Visibility::Public,
+ ident: Some("bar"),
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "String",
+ },
+ ],
+ },
+ },
+ },
+ Token![,],
+ ],
+ },
+ },
+ }
+ "###);
+
+ let data = match input.data {
+ Data::Struct(data) => data,
+ _ => panic!("expected a struct"),
+ };
+
+ snapshot!(data.fields.into_iter().collect::<Vec<_>>(), @r###"
+ [
+ Field {
+ vis: Visibility::Inherited,
+ ident: Some("foo"),
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "i32",
+ },
+ ],
+ },
+ },
+ },
+ Field {
+ vis: Visibility::Public,
+ ident: Some("bar"),
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "String",
+ },
+ ],
+ },
+ },
+ },
+ ]
+ "###);
+}
+
+#[test]
+fn test_fields_on_tuple_struct() {
+ let input = quote! {
+ struct S(i32, pub String);
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Inherited,
+ ident: "S",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Unnamed {
+ unnamed: [
+ Field {
+ vis: Visibility::Inherited,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "i32",
+ },
+ ],
+ },
+ },
+ },
+ Token![,],
+ Field {
+ vis: Visibility::Public,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "String",
+ },
+ ],
+ },
+ },
+ },
+ ],
+ },
+ semi_token: Some,
+ },
+ }
+ "###);
+
+ let data = match input.data {
+ Data::Struct(data) => data,
+ _ => panic!("expected a struct"),
+ };
+
+ snapshot!(data.fields.iter().collect::<Vec<_>>(), @r###"
+ [
+ Field {
+ vis: Visibility::Inherited,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "i32",
+ },
+ ],
+ },
+ },
+ },
+ Field {
+ vis: Visibility::Public,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "String",
+ },
+ ],
+ },
+ },
+ },
+ ]
+ "###);
+}
+
+#[test]
+fn test_ambiguous_crate() {
+ let input = quote! {
+ // The field type is `(crate::X)` not `crate (::X)`.
+ struct S(crate::X);
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Inherited,
+ ident: "S",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Unnamed {
+ unnamed: [
+ Field {
+ vis: Visibility::Inherited,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "crate",
+ },
+ Token![::],
+ PathSegment {
+ ident: "X",
+ },
+ ],
+ },
+ },
+ },
+ ],
+ },
+ semi_token: Some,
+ },
+ }
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_expr.rs b/rust/hw/char/pl011/vendor/syn/tests/test_expr.rs
new file mode 100644
index 0000000000..961e3c4ea3
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_expr.rs
@@ -0,0 +1,692 @@
+#![allow(clippy::single_element_loop, clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+use proc_macro2::{Delimiter, Group};
+use quote::{quote, ToTokens as _};
+use std::mem;
+use syn::punctuated::Punctuated;
+use syn::visit_mut::{self, VisitMut};
+use syn::{parse_quote, token, Expr, ExprRange, ExprTuple, Stmt, Token};
+
+#[test]
+fn test_expr_parse() {
+ let tokens = quote!(..100u32);
+ snapshot!(tokens as Expr, @r###"
+ Expr::Range {
+ limits: RangeLimits::HalfOpen,
+ end: Some(Expr::Lit {
+ lit: 100u32,
+ }),
+ }
+ "###);
+
+ let tokens = quote!(..100u32);
+ snapshot!(tokens as ExprRange, @r###"
+ ExprRange {
+ limits: RangeLimits::HalfOpen,
+ end: Some(Expr::Lit {
+ lit: 100u32,
+ }),
+ }
+ "###);
+}
+
+#[test]
+fn test_await() {
+ // Must not parse as Expr::Field.
+ let tokens = quote!(fut.await);
+
+ snapshot!(tokens as Expr, @r###"
+ Expr::Await {
+ base: Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "fut",
+ },
+ ],
+ },
+ },
+ }
+ "###);
+}
+
+#[rustfmt::skip]
+#[test]
+fn test_tuple_multi_index() {
+ let expected = snapshot!("tuple.0.0" as Expr, @r###"
+ Expr::Field {
+ base: Expr::Field {
+ base: Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "tuple",
+ },
+ ],
+ },
+ },
+ member: Member::Unnamed(Index {
+ index: 0,
+ }),
+ },
+ member: Member::Unnamed(Index {
+ index: 0,
+ }),
+ }
+ "###);
+
+ for &input in &[
+ "tuple .0.0",
+ "tuple. 0.0",
+ "tuple.0 .0",
+ "tuple.0. 0",
+ "tuple . 0 . 0",
+ ] {
+ assert_eq!(expected, syn::parse_str(input).unwrap());
+ }
+
+ for tokens in [
+ quote!(tuple.0.0),
+ quote!(tuple .0.0),
+ quote!(tuple. 0.0),
+ quote!(tuple.0 .0),
+ quote!(tuple.0. 0),
+ quote!(tuple . 0 . 0),
+ ] {
+ assert_eq!(expected, syn::parse2(tokens).unwrap());
+ }
+}
+
+#[test]
+fn test_macro_variable_func() {
+ // mimics the token stream corresponding to `$fn()`
+ let path = Group::new(Delimiter::None, quote!(f));
+ let tokens = quote!(#path());
+
+ snapshot!(tokens as Expr, @r###"
+ Expr::Call {
+ func: Expr::Group {
+ expr: Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "f",
+ },
+ ],
+ },
+ },
+ },
+ }
+ "###);
+
+ let path = Group::new(Delimiter::None, quote! { #[inside] f });
+ let tokens = quote!(#[outside] #path());
+
+ snapshot!(tokens as Expr, @r###"
+ Expr::Call {
+ attrs: [
+ Attribute {
+ style: AttrStyle::Outer,
+ meta: Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "outside",
+ },
+ ],
+ },
+ },
+ ],
+ func: Expr::Group {
+ expr: Expr::Path {
+ attrs: [
+ Attribute {
+ style: AttrStyle::Outer,
+ meta: Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "inside",
+ },
+ ],
+ },
+ },
+ ],
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "f",
+ },
+ ],
+ },
+ },
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_macro_variable_macro() {
+ // mimics the token stream corresponding to `$macro!()`
+ let mac = Group::new(Delimiter::None, quote!(m));
+ let tokens = quote!(#mac!());
+
+ snapshot!(tokens as Expr, @r###"
+ Expr::Macro {
+ mac: Macro {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "m",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(``),
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_macro_variable_struct() {
+ // mimics the token stream corresponding to `$struct {}`
+ let s = Group::new(Delimiter::None, quote! { S });
+ let tokens = quote!(#s {});
+
+ snapshot!(tokens as Expr, @r###"
+ Expr::Struct {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "S",
+ },
+ ],
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_macro_variable_unary() {
+ // mimics the token stream corresponding to `$expr.method()` where expr is `&self`
+ let inner = Group::new(Delimiter::None, quote!(&self));
+ let tokens = quote!(#inner.method());
+ snapshot!(tokens as Expr, @r###"
+ Expr::MethodCall {
+ receiver: Expr::Group {
+ expr: Expr::Reference {
+ expr: Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "self",
+ },
+ ],
+ },
+ },
+ },
+ },
+ method: "method",
+ }
+ "###);
+}
+
+#[test]
+fn test_macro_variable_match_arm() {
+ // mimics the token stream corresponding to `match v { _ => $expr }`
+ let expr = Group::new(Delimiter::None, quote! { #[a] () });
+ let tokens = quote!(match v { _ => #expr });
+ snapshot!(tokens as Expr, @r###"
+ Expr::Match {
+ expr: Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "v",
+ },
+ ],
+ },
+ },
+ arms: [
+ Arm {
+ pat: Pat::Wild,
+ body: Expr::Group {
+ expr: Expr::Tuple {
+ attrs: [
+ Attribute {
+ style: AttrStyle::Outer,
+ meta: Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "a",
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ },
+ ],
+ }
+ "###);
+
+ let expr = Group::new(Delimiter::None, quote!(loop {} + 1));
+ let tokens = quote!(match v { _ => #expr });
+ snapshot!(tokens as Expr, @r###"
+ Expr::Match {
+ expr: Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "v",
+ },
+ ],
+ },
+ },
+ arms: [
+ Arm {
+ pat: Pat::Wild,
+ body: Expr::Group {
+ expr: Expr::Binary {
+ left: Expr::Loop {
+ body: Block {
+ stmts: [],
+ },
+ },
+ op: BinOp::Add,
+ right: Expr::Lit {
+ lit: 1,
+ },
+ },
+ },
+ },
+ ],
+ }
+ "###);
+}
+
+// https://github.com/dtolnay/syn/issues/1019
+#[test]
+fn test_closure_vs_rangefull() {
+ #[rustfmt::skip] // rustfmt bug: https://github.com/rust-lang/rustfmt/issues/4808
+ let tokens = quote!(|| .. .method());
+ snapshot!(tokens as Expr, @r###"
+ Expr::MethodCall {
+ receiver: Expr::Closure {
+ output: ReturnType::Default,
+ body: Expr::Range {
+ limits: RangeLimits::HalfOpen,
+ },
+ },
+ method: "method",
+ }
+ "###);
+}
+
+#[test]
+fn test_postfix_operator_after_cast() {
+ syn::parse_str::<Expr>("|| &x as T[0]").unwrap_err();
+ syn::parse_str::<Expr>("|| () as ()()").unwrap_err();
+}
+
+#[test]
+fn test_range_kinds() {
+ syn::parse_str::<Expr>("..").unwrap();
+ syn::parse_str::<Expr>("..hi").unwrap();
+ syn::parse_str::<Expr>("lo..").unwrap();
+ syn::parse_str::<Expr>("lo..hi").unwrap();
+
+ syn::parse_str::<Expr>("..=").unwrap_err();
+ syn::parse_str::<Expr>("..=hi").unwrap();
+ syn::parse_str::<Expr>("lo..=").unwrap_err();
+ syn::parse_str::<Expr>("lo..=hi").unwrap();
+
+ syn::parse_str::<Expr>("...").unwrap_err();
+ syn::parse_str::<Expr>("...hi").unwrap_err();
+ syn::parse_str::<Expr>("lo...").unwrap_err();
+ syn::parse_str::<Expr>("lo...hi").unwrap_err();
+}
+
+#[test]
+fn test_range_precedence() {
+ snapshot!(".. .." as Expr, @r###"
+ Expr::Range {
+ limits: RangeLimits::HalfOpen,
+ end: Some(Expr::Range {
+ limits: RangeLimits::HalfOpen,
+ }),
+ }
+ "###);
+
+ snapshot!(".. .. ()" as Expr, @r###"
+ Expr::Range {
+ limits: RangeLimits::HalfOpen,
+ end: Some(Expr::Range {
+ limits: RangeLimits::HalfOpen,
+ end: Some(Expr::Tuple),
+ }),
+ }
+ "###);
+
+ snapshot!("() .. .." as Expr, @r###"
+ Expr::Range {
+ start: Some(Expr::Tuple),
+ limits: RangeLimits::HalfOpen,
+ end: Some(Expr::Range {
+ limits: RangeLimits::HalfOpen,
+ }),
+ }
+ "###);
+
+ // A range with a lower bound cannot be the upper bound of another range,
+ // and a range with an upper bound cannot be the lower bound of another
+ // range.
+ syn::parse_str::<Expr>(".. x ..").unwrap_err();
+ syn::parse_str::<Expr>("x .. x ..").unwrap_err();
+}
+
+#[test]
+fn test_ambiguous_label() {
+ for stmt in [
+ quote! {
+ return 'label: loop { break 'label 42; };
+ },
+ quote! {
+ break ('label: loop { break 'label 42; });
+ },
+ quote! {
+ break 1 + 'label: loop { break 'label 42; };
+ },
+ quote! {
+ break 'outer 'inner: loop { break 'inner 42; };
+ },
+ ] {
+ syn::parse2::<Stmt>(stmt).unwrap();
+ }
+
+ for stmt in [
+ // Parentheses required. See https://github.com/rust-lang/rust/pull/87026.
+ quote! {
+ break 'label: loop { break 'label 42; };
+ },
+ ] {
+ syn::parse2::<Stmt>(stmt).unwrap_err();
+ }
+}
+
+#[test]
+fn test_extended_interpolated_path() {
+ let path = Group::new(Delimiter::None, quote!(a::b));
+
+ let tokens = quote!(if #path {});
+ snapshot!(tokens as Expr, @r###"
+ Expr::If {
+ cond: Expr::Group {
+ expr: Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "a",
+ },
+ Token![::],
+ PathSegment {
+ ident: "b",
+ },
+ ],
+ },
+ },
+ },
+ then_branch: Block {
+ stmts: [],
+ },
+ }
+ "###);
+
+ let tokens = quote!(#path {});
+ snapshot!(tokens as Expr, @r###"
+ Expr::Struct {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "a",
+ },
+ Token![::],
+ PathSegment {
+ ident: "b",
+ },
+ ],
+ },
+ }
+ "###);
+
+ let tokens = quote!(#path :: c);
+ snapshot!(tokens as Expr, @r###"
+ Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "a",
+ },
+ Token![::],
+ PathSegment {
+ ident: "b",
+ },
+ Token![::],
+ PathSegment {
+ ident: "c",
+ },
+ ],
+ },
+ }
+ "###);
+
+ let nested = Group::new(Delimiter::None, quote!(a::b || true));
+ let tokens = quote!(if #nested && false {});
+ snapshot!(tokens as Expr, @r###"
+ Expr::If {
+ cond: Expr::Binary {
+ left: Expr::Group {
+ expr: Expr::Binary {
+ left: Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "a",
+ },
+ Token![::],
+ PathSegment {
+ ident: "b",
+ },
+ ],
+ },
+ },
+ op: BinOp::Or,
+ right: Expr::Lit {
+ lit: Lit::Bool {
+ value: true,
+ },
+ },
+ },
+ },
+ op: BinOp::And,
+ right: Expr::Lit {
+ lit: Lit::Bool {
+ value: false,
+ },
+ },
+ },
+ then_branch: Block {
+ stmts: [],
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_tuple_comma() {
+ let mut expr = ExprTuple {
+ attrs: Vec::new(),
+ paren_token: token::Paren::default(),
+ elems: Punctuated::new(),
+ };
+ snapshot!(expr.to_token_stream() as Expr, @"Expr::Tuple");
+
+ expr.elems.push_value(parse_quote!(continue));
+ // Must not parse to Expr::Paren
+ snapshot!(expr.to_token_stream() as Expr, @r###"
+ Expr::Tuple {
+ elems: [
+ Expr::Continue,
+ Token![,],
+ ],
+ }
+ "###);
+
+ expr.elems.push_punct(<Token![,]>::default());
+ snapshot!(expr.to_token_stream() as Expr, @r###"
+ Expr::Tuple {
+ elems: [
+ Expr::Continue,
+ Token![,],
+ ],
+ }
+ "###);
+
+ expr.elems.push_value(parse_quote!(continue));
+ snapshot!(expr.to_token_stream() as Expr, @r###"
+ Expr::Tuple {
+ elems: [
+ Expr::Continue,
+ Token![,],
+ Expr::Continue,
+ ],
+ }
+ "###);
+
+ expr.elems.push_punct(<Token![,]>::default());
+ snapshot!(expr.to_token_stream() as Expr, @r###"
+ Expr::Tuple {
+ elems: [
+ Expr::Continue,
+ Token![,],
+ Expr::Continue,
+ Token![,],
+ ],
+ }
+ "###);
+}
+
+#[test]
+fn test_binop_associativity() {
+ // Left to right.
+ snapshot!("() + () + ()" as Expr, @r###"
+ Expr::Binary {
+ left: Expr::Binary {
+ left: Expr::Tuple,
+ op: BinOp::Add,
+ right: Expr::Tuple,
+ },
+ op: BinOp::Add,
+ right: Expr::Tuple,
+ }
+ "###);
+
+ // Right to left.
+ snapshot!("() += () += ()" as Expr, @r###"
+ Expr::Binary {
+ left: Expr::Tuple,
+ op: BinOp::AddAssign,
+ right: Expr::Binary {
+ left: Expr::Tuple,
+ op: BinOp::AddAssign,
+ right: Expr::Tuple,
+ },
+ }
+ "###);
+
+ // Parenthesization is required.
+ syn::parse_str::<Expr>("() == () == ()").unwrap_err();
+}
+
+#[test]
+fn test_assign_range_precedence() {
+ // Range has higher precedence as the right-hand of an assignment, but
+ // ambiguous precedence as the left-hand of an assignment.
+ snapshot!("() = () .. ()" as Expr, @r###"
+ Expr::Assign {
+ left: Expr::Tuple,
+ right: Expr::Range {
+ start: Some(Expr::Tuple),
+ limits: RangeLimits::HalfOpen,
+ end: Some(Expr::Tuple),
+ },
+ }
+ "###);
+
+ snapshot!("() += () .. ()" as Expr, @r###"
+ Expr::Binary {
+ left: Expr::Tuple,
+ op: BinOp::AddAssign,
+ right: Expr::Range {
+ start: Some(Expr::Tuple),
+ limits: RangeLimits::HalfOpen,
+ end: Some(Expr::Tuple),
+ },
+ }
+ "###);
+
+ syn::parse_str::<Expr>("() .. () = ()").unwrap_err();
+ syn::parse_str::<Expr>("() .. () += ()").unwrap_err();
+}
+
+#[test]
+fn test_fixup() {
+ 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);
+ }
+ }
+
+ for tokens in [
+ quote! { 2 * (1 + 1) },
+ quote! { 0 + (0 + 0) },
+ quote! { (a = b) = c },
+ quote! { (x as i32) < 0 },
+ quote! { (1 + x as i32) < 0 },
+ quote! { (1 + 1).abs() },
+ quote! { (lo..hi)[..] },
+ quote! { (a..b)..(c..d) },
+ quote! { (&mut fut).await },
+ quote! { &mut (x as i32) },
+ quote! { -(x as i32) },
+ quote! { if (S {} == 1) {} },
+ quote! { { (m! {}) - 1 } },
+ quote! { match m { _ => ({}) - 1 } },
+ quote! { if let _ = (a && b) && c {} },
+ quote! { if let _ = (S {}) {} },
+ ] {
+ let original: Expr = syn::parse2(tokens).unwrap();
+
+ let mut flat = original.clone();
+ FlattenParens.visit_expr_mut(&mut flat);
+ let reconstructed: Expr = match syn::parse2(flat.to_token_stream()) {
+ Ok(reconstructed) => reconstructed,
+ Err(err) => panic!("failed to parse `{}`: {}", flat.to_token_stream(), err),
+ };
+
+ assert!(
+ original == reconstructed,
+ "original: {}\nreconstructed: {}",
+ original.to_token_stream(),
+ reconstructed.to_token_stream(),
+ );
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_generics.rs b/rust/hw/char/pl011/vendor/syn/tests/test_generics.rs
new file mode 100644
index 0000000000..3faf0dba59
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_generics.rs
@@ -0,0 +1,282 @@
+#![allow(
+ clippy::manual_let_else,
+ clippy::too_many_lines,
+ clippy::uninlined_format_args
+)]
+
+#[macro_use]
+mod macros;
+
+use quote::quote;
+use syn::{DeriveInput, ItemFn, TypeParamBound, WhereClause, WherePredicate};
+
+#[test]
+fn test_split_for_impl() {
+ let input = quote! {
+ struct S<'a, 'b: 'a, #[may_dangle] T: 'a = ()> where T: Debug;
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Inherited,
+ ident: "S",
+ generics: Generics {
+ lt_token: Some,
+ params: [
+ GenericParam::Lifetime(LifetimeParam {
+ lifetime: Lifetime {
+ ident: "a",
+ },
+ }),
+ Token![,],
+ GenericParam::Lifetime(LifetimeParam {
+ lifetime: Lifetime {
+ ident: "b",
+ },
+ colon_token: Some,
+ bounds: [
+ Lifetime {
+ ident: "a",
+ },
+ ],
+ }),
+ Token![,],
+ GenericParam::Type(TypeParam {
+ attrs: [
+ Attribute {
+ style: AttrStyle::Outer,
+ meta: Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "may_dangle",
+ },
+ ],
+ },
+ },
+ ],
+ ident: "T",
+ colon_token: Some,
+ bounds: [
+ TypeParamBound::Lifetime {
+ ident: "a",
+ },
+ ],
+ eq_token: Some,
+ default: Some(Type::Tuple),
+ }),
+ ],
+ gt_token: Some,
+ where_clause: Some(WhereClause {
+ predicates: [
+ WherePredicate::Type(PredicateType {
+ bounded_ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "T",
+ },
+ ],
+ },
+ },
+ bounds: [
+ TypeParamBound::Trait(TraitBound {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Debug",
+ },
+ ],
+ },
+ }),
+ ],
+ }),
+ ],
+ }),
+ },
+ data: Data::Struct {
+ fields: Fields::Unit,
+ semi_token: Some,
+ },
+ }
+ "###);
+
+ let generics = input.generics;
+ let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+
+ let generated = quote! {
+ impl #impl_generics MyTrait for Test #ty_generics #where_clause {}
+ };
+ let expected = quote! {
+ impl<'a, 'b: 'a, #[may_dangle] T: 'a> MyTrait
+ for Test<'a, 'b, T>
+ where
+ T: Debug
+ {}
+ };
+ assert_eq!(generated.to_string(), expected.to_string());
+
+ let turbofish = ty_generics.as_turbofish();
+ let generated = quote! {
+ Test #turbofish
+ };
+ let expected = quote! {
+ Test::<'a, 'b, T>
+ };
+ assert_eq!(generated.to_string(), expected.to_string());
+}
+
+#[test]
+fn test_ty_param_bound() {
+ let tokens = quote!('a);
+ snapshot!(tokens as TypeParamBound, @r###"
+ TypeParamBound::Lifetime {
+ ident: "a",
+ }
+ "###);
+
+ let tokens = quote!('_);
+ snapshot!(tokens as TypeParamBound, @r###"
+ TypeParamBound::Lifetime {
+ ident: "_",
+ }
+ "###);
+
+ let tokens = quote!(Debug);
+ snapshot!(tokens as TypeParamBound, @r###"
+ TypeParamBound::Trait(TraitBound {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Debug",
+ },
+ ],
+ },
+ })
+ "###);
+
+ let tokens = quote!(?Sized);
+ snapshot!(tokens as TypeParamBound, @r###"
+ TypeParamBound::Trait(TraitBound {
+ modifier: TraitBoundModifier::Maybe,
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Sized",
+ },
+ ],
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_fn_precedence_in_where_clause() {
+ // This should parse as two separate bounds, `FnOnce() -> i32` and `Send` - not
+ // `FnOnce() -> (i32 + Send)`.
+ let input = quote! {
+ fn f<G>()
+ where
+ G: FnOnce() -> i32 + Send,
+ {
+ }
+ };
+
+ snapshot!(input as ItemFn, @r###"
+ ItemFn {
+ vis: Visibility::Inherited,
+ sig: Signature {
+ ident: "f",
+ generics: Generics {
+ lt_token: Some,
+ params: [
+ GenericParam::Type(TypeParam {
+ ident: "G",
+ }),
+ ],
+ gt_token: Some,
+ where_clause: Some(WhereClause {
+ predicates: [
+ WherePredicate::Type(PredicateType {
+ bounded_ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "G",
+ },
+ ],
+ },
+ },
+ bounds: [
+ TypeParamBound::Trait(TraitBound {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "FnOnce",
+ arguments: PathArguments::Parenthesized {
+ output: ReturnType::Type(
+ Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "i32",
+ },
+ ],
+ },
+ },
+ ),
+ },
+ },
+ ],
+ },
+ }),
+ Token![+],
+ TypeParamBound::Trait(TraitBound {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Send",
+ },
+ ],
+ },
+ }),
+ ],
+ }),
+ Token![,],
+ ],
+ }),
+ },
+ output: ReturnType::Default,
+ },
+ block: Block {
+ stmts: [],
+ },
+ }
+ "###);
+
+ let where_clause = input.sig.generics.where_clause.as_ref().unwrap();
+ assert_eq!(where_clause.predicates.len(), 1);
+
+ let predicate = match &where_clause.predicates[0] {
+ WherePredicate::Type(pred) => pred,
+ _ => panic!("wrong predicate kind"),
+ };
+
+ assert_eq!(predicate.bounds.len(), 2, "{:#?}", predicate.bounds);
+
+ let first_bound = &predicate.bounds[0];
+ assert_eq!(quote!(#first_bound).to_string(), "FnOnce () -> i32");
+
+ let second_bound = &predicate.bounds[1];
+ assert_eq!(quote!(#second_bound).to_string(), "Send");
+}
+
+#[test]
+fn test_where_clause_at_end_of_input() {
+ let input = quote! {
+ where
+ };
+
+ snapshot!(input as WhereClause, @"WhereClause");
+
+ assert_eq!(input.predicates.len(), 0);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_grouping.rs b/rust/hw/char/pl011/vendor/syn/tests/test_grouping.rs
new file mode 100644
index 0000000000..326909feb5
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_grouping.rs
@@ -0,0 +1,53 @@
+#![allow(clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+use proc_macro2::{Delimiter, Group, Literal, Punct, Spacing, TokenStream, TokenTree};
+use syn::Expr;
+
+#[test]
+fn test_grouping() {
+ let tokens: TokenStream = TokenStream::from_iter([
+ TokenTree::Literal(Literal::i32_suffixed(1)),
+ TokenTree::Punct(Punct::new('+', Spacing::Alone)),
+ TokenTree::Group(Group::new(
+ Delimiter::None,
+ TokenStream::from_iter([
+ TokenTree::Literal(Literal::i32_suffixed(2)),
+ TokenTree::Punct(Punct::new('+', Spacing::Alone)),
+ TokenTree::Literal(Literal::i32_suffixed(3)),
+ ]),
+ )),
+ TokenTree::Punct(Punct::new('*', Spacing::Alone)),
+ TokenTree::Literal(Literal::i32_suffixed(4)),
+ ]);
+
+ assert_eq!(tokens.to_string(), "1i32 + 2i32 + 3i32 * 4i32");
+
+ snapshot!(tokens as Expr, @r###"
+ Expr::Binary {
+ left: Expr::Lit {
+ lit: 1i32,
+ },
+ op: BinOp::Add,
+ right: Expr::Binary {
+ left: Expr::Group {
+ expr: Expr::Binary {
+ left: Expr::Lit {
+ lit: 2i32,
+ },
+ op: BinOp::Add,
+ right: Expr::Lit {
+ lit: 3i32,
+ },
+ },
+ },
+ op: BinOp::Mul,
+ right: Expr::Lit {
+ lit: 4i32,
+ },
+ },
+ }
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_ident.rs b/rust/hw/char/pl011/vendor/syn/tests/test_ident.rs
new file mode 100644
index 0000000000..10df0ad56c
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_ident.rs
@@ -0,0 +1,87 @@
+use proc_macro2::{Ident, Span, TokenStream};
+use std::str::FromStr;
+use syn::Result;
+
+#[track_caller]
+fn parse(s: &str) -> Result<Ident> {
+ syn::parse2(TokenStream::from_str(s).unwrap())
+}
+
+#[track_caller]
+fn new(s: &str) -> Ident {
+ Ident::new(s, Span::call_site())
+}
+
+#[test]
+fn ident_parse() {
+ parse("String").unwrap();
+}
+
+#[test]
+fn ident_parse_keyword() {
+ parse("abstract").unwrap_err();
+}
+
+#[test]
+fn ident_parse_empty() {
+ parse("").unwrap_err();
+}
+
+#[test]
+fn ident_parse_lifetime() {
+ parse("'static").unwrap_err();
+}
+
+#[test]
+fn ident_parse_underscore() {
+ parse("_").unwrap_err();
+}
+
+#[test]
+fn ident_parse_number() {
+ parse("255").unwrap_err();
+}
+
+#[test]
+fn ident_parse_invalid() {
+ parse("a#").unwrap_err();
+}
+
+#[test]
+fn ident_new() {
+ new("String");
+}
+
+#[test]
+fn ident_new_keyword() {
+ new("abstract");
+}
+
+#[test]
+#[should_panic(expected = "use Option<Ident>")]
+fn ident_new_empty() {
+ new("");
+}
+
+#[test]
+#[should_panic(expected = "not a valid Ident")]
+fn ident_new_lifetime() {
+ new("'static");
+}
+
+#[test]
+fn ident_new_underscore() {
+ new("_");
+}
+
+#[test]
+#[should_panic(expected = "use Literal instead")]
+fn ident_new_number() {
+ new("255");
+}
+
+#[test]
+#[should_panic(expected = "\"a#\" is not a valid Ident")]
+fn ident_new_invalid() {
+ new("a#");
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_item.rs b/rust/hw/char/pl011/vendor/syn/tests/test_item.rs
new file mode 100644
index 0000000000..5c088bbe60
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_item.rs
@@ -0,0 +1,332 @@
+#![allow(clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
+use quote::quote;
+use syn::{Item, ItemTrait};
+
+#[test]
+fn test_macro_variable_attr() {
+ // mimics the token stream corresponding to `$attr fn f() {}`
+ let tokens = TokenStream::from_iter([
+ TokenTree::Group(Group::new(Delimiter::None, quote! { #[test] })),
+ TokenTree::Ident(Ident::new("fn", Span::call_site())),
+ TokenTree::Ident(Ident::new("f", Span::call_site())),
+ TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),
+ TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
+ ]);
+
+ snapshot!(tokens as Item, @r###"
+ Item::Fn {
+ attrs: [
+ Attribute {
+ style: AttrStyle::Outer,
+ meta: Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "test",
+ },
+ ],
+ },
+ },
+ ],
+ vis: Visibility::Inherited,
+ sig: Signature {
+ ident: "f",
+ generics: Generics,
+ output: ReturnType::Default,
+ },
+ block: Block {
+ stmts: [],
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_negative_impl() {
+ // Rustc parses all of the following.
+
+ #[cfg(any())]
+ impl ! {}
+ let tokens = quote! {
+ impl ! {}
+ };
+ snapshot!(tokens as Item, @r###"
+ Item::Impl {
+ generics: Generics,
+ self_ty: Type::Never,
+ }
+ "###);
+
+ #[cfg(any())]
+ #[rustfmt::skip]
+ impl !Trait {}
+ let tokens = quote! {
+ impl !Trait {}
+ };
+ snapshot!(tokens as Item, @r###"
+ Item::Impl {
+ generics: Generics,
+ self_ty: Type::Verbatim(`! Trait`),
+ }
+ "###);
+
+ #[cfg(any())]
+ impl !Trait for T {}
+ let tokens = quote! {
+ impl !Trait for T {}
+ };
+ snapshot!(tokens as Item, @r###"
+ Item::Impl {
+ generics: Generics,
+ trait_: Some((
+ Some,
+ Path {
+ segments: [
+ PathSegment {
+ ident: "Trait",
+ },
+ ],
+ },
+ )),
+ self_ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "T",
+ },
+ ],
+ },
+ },
+ }
+ "###);
+
+ #[cfg(any())]
+ #[rustfmt::skip]
+ impl !! {}
+ let tokens = quote! {
+ impl !! {}
+ };
+ snapshot!(tokens as Item, @r###"
+ Item::Impl {
+ generics: Generics,
+ self_ty: Type::Verbatim(`! !`),
+ }
+ "###);
+}
+
+#[test]
+fn test_macro_variable_impl() {
+ // mimics the token stream corresponding to `impl $trait for $ty {}`
+ let tokens = TokenStream::from_iter([
+ TokenTree::Ident(Ident::new("impl", Span::call_site())),
+ TokenTree::Group(Group::new(Delimiter::None, quote!(Trait))),
+ TokenTree::Ident(Ident::new("for", Span::call_site())),
+ TokenTree::Group(Group::new(Delimiter::None, quote!(Type))),
+ TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
+ ]);
+
+ snapshot!(tokens as Item, @r###"
+ Item::Impl {
+ generics: Generics,
+ trait_: Some((
+ None,
+ Path {
+ segments: [
+ PathSegment {
+ ident: "Trait",
+ },
+ ],
+ },
+ )),
+ self_ty: Type::Group {
+ elem: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Type",
+ },
+ ],
+ },
+ },
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_supertraits() {
+ // Rustc parses all of the following.
+
+ #[rustfmt::skip]
+ let tokens = quote!(trait Trait where {});
+ snapshot!(tokens as ItemTrait, @r###"
+ ItemTrait {
+ vis: Visibility::Inherited,
+ ident: "Trait",
+ generics: Generics {
+ where_clause: Some(WhereClause),
+ },
+ }
+ "###);
+
+ #[rustfmt::skip]
+ let tokens = quote!(trait Trait: where {});
+ snapshot!(tokens as ItemTrait, @r###"
+ ItemTrait {
+ vis: Visibility::Inherited,
+ ident: "Trait",
+ generics: Generics {
+ where_clause: Some(WhereClause),
+ },
+ colon_token: Some,
+ }
+ "###);
+
+ #[rustfmt::skip]
+ let tokens = quote!(trait Trait: Sized where {});
+ snapshot!(tokens as ItemTrait, @r###"
+ ItemTrait {
+ vis: Visibility::Inherited,
+ ident: "Trait",
+ generics: Generics {
+ where_clause: Some(WhereClause),
+ },
+ colon_token: Some,
+ supertraits: [
+ TypeParamBound::Trait(TraitBound {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Sized",
+ },
+ ],
+ },
+ }),
+ ],
+ }
+ "###);
+
+ #[rustfmt::skip]
+ let tokens = quote!(trait Trait: Sized + where {});
+ snapshot!(tokens as ItemTrait, @r###"
+ ItemTrait {
+ vis: Visibility::Inherited,
+ ident: "Trait",
+ generics: Generics {
+ where_clause: Some(WhereClause),
+ },
+ colon_token: Some,
+ supertraits: [
+ TypeParamBound::Trait(TraitBound {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Sized",
+ },
+ ],
+ },
+ }),
+ Token![+],
+ ],
+ }
+ "###);
+}
+
+#[test]
+fn test_type_empty_bounds() {
+ #[rustfmt::skip]
+ let tokens = quote! {
+ trait Foo {
+ type Bar: ;
+ }
+ };
+
+ snapshot!(tokens as ItemTrait, @r###"
+ ItemTrait {
+ vis: Visibility::Inherited,
+ ident: "Foo",
+ generics: Generics,
+ items: [
+ TraitItem::Type {
+ ident: "Bar",
+ generics: Generics,
+ colon_token: Some,
+ },
+ ],
+ }
+ "###);
+}
+
+#[test]
+fn test_impl_visibility() {
+ let tokens = quote! {
+ pub default unsafe impl union {}
+ };
+
+ snapshot!(tokens as Item, @"Item::Verbatim(`pub default unsafe impl union { }`)");
+}
+
+#[test]
+fn test_impl_type_parameter_defaults() {
+ #[cfg(any())]
+ impl<T = ()> () {}
+ let tokens = quote! {
+ impl<T = ()> () {}
+ };
+ snapshot!(tokens as Item, @r###"
+ Item::Impl {
+ generics: Generics {
+ lt_token: Some,
+ params: [
+ GenericParam::Type(TypeParam {
+ ident: "T",
+ eq_token: Some,
+ default: Some(Type::Tuple),
+ }),
+ ],
+ gt_token: Some,
+ },
+ self_ty: Type::Tuple,
+ }
+ "###);
+}
+
+#[test]
+fn test_impl_trait_trailing_plus() {
+ let tokens = quote! {
+ fn f() -> impl Sized + {}
+ };
+
+ snapshot!(tokens as Item, @r###"
+ Item::Fn {
+ vis: Visibility::Inherited,
+ sig: Signature {
+ ident: "f",
+ generics: Generics,
+ output: ReturnType::Type(
+ Type::ImplTrait {
+ bounds: [
+ TypeParamBound::Trait(TraitBound {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Sized",
+ },
+ ],
+ },
+ }),
+ Token![+],
+ ],
+ },
+ ),
+ },
+ block: Block {
+ stmts: [],
+ },
+ }
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_iterators.rs b/rust/hw/char/pl011/vendor/syn/tests/test_iterators.rs
new file mode 100644
index 0000000000..5f0eff59e6
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_iterators.rs
@@ -0,0 +1,70 @@
+#![allow(clippy::uninlined_format_args)]
+
+use syn::punctuated::{Pair, Punctuated};
+use syn::Token;
+
+#[macro_use]
+mod macros;
+
+macro_rules! check_exact_size_iterator {
+ ($iter:expr) => {{
+ let iter = $iter;
+ let size_hint = iter.size_hint();
+ let len = iter.len();
+ let count = iter.count();
+ assert_eq!(len, count);
+ assert_eq!(size_hint, (count, Some(count)));
+ }};
+}
+
+#[test]
+fn pairs() {
+ let mut p: Punctuated<_, Token![,]> = punctuated!(2, 3, 4);
+
+ check_exact_size_iterator!(p.pairs());
+ check_exact_size_iterator!(p.pairs_mut());
+ check_exact_size_iterator!(p.into_pairs());
+
+ let mut p: Punctuated<_, Token![,]> = punctuated!(2, 3, 4);
+
+ assert_eq!(p.pairs().next_back().map(Pair::into_value), Some(&4));
+ assert_eq!(
+ p.pairs_mut().next_back().map(Pair::into_value),
+ Some(&mut 4)
+ );
+ assert_eq!(p.into_pairs().next_back().map(Pair::into_value), Some(4));
+}
+
+#[test]
+fn iter() {
+ let mut p: Punctuated<_, Token![,]> = punctuated!(2, 3, 4);
+
+ check_exact_size_iterator!(p.iter());
+ check_exact_size_iterator!(p.iter_mut());
+ check_exact_size_iterator!(p.into_iter());
+
+ let mut p: Punctuated<_, Token![,]> = punctuated!(2, 3, 4);
+
+ assert_eq!(p.iter().next_back(), Some(&4));
+ assert_eq!(p.iter_mut().next_back(), Some(&mut 4));
+ assert_eq!(p.into_iter().next_back(), Some(4));
+}
+
+#[test]
+fn may_dangle() {
+ let p: Punctuated<_, Token![,]> = punctuated!(2, 3, 4);
+ for element in &p {
+ if *element == 2 {
+ drop(p);
+ break;
+ }
+ }
+
+ let mut p: Punctuated<_, Token![,]> = punctuated!(2, 3, 4);
+ for element in &mut p {
+ if *element == 2 {
+ drop(p);
+ break;
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_lit.rs b/rust/hw/char/pl011/vendor/syn/tests/test_lit.rs
new file mode 100644
index 0000000000..0d5ecdcef5
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_lit.rs
@@ -0,0 +1,331 @@
+#![allow(
+ clippy::float_cmp,
+ clippy::needless_raw_string_hashes,
+ clippy::non_ascii_literal,
+ clippy::single_match_else,
+ clippy::uninlined_format_args
+)]
+
+#[macro_use]
+mod macros;
+
+use proc_macro2::{Delimiter, Group, Literal, Span, TokenStream, TokenTree};
+use quote::ToTokens;
+use std::ffi::CStr;
+use std::str::FromStr;
+use syn::{Lit, LitFloat, LitInt, LitStr};
+
+#[track_caller]
+fn lit(s: &str) -> Lit {
+ let mut tokens = TokenStream::from_str(s).unwrap().into_iter();
+ match tokens.next().unwrap() {
+ TokenTree::Literal(lit) => {
+ assert!(tokens.next().is_none());
+ Lit::new(lit)
+ }
+ wrong => panic!("{:?}", wrong),
+ }
+}
+
+#[test]
+fn strings() {
+ #[track_caller]
+ fn test_string(s: &str, value: &str) {
+ let s = s.trim();
+ match lit(s) {
+ Lit::Str(lit) => {
+ assert_eq!(lit.value(), value);
+ let again = lit.into_token_stream().to_string();
+ if again != s {
+ test_string(&again, value);
+ }
+ }
+ wrong => panic!("{:?}", wrong),
+ }
+ }
+
+ test_string(r#" "" "#, "");
+ test_string(r#" "a" "#, "a");
+ test_string(r#" "\n" "#, "\n");
+ test_string(r#" "\r" "#, "\r");
+ test_string(r#" "\t" "#, "\t");
+ test_string(r#" "🐕" "#, "🐕"); // NOTE: This is an emoji
+ test_string(r#" "\"" "#, "\"");
+ test_string(r#" "'" "#, "'");
+ test_string(r#" "\u{1F415}" "#, "\u{1F415}");
+ test_string(r#" "\u{1_2__3_}" "#, "\u{123}");
+ test_string(
+ "\"contains\nnewlines\\\nescaped newlines\"",
+ "contains\nnewlinesescaped newlines",
+ );
+ test_string(
+ "\"escaped newline\\\n \x0C unsupported whitespace\"",
+ "escaped newline\x0C unsupported whitespace",
+ );
+ test_string("r\"raw\nstring\\\nhere\"", "raw\nstring\\\nhere");
+ test_string("\"...\"q", "...");
+ test_string("r\"...\"q", "...");
+ test_string("r##\"...\"##q", "...");
+}
+
+#[test]
+fn byte_strings() {
+ #[track_caller]
+ fn test_byte_string(s: &str, value: &[u8]) {
+ let s = s.trim();
+ match lit(s) {
+ Lit::ByteStr(lit) => {
+ assert_eq!(lit.value(), value);
+ let again = lit.into_token_stream().to_string();
+ if again != s {
+ test_byte_string(&again, value);
+ }
+ }
+ wrong => panic!("{:?}", wrong),
+ }
+ }
+
+ test_byte_string(r#" b"" "#, b"");
+ test_byte_string(r#" b"a" "#, b"a");
+ test_byte_string(r#" b"\n" "#, b"\n");
+ test_byte_string(r#" b"\r" "#, b"\r");
+ test_byte_string(r#" b"\t" "#, b"\t");
+ test_byte_string(r#" b"\"" "#, b"\"");
+ test_byte_string(r#" b"'" "#, b"'");
+ test_byte_string(
+ "b\"contains\nnewlines\\\nescaped newlines\"",
+ b"contains\nnewlinesescaped newlines",
+ );
+ test_byte_string("br\"raw\nstring\\\nhere\"", b"raw\nstring\\\nhere");
+ test_byte_string("b\"...\"q", b"...");
+ test_byte_string("br\"...\"q", b"...");
+ test_byte_string("br##\"...\"##q", b"...");
+}
+
+#[test]
+fn c_strings() {
+ #[track_caller]
+ fn test_c_string(s: &str, value: &CStr) {
+ let s = s.trim();
+ match lit(s) {
+ Lit::CStr(lit) => {
+ assert_eq!(*lit.value(), *value);
+ let again = lit.into_token_stream().to_string();
+ if again != s {
+ test_c_string(&again, value);
+ }
+ }
+ wrong => panic!("{:?}", wrong),
+ }
+ }
+
+ test_c_string(r#" c"" "#, c"");
+ test_c_string(r#" c"a" "#, c"a");
+ test_c_string(r#" c"\n" "#, c"\n");
+ test_c_string(r#" c"\r" "#, c"\r");
+ test_c_string(r#" c"\t" "#, c"\t");
+ test_c_string(r#" c"\\" "#, c"\\");
+ test_c_string(r#" c"\'" "#, c"'");
+ test_c_string(r#" c"\"" "#, c"\"");
+ test_c_string(
+ "c\"contains\nnewlines\\\nescaped newlines\"",
+ c"contains\nnewlinesescaped newlines",
+ );
+ test_c_string("cr\"raw\nstring\\\nhere\"", c"raw\nstring\\\nhere");
+ test_c_string("c\"...\"q", c"...");
+ test_c_string("cr\"...\"", c"...");
+ test_c_string("cr##\"...\"##", c"...");
+ test_c_string(
+ r#" c"hello\x80我叫\u{1F980}" "#, // from the RFC
+ c"hello\x80我叫\u{1F980}",
+ );
+}
+
+#[test]
+fn bytes() {
+ #[track_caller]
+ fn test_byte(s: &str, value: u8) {
+ let s = s.trim();
+ match lit(s) {
+ Lit::Byte(lit) => {
+ assert_eq!(lit.value(), value);
+ let again = lit.into_token_stream().to_string();
+ assert_eq!(again, s);
+ }
+ wrong => panic!("{:?}", wrong),
+ }
+ }
+
+ test_byte(r#" b'a' "#, b'a');
+ test_byte(r#" b'\n' "#, b'\n');
+ test_byte(r#" b'\r' "#, b'\r');
+ test_byte(r#" b'\t' "#, b'\t');
+ test_byte(r#" b'\'' "#, b'\'');
+ test_byte(r#" b'"' "#, b'"');
+ test_byte(r#" b'a'q "#, b'a');
+}
+
+#[test]
+fn chars() {
+ #[track_caller]
+ fn test_char(s: &str, value: char) {
+ let s = s.trim();
+ match lit(s) {
+ Lit::Char(lit) => {
+ assert_eq!(lit.value(), value);
+ let again = lit.into_token_stream().to_string();
+ if again != s {
+ test_char(&again, value);
+ }
+ }
+ wrong => panic!("{:?}", wrong),
+ }
+ }
+
+ test_char(r#" 'a' "#, 'a');
+ test_char(r#" '\n' "#, '\n');
+ test_char(r#" '\r' "#, '\r');
+ test_char(r#" '\t' "#, '\t');
+ test_char(r#" '🐕' "#, '🐕'); // NOTE: This is an emoji
+ test_char(r#" '\'' "#, '\'');
+ test_char(r#" '"' "#, '"');
+ test_char(r#" '\u{1F415}' "#, '\u{1F415}');
+ test_char(r#" 'a'q "#, 'a');
+}
+
+#[test]
+fn ints() {
+ #[track_caller]
+ fn test_int(s: &str, value: u64, suffix: &str) {
+ match lit(s) {
+ Lit::Int(lit) => {
+ assert_eq!(lit.base10_digits().parse::<u64>().unwrap(), value);
+ assert_eq!(lit.suffix(), suffix);
+ let again = lit.into_token_stream().to_string();
+ if again != s {
+ test_int(&again, value, suffix);
+ }
+ }
+ wrong => panic!("{:?}", wrong),
+ }
+ }
+
+ test_int("5", 5, "");
+ test_int("5u32", 5, "u32");
+ test_int("0E", 0, "E");
+ test_int("0ECMA", 0, "ECMA");
+ test_int("0o0A", 0, "A");
+ test_int("5_0", 50, "");
+ test_int("5_____0_____", 50, "");
+ test_int("0x7f", 127, "");
+ test_int("0x7F", 127, "");
+ test_int("0b1001", 9, "");
+ test_int("0o73", 59, "");
+ test_int("0x7Fu8", 127, "u8");
+ test_int("0b1001i8", 9, "i8");
+ test_int("0o73u32", 59, "u32");
+ test_int("0x__7___f_", 127, "");
+ test_int("0x__7___F_", 127, "");
+ test_int("0b_1_0__01", 9, "");
+ test_int("0o_7__3", 59, "");
+ test_int("0x_7F__u8", 127, "u8");
+ test_int("0b__10__0_1i8", 9, "i8");
+ test_int("0o__7__________________3u32", 59, "u32");
+ test_int("0e1\u{5c5}", 0, "e1\u{5c5}");
+}
+
+#[test]
+fn floats() {
+ #[track_caller]
+ fn test_float(s: &str, value: f64, suffix: &str) {
+ match lit(s) {
+ Lit::Float(lit) => {
+ assert_eq!(lit.base10_digits().parse::<f64>().unwrap(), value);
+ assert_eq!(lit.suffix(), suffix);
+ let again = lit.into_token_stream().to_string();
+ if again != s {
+ test_float(&again, value, suffix);
+ }
+ }
+ wrong => panic!("{:?}", wrong),
+ }
+ }
+
+ test_float("5.5", 5.5, "");
+ test_float("5.5E12", 5.5e12, "");
+ test_float("5.5e12", 5.5e12, "");
+ test_float("1.0__3e-12", 1.03e-12, "");
+ test_float("1.03e+12", 1.03e12, "");
+ test_float("9e99e99", 9e99, "e99");
+ test_float("1e_0", 1.0, "");
+ test_float("0.0ECMA", 0.0, "ECMA");
+}
+
+#[test]
+fn negative() {
+ let span = Span::call_site();
+ assert_eq!("-1", LitInt::new("-1", span).to_string());
+ assert_eq!("-1i8", LitInt::new("-1i8", span).to_string());
+ assert_eq!("-1i16", LitInt::new("-1i16", span).to_string());
+ assert_eq!("-1i32", LitInt::new("-1i32", span).to_string());
+ assert_eq!("-1i64", LitInt::new("-1i64", span).to_string());
+ assert_eq!("-1.5", LitFloat::new("-1.5", span).to_string());
+ assert_eq!("-1.5f32", LitFloat::new("-1.5f32", span).to_string());
+ assert_eq!("-1.5f64", LitFloat::new("-1.5f64", span).to_string());
+}
+
+#[test]
+fn suffix() {
+ #[track_caller]
+ fn get_suffix(token: &str) -> String {
+ let lit = syn::parse_str::<Lit>(token).unwrap();
+ match lit {
+ Lit::Str(lit) => lit.suffix().to_owned(),
+ Lit::ByteStr(lit) => lit.suffix().to_owned(),
+ Lit::CStr(lit) => lit.suffix().to_owned(),
+ Lit::Byte(lit) => lit.suffix().to_owned(),
+ Lit::Char(lit) => lit.suffix().to_owned(),
+ Lit::Int(lit) => lit.suffix().to_owned(),
+ Lit::Float(lit) => lit.suffix().to_owned(),
+ _ => unimplemented!(),
+ }
+ }
+
+ assert_eq!(get_suffix("\"\"s"), "s");
+ assert_eq!(get_suffix("r\"\"r"), "r");
+ assert_eq!(get_suffix("r#\"\"#r"), "r");
+ assert_eq!(get_suffix("b\"\"b"), "b");
+ assert_eq!(get_suffix("br\"\"br"), "br");
+ assert_eq!(get_suffix("br#\"\"#br"), "br");
+ assert_eq!(get_suffix("c\"\"c"), "c");
+ assert_eq!(get_suffix("cr\"\"cr"), "cr");
+ assert_eq!(get_suffix("cr#\"\"#cr"), "cr");
+ assert_eq!(get_suffix("'c'c"), "c");
+ assert_eq!(get_suffix("b'b'b"), "b");
+ assert_eq!(get_suffix("1i32"), "i32");
+ assert_eq!(get_suffix("1_i32"), "i32");
+ assert_eq!(get_suffix("1.0f32"), "f32");
+ assert_eq!(get_suffix("1.0_f32"), "f32");
+}
+
+#[test]
+fn test_deep_group_empty() {
+ let tokens = TokenStream::from_iter([TokenTree::Group(Group::new(
+ Delimiter::None,
+ TokenStream::from_iter([TokenTree::Group(Group::new(
+ Delimiter::None,
+ TokenStream::from_iter([TokenTree::Literal(Literal::string("hi"))]),
+ ))]),
+ ))]);
+
+ snapshot!(tokens as Lit, @r#""hi""# );
+}
+
+#[test]
+fn test_error() {
+ let err = syn::parse_str::<LitStr>("...").unwrap_err();
+ assert_eq!("expected string literal", err.to_string());
+
+ let err = syn::parse_str::<LitStr>("5").unwrap_err();
+ assert_eq!("expected string literal", err.to_string());
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_meta.rs b/rust/hw/char/pl011/vendor/syn/tests/test_meta.rs
new file mode 100644
index 0000000000..ea6093115a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_meta.rs
@@ -0,0 +1,154 @@
+#![allow(
+ clippy::shadow_unrelated,
+ clippy::too_many_lines,
+ clippy::uninlined_format_args
+)]
+
+#[macro_use]
+mod macros;
+
+use syn::{Meta, MetaList, MetaNameValue};
+
+#[test]
+fn test_parse_meta_item_word() {
+ let input = "hello";
+
+ snapshot!(input as Meta, @r###"
+ Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "hello",
+ },
+ ],
+ }
+ "###);
+}
+
+#[test]
+fn test_parse_meta_name_value() {
+ let input = "foo = 5";
+ let (inner, meta) = (input, input);
+
+ snapshot!(inner as MetaNameValue, @r###"
+ MetaNameValue {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ value: Expr::Lit {
+ lit: 5,
+ },
+ }
+ "###);
+
+ snapshot!(meta as Meta, @r###"
+ Meta::NameValue {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ value: Expr::Lit {
+ lit: 5,
+ },
+ }
+ "###);
+
+ assert_eq!(meta, Meta::NameValue(inner));
+}
+
+#[test]
+fn test_parse_meta_item_list_lit() {
+ let input = "foo(5)";
+ let (inner, meta) = (input, input);
+
+ snapshot!(inner as MetaList, @r###"
+ MetaList {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`5`),
+ }
+ "###);
+
+ snapshot!(meta as Meta, @r###"
+ Meta::List {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`5`),
+ }
+ "###);
+
+ assert_eq!(meta, Meta::List(inner));
+}
+
+#[test]
+fn test_parse_meta_item_multiple() {
+ let input = "foo(word, name = 5, list(name2 = 6), word2)";
+ let (inner, meta) = (input, input);
+
+ snapshot!(inner as MetaList, @r###"
+ MetaList {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`word , name = 5 , list (name2 = 6) , word2`),
+ }
+ "###);
+
+ snapshot!(meta as Meta, @r###"
+ Meta::List {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "foo",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`word , name = 5 , list (name2 = 6) , word2`),
+ }
+ "###);
+
+ assert_eq!(meta, Meta::List(inner));
+}
+
+#[test]
+fn test_parse_path() {
+ let input = "::serde::Serialize";
+ snapshot!(input as Meta, @r###"
+ Meta::Path {
+ leading_colon: Some,
+ segments: [
+ PathSegment {
+ ident: "serde",
+ },
+ Token![::],
+ PathSegment {
+ ident: "Serialize",
+ },
+ ],
+ }
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_parse_buffer.rs b/rust/hw/char/pl011/vendor/syn/tests/test_parse_buffer.rs
new file mode 100644
index 0000000000..62abc6d282
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_parse_buffer.rs
@@ -0,0 +1,103 @@
+#![allow(clippy::non_ascii_literal)]
+
+use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, TokenStream, TokenTree};
+use std::panic;
+use syn::parse::discouraged::Speculative as _;
+use syn::parse::{Parse, ParseStream, Parser, Result};
+use syn::{parenthesized, Token};
+
+#[test]
+#[should_panic(expected = "fork was not derived from the advancing parse stream")]
+fn smuggled_speculative_cursor_between_sources() {
+ struct BreakRules;
+ impl Parse for BreakRules {
+ fn parse(input1: ParseStream) -> Result<Self> {
+ let nested = |input2: ParseStream| {
+ input1.advance_to(input2);
+ Ok(Self)
+ };
+ nested.parse_str("")
+ }
+ }
+
+ syn::parse_str::<BreakRules>("").unwrap();
+}
+
+#[test]
+#[should_panic(expected = "fork was not derived from the advancing parse stream")]
+fn smuggled_speculative_cursor_between_brackets() {
+ struct BreakRules;
+ impl Parse for BreakRules {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let a;
+ let b;
+ parenthesized!(a in input);
+ parenthesized!(b in input);
+ a.advance_to(&b);
+ Ok(Self)
+ }
+ }
+
+ syn::parse_str::<BreakRules>("()()").unwrap();
+}
+
+#[test]
+#[should_panic(expected = "fork was not derived from the advancing parse stream")]
+fn smuggled_speculative_cursor_into_brackets() {
+ struct BreakRules;
+ impl Parse for BreakRules {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let a;
+ parenthesized!(a in input);
+ input.advance_to(&a);
+ Ok(Self)
+ }
+ }
+
+ syn::parse_str::<BreakRules>("()").unwrap();
+}
+
+#[test]
+fn trailing_empty_none_group() {
+ fn parse(input: ParseStream) -> Result<()> {
+ input.parse::<Token![+]>()?;
+
+ let content;
+ parenthesized!(content in input);
+ content.parse::<Token![+]>()?;
+
+ Ok(())
+ }
+
+ // `+ ( + «∅ ∅» ) «∅ «∅ ∅» ∅»`
+ let tokens = TokenStream::from_iter([
+ TokenTree::Punct(Punct::new('+', Spacing::Alone)),
+ TokenTree::Group(Group::new(
+ Delimiter::Parenthesis,
+ TokenStream::from_iter([
+ TokenTree::Punct(Punct::new('+', Spacing::Alone)),
+ TokenTree::Group(Group::new(Delimiter::None, TokenStream::new())),
+ ]),
+ )),
+ TokenTree::Group(Group::new(Delimiter::None, TokenStream::new())),
+ TokenTree::Group(Group::new(
+ Delimiter::None,
+ TokenStream::from_iter([TokenTree::Group(Group::new(
+ Delimiter::None,
+ TokenStream::new(),
+ ))]),
+ )),
+ ]);
+
+ parse.parse2(tokens).unwrap();
+}
+
+#[test]
+fn test_unwind_safe() {
+ fn parse(input: ParseStream) -> Result<Ident> {
+ let thread_result = panic::catch_unwind(|| input.parse());
+ thread_result.unwrap()
+ }
+
+ parse.parse_str("throw").unwrap();
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_parse_quote.rs b/rust/hw/char/pl011/vendor/syn/tests/test_parse_quote.rs
new file mode 100644
index 0000000000..c0e753260a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_parse_quote.rs
@@ -0,0 +1,166 @@
+#![allow(clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+use syn::punctuated::Punctuated;
+use syn::{parse_quote, Attribute, Field, Lit, Pat, Stmt, Token};
+
+#[test]
+fn test_attribute() {
+ let attr: Attribute = parse_quote!(#[test]);
+ snapshot!(attr, @r###"
+ Attribute {
+ style: AttrStyle::Outer,
+ meta: Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "test",
+ },
+ ],
+ },
+ }
+ "###);
+
+ let attr: Attribute = parse_quote!(#![no_std]);
+ snapshot!(attr, @r###"
+ Attribute {
+ style: AttrStyle::Inner,
+ meta: Meta::Path {
+ segments: [
+ PathSegment {
+ ident: "no_std",
+ },
+ ],
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_field() {
+ let field: Field = parse_quote!(pub enabled: bool);
+ snapshot!(field, @r###"
+ Field {
+ vis: Visibility::Public,
+ ident: Some("enabled"),
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "bool",
+ },
+ ],
+ },
+ },
+ }
+ "###);
+
+ let field: Field = parse_quote!(primitive::bool);
+ snapshot!(field, @r###"
+ Field {
+ vis: Visibility::Inherited,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "primitive",
+ },
+ Token![::],
+ PathSegment {
+ ident: "bool",
+ },
+ ],
+ },
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_pat() {
+ let pat: Pat = parse_quote!(Some(false) | None);
+ snapshot!(&pat, @r###"
+ Pat::Or {
+ cases: [
+ Pat::TupleStruct {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Some",
+ },
+ ],
+ },
+ elems: [
+ Pat::Lit(ExprLit {
+ lit: Lit::Bool {
+ value: false,
+ },
+ }),
+ ],
+ },
+ Token![|],
+ Pat::Ident {
+ ident: "None",
+ },
+ ],
+ }
+ "###);
+
+ let boxed_pat: Box<Pat> = parse_quote!(Some(false) | None);
+ assert_eq!(*boxed_pat, pat);
+}
+
+#[test]
+fn test_punctuated() {
+ let punctuated: Punctuated<Lit, Token![|]> = parse_quote!(true | true);
+ snapshot!(punctuated, @r###"
+ [
+ Lit::Bool {
+ value: true,
+ },
+ Token![|],
+ Lit::Bool {
+ value: true,
+ },
+ ]
+ "###);
+
+ let punctuated: Punctuated<Lit, Token![|]> = parse_quote!(true | true |);
+ snapshot!(punctuated, @r###"
+ [
+ Lit::Bool {
+ value: true,
+ },
+ Token![|],
+ Lit::Bool {
+ value: true,
+ },
+ Token![|],
+ ]
+ "###);
+}
+
+#[test]
+fn test_vec_stmt() {
+ let stmts: Vec<Stmt> = parse_quote! {
+ let _;
+ true
+ };
+ snapshot!(stmts, @r###"
+ [
+ Stmt::Local {
+ pat: Pat::Wild,
+ },
+ Stmt::Expr(
+ Expr::Lit {
+ lit: Lit::Bool {
+ value: true,
+ },
+ },
+ None,
+ ),
+ ]
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_parse_stream.rs b/rust/hw/char/pl011/vendor/syn/tests/test_parse_stream.rs
new file mode 100644
index 0000000000..a650fc8534
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_parse_stream.rs
@@ -0,0 +1,187 @@
+#![allow(clippy::items_after_statements, clippy::let_underscore_untyped)]
+
+use proc_macro2::{Delimiter, Group, Punct, Spacing, Span, TokenStream, TokenTree};
+use quote::quote;
+use syn::ext::IdentExt as _;
+use syn::parse::discouraged::AnyDelimiter;
+use syn::parse::{ParseStream, Parser as _, Result};
+use syn::{parenthesized, token, Ident, Lifetime, Token};
+
+#[test]
+fn test_peek_punct() {
+ let tokens = quote!(+= + =);
+
+ fn assert(input: ParseStream) -> Result<()> {
+ assert!(input.peek(Token![+]));
+ assert!(input.peek(Token![+=]));
+
+ let _: Token![+] = input.parse()?;
+
+ assert!(input.peek(Token![=]));
+ assert!(!input.peek(Token![==]));
+ assert!(!input.peek(Token![+]));
+
+ let _: Token![=] = input.parse()?;
+
+ assert!(input.peek(Token![+]));
+ assert!(!input.peek(Token![+=]));
+
+ let _: Token![+] = input.parse()?;
+ let _: Token![=] = input.parse()?;
+ Ok(())
+ }
+
+ assert.parse2(tokens).unwrap();
+}
+
+#[test]
+fn test_peek_lifetime() {
+ // 'static ;
+ let tokens = TokenStream::from_iter([
+ TokenTree::Punct(Punct::new('\'', Spacing::Joint)),
+ TokenTree::Ident(Ident::new("static", Span::call_site())),
+ TokenTree::Punct(Punct::new(';', Spacing::Alone)),
+ ]);
+
+ fn assert(input: ParseStream) -> Result<()> {
+ assert!(input.peek(Lifetime));
+ assert!(input.peek2(Token![;]));
+ assert!(!input.peek2(Token![static]));
+
+ let _: Lifetime = input.parse()?;
+
+ assert!(input.peek(Token![;]));
+
+ let _: Token![;] = input.parse()?;
+ Ok(())
+ }
+
+ assert.parse2(tokens).unwrap();
+}
+
+#[test]
+fn test_peek_not_lifetime() {
+ // ' static
+ let tokens = TokenStream::from_iter([
+ TokenTree::Punct(Punct::new('\'', Spacing::Alone)),
+ TokenTree::Ident(Ident::new("static", Span::call_site())),
+ ]);
+
+ fn assert(input: ParseStream) -> Result<()> {
+ assert!(!input.peek(Lifetime));
+ assert!(input.parse::<Option<Punct>>()?.is_none());
+
+ let _: TokenTree = input.parse()?;
+
+ assert!(input.peek(Token![static]));
+
+ let _: Token![static] = input.parse()?;
+ Ok(())
+ }
+
+ assert.parse2(tokens).unwrap();
+}
+
+#[test]
+fn test_peek_ident() {
+ let tokens = quote!(static var);
+
+ fn assert(input: ParseStream) -> Result<()> {
+ assert!(!input.peek(Ident));
+ assert!(input.peek(Ident::peek_any));
+ assert!(input.peek(Token![static]));
+
+ let _: Token![static] = input.parse()?;
+
+ assert!(input.peek(Ident));
+ assert!(input.peek(Ident::peek_any));
+
+ let _: Ident = input.parse()?;
+ Ok(())
+ }
+
+ assert.parse2(tokens).unwrap();
+}
+
+#[test]
+fn test_peek_groups() {
+ // pub ( :: ) «∅ ! = ∅» static
+ let tokens = TokenStream::from_iter([
+ TokenTree::Ident(Ident::new("pub", Span::call_site())),
+ TokenTree::Group(Group::new(
+ Delimiter::Parenthesis,
+ TokenStream::from_iter([
+ TokenTree::Punct(Punct::new(':', Spacing::Joint)),
+ TokenTree::Punct(Punct::new(':', Spacing::Alone)),
+ ]),
+ )),
+ TokenTree::Group(Group::new(
+ Delimiter::None,
+ TokenStream::from_iter([
+ TokenTree::Punct(Punct::new('!', Spacing::Alone)),
+ TokenTree::Punct(Punct::new('=', Spacing::Alone)),
+ ]),
+ )),
+ TokenTree::Ident(Ident::new("static", Span::call_site())),
+ ]);
+
+ fn assert(input: ParseStream) -> Result<()> {
+ assert!(input.peek2(token::Paren));
+ assert!(input.peek3(token::Group));
+ assert!(input.peek3(Token![!]));
+
+ let _: Token![pub] = input.parse()?;
+
+ assert!(input.peek(token::Paren));
+ assert!(!input.peek(Token![::]));
+ assert!(!input.peek2(Token![::]));
+ assert!(input.peek2(Token![!]));
+ assert!(input.peek2(token::Group));
+ assert!(input.peek3(Token![=]));
+ assert!(!input.peek3(Token![static]));
+
+ let content;
+ parenthesized!(content in input);
+
+ assert!(content.peek(Token![::]));
+ assert!(content.peek2(Token![:]));
+ assert!(!content.peek3(token::Group));
+ assert!(!content.peek3(Token![!]));
+
+ assert!(input.peek(token::Group));
+ assert!(input.peek(Token![!]));
+
+ let _: Token![::] = content.parse()?;
+
+ assert!(input.peek(token::Group));
+ assert!(input.peek(Token![!]));
+ assert!(input.peek2(Token![=]));
+ assert!(input.peek3(Token![static]));
+ assert!(!input.peek2(Token![static]));
+
+ let implicit = input.fork();
+ let explicit = input.fork();
+
+ let _: Token![!] = implicit.parse()?;
+ assert!(implicit.peek(Token![=]));
+ assert!(implicit.peek2(Token![static]));
+ let _: Token![=] = implicit.parse()?;
+ assert!(implicit.peek(Token![static]));
+
+ let (delimiter, _span, grouped) = explicit.parse_any_delimiter()?;
+ assert_eq!(delimiter, Delimiter::None);
+ assert!(grouped.peek(Token![!]));
+ assert!(grouped.peek2(Token![=]));
+ assert!(!grouped.peek3(Token![static]));
+ let _: Token![!] = grouped.parse()?;
+ assert!(grouped.peek(Token![=]));
+ assert!(!grouped.peek2(Token![static]));
+ let _: Token![=] = grouped.parse()?;
+ assert!(!grouped.peek(Token![static]));
+
+ let _: TokenStream = input.parse()?;
+ Ok(())
+ }
+
+ assert.parse2(tokens).unwrap();
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_pat.rs b/rust/hw/char/pl011/vendor/syn/tests/test_pat.rs
new file mode 100644
index 0000000000..3d13385fd9
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_pat.rs
@@ -0,0 +1,152 @@
+#![allow(clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+use proc_macro2::{Delimiter, Group, TokenStream, TokenTree};
+use quote::{quote, ToTokens as _};
+use syn::parse::Parser;
+use syn::punctuated::Punctuated;
+use syn::{parse_quote, token, Item, Pat, PatTuple, Stmt, Token};
+
+#[test]
+fn test_pat_ident() {
+ match Pat::parse_single.parse2(quote!(self)).unwrap() {
+ Pat::Ident(_) => (),
+ value => panic!("expected PatIdent, got {:?}", value),
+ }
+}
+
+#[test]
+fn test_pat_path() {
+ match Pat::parse_single.parse2(quote!(self::CONST)).unwrap() {
+ Pat::Path(_) => (),
+ value => panic!("expected PatPath, got {:?}", value),
+ }
+}
+
+#[test]
+fn test_leading_vert() {
+ // https://github.com/rust-lang/rust/blob/1.43.0/src/test/ui/or-patterns/remove-leading-vert.rs
+
+ syn::parse_str::<Item>("fn f() {}").unwrap();
+ syn::parse_str::<Item>("fn fun1(| A: E) {}").unwrap_err();
+ syn::parse_str::<Item>("fn fun2(|| A: E) {}").unwrap_err();
+
+ syn::parse_str::<Stmt>("let | () = ();").unwrap_err();
+ syn::parse_str::<Stmt>("let (| A): E;").unwrap();
+ syn::parse_str::<Stmt>("let (|| A): (E);").unwrap_err();
+ syn::parse_str::<Stmt>("let (| A,): (E,);").unwrap();
+ syn::parse_str::<Stmt>("let [| A]: [E; 1];").unwrap();
+ syn::parse_str::<Stmt>("let [|| A]: [E; 1];").unwrap_err();
+ syn::parse_str::<Stmt>("let TS(| A): TS;").unwrap();
+ syn::parse_str::<Stmt>("let TS(|| A): TS;").unwrap_err();
+ syn::parse_str::<Stmt>("let NS { f: | A }: NS;").unwrap();
+ syn::parse_str::<Stmt>("let NS { f: || A }: NS;").unwrap_err();
+}
+
+#[test]
+fn test_group() {
+ let group = Group::new(Delimiter::None, quote!(Some(_)));
+ let tokens = TokenStream::from_iter([TokenTree::Group(group)]);
+ let pat = Pat::parse_single.parse2(tokens).unwrap();
+
+ snapshot!(pat, @r###"
+ Pat::TupleStruct {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Some",
+ },
+ ],
+ },
+ elems: [
+ Pat::Wild,
+ ],
+ }
+ "###);
+}
+
+#[test]
+fn test_ranges() {
+ Pat::parse_single.parse_str("..").unwrap();
+ Pat::parse_single.parse_str("..hi").unwrap();
+ Pat::parse_single.parse_str("lo..").unwrap();
+ Pat::parse_single.parse_str("lo..hi").unwrap();
+
+ Pat::parse_single.parse_str("..=").unwrap_err();
+ Pat::parse_single.parse_str("..=hi").unwrap();
+ Pat::parse_single.parse_str("lo..=").unwrap_err();
+ Pat::parse_single.parse_str("lo..=hi").unwrap();
+
+ Pat::parse_single.parse_str("...").unwrap_err();
+ Pat::parse_single.parse_str("...hi").unwrap_err();
+ Pat::parse_single.parse_str("lo...").unwrap_err();
+ Pat::parse_single.parse_str("lo...hi").unwrap();
+
+ Pat::parse_single.parse_str("[lo..]").unwrap_err();
+ Pat::parse_single.parse_str("[..=hi]").unwrap_err();
+ Pat::parse_single.parse_str("[(lo..)]").unwrap();
+ Pat::parse_single.parse_str("[(..=hi)]").unwrap();
+ Pat::parse_single.parse_str("[lo..=hi]").unwrap();
+
+ Pat::parse_single.parse_str("[_, lo.., _]").unwrap_err();
+ Pat::parse_single.parse_str("[_, ..=hi, _]").unwrap_err();
+ Pat::parse_single.parse_str("[_, (lo..), _]").unwrap();
+ Pat::parse_single.parse_str("[_, (..=hi), _]").unwrap();
+ Pat::parse_single.parse_str("[_, lo..=hi, _]").unwrap();
+}
+
+#[test]
+fn test_tuple_comma() {
+ let mut expr = PatTuple {
+ attrs: Vec::new(),
+ paren_token: token::Paren::default(),
+ elems: Punctuated::new(),
+ };
+ snapshot!(expr.to_token_stream() as Pat, @"Pat::Tuple");
+
+ expr.elems.push_value(parse_quote!(_));
+ // Must not parse to Pat::Paren
+ snapshot!(expr.to_token_stream() as Pat, @r###"
+ Pat::Tuple {
+ elems: [
+ Pat::Wild,
+ Token![,],
+ ],
+ }
+ "###);
+
+ expr.elems.push_punct(<Token![,]>::default());
+ snapshot!(expr.to_token_stream() as Pat, @r###"
+ Pat::Tuple {
+ elems: [
+ Pat::Wild,
+ Token![,],
+ ],
+ }
+ "###);
+
+ expr.elems.push_value(parse_quote!(_));
+ snapshot!(expr.to_token_stream() as Pat, @r###"
+ Pat::Tuple {
+ elems: [
+ Pat::Wild,
+ Token![,],
+ Pat::Wild,
+ ],
+ }
+ "###);
+
+ expr.elems.push_punct(<Token![,]>::default());
+ snapshot!(expr.to_token_stream() as Pat, @r###"
+ Pat::Tuple {
+ elems: [
+ Pat::Wild,
+ Token![,],
+ Pat::Wild,
+ Token![,],
+ ],
+ }
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_path.rs b/rust/hw/char/pl011/vendor/syn/tests/test_path.rs
new file mode 100644
index 0000000000..628b9f853a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_path.rs
@@ -0,0 +1,130 @@
+#![allow(clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
+use quote::{quote, ToTokens};
+use syn::{parse_quote, Expr, Type, TypePath};
+
+#[test]
+fn parse_interpolated_leading_component() {
+ // mimics the token stream corresponding to `$mod::rest`
+ let tokens = TokenStream::from_iter([
+ TokenTree::Group(Group::new(Delimiter::None, quote! { first })),
+ TokenTree::Punct(Punct::new(':', Spacing::Joint)),
+ TokenTree::Punct(Punct::new(':', Spacing::Alone)),
+ TokenTree::Ident(Ident::new("rest", Span::call_site())),
+ ]);
+
+ snapshot!(tokens.clone() as Expr, @r###"
+ Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "first",
+ },
+ Token![::],
+ PathSegment {
+ ident: "rest",
+ },
+ ],
+ },
+ }
+ "###);
+
+ snapshot!(tokens as Type, @r###"
+ Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "first",
+ },
+ Token![::],
+ PathSegment {
+ ident: "rest",
+ },
+ ],
+ },
+ }
+ "###);
+}
+
+#[test]
+fn print_incomplete_qpath() {
+ // qpath with `as` token
+ let mut ty: TypePath = parse_quote!(<Self as A>::Q);
+ snapshot!(ty.to_token_stream(), @r###"
+ TokenStream(`< Self as A > :: Q`)
+ "###);
+ assert!(ty.path.segments.pop().is_some());
+ snapshot!(ty.to_token_stream(), @r###"
+ TokenStream(`< Self as A > ::`)
+ "###);
+ assert!(ty.path.segments.pop().is_some());
+ snapshot!(ty.to_token_stream(), @r###"
+ TokenStream(`< Self >`)
+ "###);
+ assert!(ty.path.segments.pop().is_none());
+
+ // qpath without `as` token
+ let mut ty: TypePath = parse_quote!(<Self>::A::B);
+ snapshot!(ty.to_token_stream(), @r###"
+ TokenStream(`< Self > :: A :: B`)
+ "###);
+ assert!(ty.path.segments.pop().is_some());
+ snapshot!(ty.to_token_stream(), @r###"
+ TokenStream(`< Self > :: A ::`)
+ "###);
+ assert!(ty.path.segments.pop().is_some());
+ snapshot!(ty.to_token_stream(), @r###"
+ TokenStream(`< Self > ::`)
+ "###);
+ assert!(ty.path.segments.pop().is_none());
+
+ // normal path
+ let mut ty: TypePath = parse_quote!(Self::A::B);
+ snapshot!(ty.to_token_stream(), @r###"
+ TokenStream(`Self :: A :: B`)
+ "###);
+ assert!(ty.path.segments.pop().is_some());
+ snapshot!(ty.to_token_stream(), @r###"
+ TokenStream(`Self :: A ::`)
+ "###);
+ assert!(ty.path.segments.pop().is_some());
+ snapshot!(ty.to_token_stream(), @r###"
+ TokenStream(`Self ::`)
+ "###);
+ assert!(ty.path.segments.pop().is_some());
+ snapshot!(ty.to_token_stream(), @r###"
+ TokenStream(``)
+ "###);
+ assert!(ty.path.segments.pop().is_none());
+}
+
+#[test]
+fn parse_parenthesized_path_arguments_with_disambiguator() {
+ #[rustfmt::skip]
+ let tokens = quote!(dyn FnOnce::() -> !);
+ snapshot!(tokens as Type, @r###"
+ Type::TraitObject {
+ dyn_token: Some,
+ bounds: [
+ TypeParamBound::Trait(TraitBound {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "FnOnce",
+ arguments: PathArguments::Parenthesized {
+ output: ReturnType::Type(
+ Type::Never,
+ ),
+ },
+ },
+ ],
+ },
+ }),
+ ],
+ }
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_precedence.rs b/rust/hw/char/pl011/vendor/syn/tests/test_precedence.rs
new file mode 100644
index 0000000000..02b87f37d8
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_precedence.rs
@@ -0,0 +1,537 @@
+// This test does the following for every file in the rust-lang/rust repo:
+//
+// 1. Parse the file using syn into a syn::File.
+// 2. Extract every syn::Expr from the file.
+// 3. Print each expr to a string of source code.
+// 4. Parse the source code using librustc_parse into a rustc_ast::Expr.
+// 5. For both the syn::Expr and rustc_ast::Expr, crawl the syntax tree to
+// insert parentheses surrounding every subexpression.
+// 6. Serialize the fully parenthesized syn::Expr to a string of source code.
+// 7. Parse the fully parenthesized source code using librustc_parse.
+// 8. Compare the rustc_ast::Expr resulting from parenthesizing using rustc data
+// structures vs syn data structures, ignoring spans. If they agree, rustc's
+// parser and syn's parser have identical handling of expression precedence.
+
+#![cfg(not(syn_disable_nightly_tests))]
+#![cfg(not(miri))]
+#![recursion_limit = "1024"]
+#![feature(rustc_private)]
+#![allow(
+ clippy::blocks_in_conditions,
+ clippy::doc_markdown,
+ clippy::explicit_deref_methods,
+ clippy::let_underscore_untyped,
+ clippy::manual_assert,
+ clippy::manual_let_else,
+ clippy::match_like_matches_macro,
+ clippy::match_wildcard_for_single_variants,
+ clippy::too_many_lines,
+ clippy::uninlined_format_args
+)]
+
+extern crate rustc_ast;
+extern crate rustc_ast_pretty;
+extern crate rustc_data_structures;
+extern crate rustc_driver;
+extern crate rustc_span;
+extern crate smallvec;
+extern crate thin_vec;
+
+use crate::common::eq::SpanlessEq;
+use crate::common::parse;
+use quote::ToTokens;
+use rustc_ast::ast;
+use rustc_ast::ptr::P;
+use rustc_ast_pretty::pprust;
+use rustc_span::edition::Edition;
+use std::fs;
+use std::path::Path;
+use std::process;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+#[macro_use]
+mod macros;
+
+mod common;
+mod repo;
+
+#[test]
+fn test_rustc_precedence() {
+ common::rayon_init();
+ repo::clone_rust();
+ let abort_after = common::abort_after();
+ if abort_after == 0 {
+ panic!("skipping all precedence tests");
+ }
+
+ let passed = AtomicUsize::new(0);
+ let failed = AtomicUsize::new(0);
+
+ repo::for_each_rust_file(|path| {
+ let content = fs::read_to_string(path).unwrap();
+
+ let (l_passed, l_failed) = match syn::parse_file(&content) {
+ Ok(file) => {
+ let edition = repo::edition(path).parse().unwrap();
+ let exprs = collect_exprs(file);
+ let (l_passed, l_failed) = test_expressions(path, edition, exprs);
+ errorf!(
+ "=== {}: {} passed | {} failed\n",
+ path.display(),
+ l_passed,
+ l_failed,
+ );
+ (l_passed, l_failed)
+ }
+ Err(msg) => {
+ errorf!("\nFAIL {} - syn failed to parse: {}\n", path.display(), msg);
+ (0, 1)
+ }
+ };
+
+ passed.fetch_add(l_passed, Ordering::Relaxed);
+ let prev_failed = failed.fetch_add(l_failed, Ordering::Relaxed);
+
+ if prev_failed + l_failed >= abort_after {
+ process::exit(1);
+ }
+ });
+
+ let passed = passed.load(Ordering::Relaxed);
+ let failed = failed.load(Ordering::Relaxed);
+
+ errorf!("\n===== Precedence Test Results =====\n");
+ errorf!("{} passed | {} failed\n", passed, failed);
+
+ if failed > 0 {
+ panic!("{} failures", failed);
+ }
+}
+
+fn test_expressions(path: &Path, edition: Edition, exprs: Vec<syn::Expr>) -> (usize, usize) {
+ let mut passed = 0;
+ let mut failed = 0;
+
+ rustc_span::create_session_if_not_set_then(edition, |_| {
+ for expr in exprs {
+ let source_code = expr.to_token_stream().to_string();
+ let librustc_ast = if let Some(e) = librustc_parse_and_rewrite(&source_code) {
+ e
+ } else {
+ failed += 1;
+ errorf!(
+ "\nFAIL {} - librustc failed to parse original\n",
+ path.display(),
+ );
+ continue;
+ };
+
+ let syn_parenthesized_code =
+ syn_parenthesize(expr.clone()).to_token_stream().to_string();
+ let syn_ast = if let Some(e) = parse::librustc_expr(&syn_parenthesized_code) {
+ e
+ } else {
+ failed += 1;
+ errorf!(
+ "\nFAIL {} - librustc failed to parse parenthesized\n",
+ path.display(),
+ );
+ continue;
+ };
+
+ if !SpanlessEq::eq(&syn_ast, &librustc_ast) {
+ failed += 1;
+ let syn_pretty = pprust::expr_to_string(&syn_ast);
+ let librustc_pretty = pprust::expr_to_string(&librustc_ast);
+ errorf!(
+ "\nFAIL {}\n{}\nsyn != rustc\n{}\n",
+ path.display(),
+ syn_pretty,
+ librustc_pretty,
+ );
+ continue;
+ }
+
+ let expr_invisible = make_parens_invisible(expr);
+ let Ok(reparsed_expr_invisible) = syn::parse2(expr_invisible.to_token_stream()) else {
+ failed += 1;
+ errorf!(
+ "\nFAIL {} - syn failed to parse invisible delimiters\n{}\n",
+ path.display(),
+ source_code,
+ );
+ continue;
+ };
+ if expr_invisible != reparsed_expr_invisible {
+ failed += 1;
+ errorf!(
+ "\nFAIL {} - mismatch after parsing invisible delimiters\n{}\n",
+ path.display(),
+ source_code,
+ );
+ continue;
+ }
+
+ passed += 1;
+ }
+ });
+
+ (passed, failed)
+}
+
+fn librustc_parse_and_rewrite(input: &str) -> Option<P<ast::Expr>> {
+ parse::librustc_expr(input).map(librustc_parenthesize)
+}
+
+fn librustc_parenthesize(mut librustc_expr: P<ast::Expr>) -> P<ast::Expr> {
+ use rustc_ast::ast::{
+ AssocItem, AssocItemKind, Attribute, BinOpKind, Block, BorrowKind, BoundConstness, Expr,
+ ExprField, ExprKind, GenericArg, GenericBound, Local, LocalKind, Pat, Stmt, StmtKind,
+ StructExpr, StructRest, TraitBoundModifiers, Ty,
+ };
+ use rustc_ast::mut_visit::{noop_flat_map_item, MutVisitor};
+ use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
+ use rustc_span::DUMMY_SP;
+ use smallvec::SmallVec;
+ use std::mem;
+ use std::ops::DerefMut;
+ use thin_vec::ThinVec;
+
+ struct FullyParenthesize;
+
+ fn contains_let_chain(expr: &Expr) -> bool {
+ match &expr.kind {
+ ExprKind::Let(..) => true,
+ ExprKind::Binary(binop, left, right) => {
+ binop.node == BinOpKind::And
+ && (contains_let_chain(left) || contains_let_chain(right))
+ }
+ _ => false,
+ }
+ }
+
+ fn flat_map_field<T: MutVisitor>(mut f: ExprField, vis: &mut T) -> Vec<ExprField> {
+ if f.is_shorthand {
+ noop_visit_expr(&mut f.expr, vis);
+ } else {
+ vis.visit_expr(&mut f.expr);
+ }
+ vec![f]
+ }
+
+ fn flat_map_stmt<T: MutVisitor>(stmt: Stmt, vis: &mut T) -> Vec<Stmt> {
+ let kind = match stmt.kind {
+ // Don't wrap toplevel expressions in statements.
+ StmtKind::Expr(mut e) => {
+ noop_visit_expr(&mut e, vis);
+ StmtKind::Expr(e)
+ }
+ StmtKind::Semi(mut e) => {
+ noop_visit_expr(&mut e, vis);
+ StmtKind::Semi(e)
+ }
+ s => s,
+ };
+
+ vec![Stmt { kind, ..stmt }]
+ }
+
+ fn noop_visit_expr<T: MutVisitor>(e: &mut Expr, vis: &mut T) {
+ match &mut e.kind {
+ ExprKind::AddrOf(BorrowKind::Raw, ..) => {}
+ ExprKind::Struct(expr) => {
+ let StructExpr {
+ qself,
+ path,
+ fields,
+ rest,
+ } = expr.deref_mut();
+ vis.visit_qself(qself);
+ vis.visit_path(path);
+ fields.flat_map_in_place(|field| flat_map_field(field, vis));
+ if let StructRest::Base(rest) = rest {
+ vis.visit_expr(rest);
+ }
+ }
+ _ => rustc_ast::mut_visit::noop_visit_expr(e, vis),
+ }
+ }
+
+ impl MutVisitor for FullyParenthesize {
+ fn visit_expr(&mut self, e: &mut P<Expr>) {
+ noop_visit_expr(e, self);
+ match e.kind {
+ ExprKind::Block(..) | ExprKind::If(..) | ExprKind::Let(..) => {}
+ ExprKind::Binary(..) if contains_let_chain(e) => {}
+ _ => {
+ let inner = mem::replace(
+ e,
+ P(Expr {
+ id: ast::DUMMY_NODE_ID,
+ kind: ExprKind::Dummy,
+ span: DUMMY_SP,
+ attrs: ThinVec::new(),
+ tokens: None,
+ }),
+ );
+ e.kind = ExprKind::Paren(inner);
+ }
+ }
+ }
+
+ fn visit_generic_arg(&mut self, arg: &mut GenericArg) {
+ match arg {
+ GenericArg::Lifetime(_lifetime) => {}
+ GenericArg::Type(arg) => self.visit_ty(arg),
+ // Don't wrap unbraced const generic arg as that's invalid syntax.
+ GenericArg::Const(anon_const) => {
+ if let ExprKind::Block(..) = &mut anon_const.value.kind {
+ noop_visit_expr(&mut anon_const.value, self);
+ }
+ }
+ }
+ }
+
+ fn visit_param_bound(&mut self, bound: &mut GenericBound) {
+ match bound {
+ GenericBound::Trait(
+ _,
+ TraitBoundModifiers {
+ constness: BoundConstness::Maybe(_),
+ ..
+ },
+ ) => {}
+ GenericBound::Trait(ty, _modifier) => self.visit_poly_trait_ref(ty),
+ GenericBound::Outlives(_lifetime) => {}
+ }
+ }
+
+ fn visit_block(&mut self, block: &mut P<Block>) {
+ self.visit_id(&mut block.id);
+ block
+ .stmts
+ .flat_map_in_place(|stmt| flat_map_stmt(stmt, self));
+ self.visit_span(&mut block.span);
+ }
+
+ fn visit_local(&mut self, local: &mut P<Local>) {
+ match &mut local.kind {
+ LocalKind::Decl => {}
+ LocalKind::Init(init) => {
+ self.visit_expr(init);
+ }
+ LocalKind::InitElse(init, els) => {
+ self.visit_expr(init);
+ self.visit_block(els);
+ }
+ }
+ }
+
+ fn flat_map_trait_item(&mut self, item: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> {
+ match &item.kind {
+ AssocItemKind::Const(const_item)
+ if !const_item.generics.params.is_empty()
+ || !const_item.generics.where_clause.predicates.is_empty() =>
+ {
+ SmallVec::from([item])
+ }
+ _ => noop_flat_map_item(item, self),
+ }
+ }
+
+ fn flat_map_impl_item(&mut self, item: P<AssocItem>) -> SmallVec<[P<AssocItem>; 1]> {
+ match &item.kind {
+ AssocItemKind::Const(const_item)
+ if !const_item.generics.params.is_empty()
+ || !const_item.generics.where_clause.predicates.is_empty() =>
+ {
+ SmallVec::from([item])
+ }
+ _ => noop_flat_map_item(item, self),
+ }
+ }
+
+ // We don't want to look at expressions that might appear in patterns or
+ // types yet. We'll look into comparing those in the future. For now
+ // focus on expressions appearing in other places.
+ fn visit_pat(&mut self, pat: &mut P<Pat>) {
+ let _ = pat;
+ }
+
+ fn visit_ty(&mut self, ty: &mut P<Ty>) {
+ let _ = ty;
+ }
+
+ fn visit_attribute(&mut self, attr: &mut Attribute) {
+ let _ = attr;
+ }
+ }
+
+ let mut folder = FullyParenthesize;
+ folder.visit_expr(&mut librustc_expr);
+ librustc_expr
+}
+
+fn syn_parenthesize(syn_expr: syn::Expr) -> syn::Expr {
+ use syn::fold::{fold_expr, fold_generic_argument, Fold};
+ use syn::{token, BinOp, Expr, ExprParen, GenericArgument, MetaNameValue, Pat, Stmt, Type};
+
+ struct FullyParenthesize;
+
+ fn parenthesize(expr: Expr) -> Expr {
+ Expr::Paren(ExprParen {
+ attrs: Vec::new(),
+ expr: Box::new(expr),
+ paren_token: token::Paren::default(),
+ })
+ }
+
+ fn needs_paren(expr: &Expr) -> bool {
+ match expr {
+ Expr::Group(_) => unreachable!(),
+ Expr::If(_) | Expr::Unsafe(_) | Expr::Block(_) | Expr::Let(_) => false,
+ Expr::Binary(_) => !contains_let_chain(expr),
+ _ => true,
+ }
+ }
+
+ fn contains_let_chain(expr: &Expr) -> bool {
+ match expr {
+ Expr::Let(_) => true,
+ Expr::Binary(expr) => {
+ matches!(expr.op, BinOp::And(_))
+ && (contains_let_chain(&expr.left) || contains_let_chain(&expr.right))
+ }
+ _ => false,
+ }
+ }
+
+ impl Fold for FullyParenthesize {
+ fn fold_expr(&mut self, expr: Expr) -> Expr {
+ let needs_paren = needs_paren(&expr);
+ let folded = fold_expr(self, expr);
+ if needs_paren {
+ parenthesize(folded)
+ } else {
+ folded
+ }
+ }
+
+ fn fold_generic_argument(&mut self, arg: GenericArgument) -> GenericArgument {
+ match arg {
+ GenericArgument::Const(arg) => GenericArgument::Const(match arg {
+ Expr::Block(_) => fold_expr(self, arg),
+ // Don't wrap unbraced const generic arg as that's invalid syntax.
+ _ => arg,
+ }),
+ _ => fold_generic_argument(self, arg),
+ }
+ }
+
+ fn fold_stmt(&mut self, stmt: Stmt) -> Stmt {
+ match stmt {
+ // Don't wrap toplevel expressions in statements.
+ Stmt::Expr(Expr::Verbatim(_), Some(_)) => stmt,
+ Stmt::Expr(e, semi) => Stmt::Expr(fold_expr(self, e), semi),
+ s => s,
+ }
+ }
+
+ fn fold_meta_name_value(&mut self, meta: MetaNameValue) -> MetaNameValue {
+ // Don't turn #[p = "..."] into #[p = ("...")].
+ meta
+ }
+
+ // We don't want to look at expressions that might appear in patterns or
+ // types yet. We'll look into comparing those in the future. For now
+ // focus on expressions appearing in other places.
+ fn fold_pat(&mut self, pat: Pat) -> Pat {
+ pat
+ }
+
+ fn fold_type(&mut self, ty: Type) -> Type {
+ ty
+ }
+ }
+
+ let mut folder = FullyParenthesize;
+ folder.fold_expr(syn_expr)
+}
+
+fn make_parens_invisible(expr: syn::Expr) -> syn::Expr {
+ use syn::fold::{fold_expr, fold_stmt, Fold};
+ use syn::{token, Expr, ExprGroup, ExprParen, Stmt};
+
+ struct MakeParensInvisible;
+
+ impl Fold for MakeParensInvisible {
+ fn fold_expr(&mut self, mut expr: Expr) -> Expr {
+ if let Expr::Paren(paren) = expr {
+ expr = Expr::Group(ExprGroup {
+ attrs: paren.attrs,
+ group_token: token::Group(paren.paren_token.span.join()),
+ expr: paren.expr,
+ });
+ }
+ fold_expr(self, expr)
+ }
+
+ fn fold_stmt(&mut self, stmt: Stmt) -> Stmt {
+ if let Stmt::Expr(expr @ (Expr::Binary(_) | Expr::Cast(_)), None) = stmt {
+ Stmt::Expr(
+ Expr::Paren(ExprParen {
+ attrs: Vec::new(),
+ paren_token: token::Paren::default(),
+ expr: Box::new(fold_expr(self, expr)),
+ }),
+ None,
+ )
+ } else {
+ fold_stmt(self, stmt)
+ }
+ }
+ }
+
+ let mut folder = MakeParensInvisible;
+ folder.fold_expr(expr)
+}
+
+/// Walk through a crate collecting all expressions we can find in it.
+fn collect_exprs(file: syn::File) -> Vec<syn::Expr> {
+ use syn::fold::Fold;
+ use syn::punctuated::Punctuated;
+ use syn::{token, ConstParam, Expr, ExprTuple, Pat, Path};
+
+ struct CollectExprs(Vec<Expr>);
+ impl Fold for CollectExprs {
+ fn fold_expr(&mut self, expr: Expr) -> Expr {
+ match expr {
+ Expr::Verbatim(_) => {}
+ _ => self.0.push(expr),
+ }
+
+ Expr::Tuple(ExprTuple {
+ attrs: vec![],
+ elems: Punctuated::new(),
+ paren_token: token::Paren::default(),
+ })
+ }
+
+ fn fold_pat(&mut self, pat: Pat) -> Pat {
+ pat
+ }
+
+ fn fold_path(&mut self, path: Path) -> Path {
+ // Skip traversing into const generic path arguments
+ path
+ }
+
+ fn fold_const_param(&mut self, const_param: ConstParam) -> ConstParam {
+ const_param
+ }
+ }
+
+ let mut folder = CollectExprs(vec![]);
+ folder.fold_file(file);
+ folder.0
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_receiver.rs b/rust/hw/char/pl011/vendor/syn/tests/test_receiver.rs
new file mode 100644
index 0000000000..8decb555c5
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_receiver.rs
@@ -0,0 +1,321 @@
+#![allow(clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+use syn::{parse_quote, TraitItemFn};
+
+#[test]
+fn test_by_value() {
+ let TraitItemFn { sig, .. } = parse_quote! {
+ fn by_value(self: Self);
+ };
+ snapshot!(&sig.inputs[0], @r###"
+ FnArg::Receiver(Receiver {
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Self",
+ },
+ ],
+ },
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_by_mut_value() {
+ let TraitItemFn { sig, .. } = parse_quote! {
+ fn by_mut(mut self: Self);
+ };
+ snapshot!(&sig.inputs[0], @r###"
+ FnArg::Receiver(Receiver {
+ mutability: Some,
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Self",
+ },
+ ],
+ },
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_by_ref() {
+ let TraitItemFn { sig, .. } = parse_quote! {
+ fn by_ref(self: &Self);
+ };
+ snapshot!(&sig.inputs[0], @r###"
+ FnArg::Receiver(Receiver {
+ colon_token: Some,
+ ty: Type::Reference {
+ elem: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Self",
+ },
+ ],
+ },
+ },
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_by_box() {
+ let TraitItemFn { sig, .. } = parse_quote! {
+ fn by_box(self: Box<Self>);
+ };
+ snapshot!(&sig.inputs[0], @r###"
+ FnArg::Receiver(Receiver {
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Box",
+ arguments: PathArguments::AngleBracketed {
+ args: [
+ GenericArgument::Type(Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Self",
+ },
+ ],
+ },
+ }),
+ ],
+ },
+ },
+ ],
+ },
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_by_pin() {
+ let TraitItemFn { sig, .. } = parse_quote! {
+ fn by_pin(self: Pin<Self>);
+ };
+ snapshot!(&sig.inputs[0], @r###"
+ FnArg::Receiver(Receiver {
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Pin",
+ arguments: PathArguments::AngleBracketed {
+ args: [
+ GenericArgument::Type(Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Self",
+ },
+ ],
+ },
+ }),
+ ],
+ },
+ },
+ ],
+ },
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_explicit_type() {
+ let TraitItemFn { sig, .. } = parse_quote! {
+ fn explicit_type(self: Pin<MyType>);
+ };
+ snapshot!(&sig.inputs[0], @r###"
+ FnArg::Receiver(Receiver {
+ colon_token: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Pin",
+ arguments: PathArguments::AngleBracketed {
+ args: [
+ GenericArgument::Type(Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "MyType",
+ },
+ ],
+ },
+ }),
+ ],
+ },
+ },
+ ],
+ },
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_value_shorthand() {
+ let TraitItemFn { sig, .. } = parse_quote! {
+ fn value_shorthand(self);
+ };
+ snapshot!(&sig.inputs[0], @r###"
+ FnArg::Receiver(Receiver {
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Self",
+ },
+ ],
+ },
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_mut_value_shorthand() {
+ let TraitItemFn { sig, .. } = parse_quote! {
+ fn mut_value_shorthand(mut self);
+ };
+ snapshot!(&sig.inputs[0], @r###"
+ FnArg::Receiver(Receiver {
+ mutability: Some,
+ ty: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Self",
+ },
+ ],
+ },
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_ref_shorthand() {
+ let TraitItemFn { sig, .. } = parse_quote! {
+ fn ref_shorthand(&self);
+ };
+ snapshot!(&sig.inputs[0], @r###"
+ FnArg::Receiver(Receiver {
+ reference: Some(None),
+ ty: Type::Reference {
+ elem: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Self",
+ },
+ ],
+ },
+ },
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_ref_shorthand_with_lifetime() {
+ let TraitItemFn { sig, .. } = parse_quote! {
+ fn ref_shorthand(&'a self);
+ };
+ snapshot!(&sig.inputs[0], @r###"
+ FnArg::Receiver(Receiver {
+ reference: Some(Some(Lifetime {
+ ident: "a",
+ })),
+ ty: Type::Reference {
+ lifetime: Some(Lifetime {
+ ident: "a",
+ }),
+ elem: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Self",
+ },
+ ],
+ },
+ },
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_ref_mut_shorthand() {
+ let TraitItemFn { sig, .. } = parse_quote! {
+ fn ref_mut_shorthand(&mut self);
+ };
+ snapshot!(&sig.inputs[0], @r###"
+ FnArg::Receiver(Receiver {
+ reference: Some(None),
+ mutability: Some,
+ ty: Type::Reference {
+ mutability: Some,
+ elem: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Self",
+ },
+ ],
+ },
+ },
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_ref_mut_shorthand_with_lifetime() {
+ let TraitItemFn { sig, .. } = parse_quote! {
+ fn ref_mut_shorthand(&'a mut self);
+ };
+ snapshot!(&sig.inputs[0], @r###"
+ FnArg::Receiver(Receiver {
+ reference: Some(Some(Lifetime {
+ ident: "a",
+ })),
+ mutability: Some,
+ ty: Type::Reference {
+ lifetime: Some(Lifetime {
+ ident: "a",
+ }),
+ mutability: Some,
+ elem: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Self",
+ },
+ ],
+ },
+ },
+ },
+ })
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_round_trip.rs b/rust/hw/char/pl011/vendor/syn/tests/test_round_trip.rs
new file mode 100644
index 0000000000..9b089036d0
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_round_trip.rs
@@ -0,0 +1,253 @@
+#![cfg(not(syn_disable_nightly_tests))]
+#![cfg(not(miri))]
+#![recursion_limit = "1024"]
+#![feature(rustc_private)]
+#![allow(
+ clippy::blocks_in_conditions,
+ clippy::manual_assert,
+ clippy::manual_let_else,
+ clippy::match_like_matches_macro,
+ clippy::uninlined_format_args
+)]
+
+extern crate rustc_ast;
+extern crate rustc_ast_pretty;
+extern crate rustc_data_structures;
+extern crate rustc_driver;
+extern crate rustc_error_messages;
+extern crate rustc_errors;
+extern crate rustc_expand;
+extern crate rustc_parse as parse;
+extern crate rustc_session;
+extern crate rustc_span;
+
+use crate::common::eq::SpanlessEq;
+use quote::quote;
+use rustc_ast::ast::{
+ AngleBracketedArg, AngleBracketedArgs, Crate, GenericArg, GenericParamKind, Generics,
+ WhereClause,
+};
+use rustc_ast::mut_visit::MutVisitor;
+use rustc_ast_pretty::pprust;
+use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
+use rustc_error_messages::{DiagMessage, LazyFallbackBundle};
+use rustc_errors::{translation, Diag, PResult};
+use rustc_session::parse::ParseSess;
+use rustc_span::FileName;
+use std::borrow::Cow;
+use std::fs;
+use std::panic;
+use std::path::Path;
+use std::process;
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::time::Instant;
+
+#[macro_use]
+mod macros;
+
+mod common;
+mod repo;
+
+#[test]
+fn test_round_trip() {
+ common::rayon_init();
+ repo::clone_rust();
+ let abort_after = common::abort_after();
+ if abort_after == 0 {
+ panic!("skipping all round_trip tests");
+ }
+
+ let failed = AtomicUsize::new(0);
+
+ repo::for_each_rust_file(|path| test(path, &failed, abort_after));
+
+ let failed = failed.load(Ordering::Relaxed);
+ if failed > 0 {
+ panic!("{} failures", failed);
+ }
+}
+
+fn test(path: &Path, failed: &AtomicUsize, abort_after: usize) {
+ let failed = || {
+ let prev_failed = failed.fetch_add(1, Ordering::Relaxed);
+ if prev_failed + 1 >= abort_after {
+ process::exit(1);
+ }
+ };
+
+ let content = fs::read_to_string(path).unwrap();
+
+ let (back, elapsed) = match panic::catch_unwind(|| {
+ let start = Instant::now();
+ let result = syn::parse_file(&content);
+ let elapsed = start.elapsed();
+ result.map(|krate| (quote!(#krate).to_string(), elapsed))
+ }) {
+ Err(_) => {
+ errorf!("=== {}: syn panic\n", path.display());
+ failed();
+ return;
+ }
+ Ok(Err(msg)) => {
+ errorf!("=== {}: syn failed to parse\n{:?}\n", path.display(), msg);
+ failed();
+ return;
+ }
+ Ok(Ok(result)) => result,
+ };
+
+ let edition = repo::edition(path).parse().unwrap();
+
+ rustc_span::create_session_if_not_set_then(edition, |_| {
+ let equal = match panic::catch_unwind(|| {
+ let locale_resources = rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec();
+ let sess = ParseSess::new(locale_resources);
+ let before = match librustc_parse(content, &sess) {
+ Ok(before) => before,
+ Err(diagnostic) => {
+ errorf!(
+ "=== {}: ignore - librustc failed to parse original content: {}\n",
+ path.display(),
+ translate_message(&diagnostic),
+ );
+ diagnostic.cancel();
+ return Err(true);
+ }
+ };
+ let after = match librustc_parse(back, &sess) {
+ Ok(after) => after,
+ Err(diagnostic) => {
+ errorf!("=== {}: librustc failed to parse", path.display());
+ diagnostic.emit();
+ return Err(false);
+ }
+ };
+ Ok((before, after))
+ }) {
+ Err(_) => {
+ errorf!("=== {}: ignoring librustc panic\n", path.display());
+ true
+ }
+ Ok(Err(equal)) => equal,
+ Ok(Ok((mut before, mut after))) => {
+ normalize(&mut before);
+ normalize(&mut after);
+ if SpanlessEq::eq(&before, &after) {
+ errorf!(
+ "=== {}: pass in {}ms\n",
+ path.display(),
+ elapsed.as_secs() * 1000 + u64::from(elapsed.subsec_nanos()) / 1_000_000
+ );
+ true
+ } else {
+ errorf!(
+ "=== {}: FAIL\n{}\n!=\n{}\n",
+ path.display(),
+ pprust::crate_to_string_for_macros(&before),
+ pprust::crate_to_string_for_macros(&after),
+ );
+ false
+ }
+ }
+ };
+ if !equal {
+ failed();
+ }
+ });
+}
+
+fn librustc_parse(content: String, sess: &ParseSess) -> PResult<Crate> {
+ static COUNTER: AtomicUsize = AtomicUsize::new(0);
+ let counter = COUNTER.fetch_add(1, Ordering::Relaxed);
+ let name = FileName::Custom(format!("test_round_trip{}", counter));
+ parse::parse_crate_from_source_str(name, content, sess)
+}
+
+fn translate_message(diagnostic: &Diag) -> Cow<'static, str> {
+ thread_local! {
+ static FLUENT_BUNDLE: LazyFallbackBundle = {
+ let locale_resources = rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec();
+ let with_directionality_markers = false;
+ rustc_error_messages::fallback_fluent_bundle(locale_resources, with_directionality_markers)
+ };
+ }
+
+ let message = &diagnostic.messages[0].0;
+ let args = translation::to_fluent_args(diagnostic.args.iter());
+
+ let (identifier, attr) = match message {
+ DiagMessage::Str(msg) | DiagMessage::Translated(msg) => return msg.clone(),
+ DiagMessage::FluentIdentifier(identifier, attr) => (identifier, attr),
+ };
+
+ FLUENT_BUNDLE.with(|fluent_bundle| {
+ let message = fluent_bundle
+ .get_message(identifier)
+ .expect("missing diagnostic in fluent bundle");
+ let value = match attr {
+ Some(attr) => message
+ .get_attribute(attr)
+ .expect("missing attribute in fluent message")
+ .value(),
+ None => message.value().expect("missing value in fluent message"),
+ };
+
+ let mut err = Vec::new();
+ let translated = fluent_bundle.format_pattern(value, Some(&args), &mut err);
+ assert!(err.is_empty());
+ Cow::Owned(translated.into_owned())
+ })
+}
+
+fn normalize(krate: &mut Crate) {
+ struct NormalizeVisitor;
+
+ impl MutVisitor for NormalizeVisitor {
+ fn visit_angle_bracketed_parameter_data(&mut self, e: &mut AngleBracketedArgs) {
+ #[derive(Ord, PartialOrd, Eq, PartialEq)]
+ enum Group {
+ Lifetimes,
+ TypesAndConsts,
+ Constraints,
+ }
+ e.args.sort_by_key(|arg| match arg {
+ AngleBracketedArg::Arg(arg) => match arg {
+ GenericArg::Lifetime(_) => Group::Lifetimes,
+ GenericArg::Type(_) | GenericArg::Const(_) => Group::TypesAndConsts,
+ },
+ AngleBracketedArg::Constraint(_) => Group::Constraints,
+ });
+ for arg in &mut e.args {
+ match arg {
+ AngleBracketedArg::Arg(arg) => self.visit_generic_arg(arg),
+ AngleBracketedArg::Constraint(constraint) => self.visit_constraint(constraint),
+ }
+ }
+ }
+
+ fn visit_generics(&mut self, e: &mut Generics) {
+ #[derive(Ord, PartialOrd, Eq, PartialEq)]
+ enum Group {
+ Lifetimes,
+ TypesAndConsts,
+ }
+ e.params.sort_by_key(|param| match param.kind {
+ GenericParamKind::Lifetime => Group::Lifetimes,
+ GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
+ Group::TypesAndConsts
+ }
+ });
+ e.params
+ .flat_map_in_place(|param| self.flat_map_generic_param(param));
+ self.visit_where_clause(&mut e.where_clause);
+ }
+
+ fn visit_where_clause(&mut self, e: &mut WhereClause) {
+ if e.predicates.is_empty() {
+ e.has_where_token = false;
+ }
+ }
+ }
+
+ NormalizeVisitor.visit_crate(krate);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_shebang.rs b/rust/hw/char/pl011/vendor/syn/tests/test_shebang.rs
new file mode 100644
index 0000000000..843916180f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_shebang.rs
@@ -0,0 +1,67 @@
+#![allow(clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+#[test]
+fn test_basic() {
+ let content = "#!/usr/bin/env rustx\nfn main() {}";
+ let file = syn::parse_file(content).unwrap();
+ snapshot!(file, @r###"
+ File {
+ shebang: Some("#!/usr/bin/env rustx"),
+ items: [
+ Item::Fn {
+ vis: Visibility::Inherited,
+ sig: Signature {
+ ident: "main",
+ generics: Generics,
+ output: ReturnType::Default,
+ },
+ block: Block {
+ stmts: [],
+ },
+ },
+ ],
+ }
+ "###);
+}
+
+#[test]
+fn test_comment() {
+ let content = "#!//am/i/a/comment\n[allow(dead_code)] fn main() {}";
+ let file = syn::parse_file(content).unwrap();
+ snapshot!(file, @r###"
+ File {
+ attrs: [
+ Attribute {
+ style: AttrStyle::Inner,
+ meta: Meta::List {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "allow",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`dead_code`),
+ },
+ },
+ ],
+ items: [
+ Item::Fn {
+ vis: Visibility::Inherited,
+ sig: Signature {
+ ident: "main",
+ generics: Generics,
+ output: ReturnType::Default,
+ },
+ block: Block {
+ stmts: [],
+ },
+ },
+ ],
+ }
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_size.rs b/rust/hw/char/pl011/vendor/syn/tests/test_size.rs
new file mode 100644
index 0000000000..32e6119c98
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_size.rs
@@ -0,0 +1,36 @@
+// Assumes proc-macro2's "span-locations" feature is off.
+
+#![cfg(target_pointer_width = "64")]
+
+use std::mem;
+use syn::{Expr, Item, Lit, Pat, Type};
+
+#[rustversion::attr(before(2022-11-24), ignore)]
+#[test]
+fn test_expr_size() {
+ assert_eq!(mem::size_of::<Expr>(), 176);
+}
+
+#[rustversion::attr(before(2022-09-09), ignore)]
+#[test]
+fn test_item_size() {
+ assert_eq!(mem::size_of::<Item>(), 352);
+}
+
+#[rustversion::attr(before(2023-04-29), ignore)]
+#[test]
+fn test_type_size() {
+ assert_eq!(mem::size_of::<Type>(), 224);
+}
+
+#[rustversion::attr(before(2023-04-29), ignore)]
+#[test]
+fn test_pat_size() {
+ assert_eq!(mem::size_of::<Pat>(), 184);
+}
+
+#[rustversion::attr(before(2023-12-20), ignore)]
+#[test]
+fn test_lit_size() {
+ assert_eq!(mem::size_of::<Lit>(), 24);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_stmt.rs b/rust/hw/char/pl011/vendor/syn/tests/test_stmt.rs
new file mode 100644
index 0000000000..318e18b069
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_stmt.rs
@@ -0,0 +1,322 @@
+#![allow(
+ clippy::assertions_on_result_states,
+ clippy::non_ascii_literal,
+ clippy::uninlined_format_args
+)]
+
+#[macro_use]
+mod macros;
+
+use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
+use quote::{quote, ToTokens as _};
+use syn::parse::Parser as _;
+use syn::{Block, Stmt};
+
+#[test]
+fn test_raw_operator() {
+ let stmt = syn::parse_str::<Stmt>("let _ = &raw const x;").unwrap();
+
+ snapshot!(stmt, @r###"
+ Stmt::Local {
+ pat: Pat::Wild,
+ init: Some(LocalInit {
+ expr: Expr::Verbatim(`& raw const x`),
+ }),
+ }
+ "###);
+}
+
+#[test]
+fn test_raw_variable() {
+ let stmt = syn::parse_str::<Stmt>("let _ = &raw;").unwrap();
+
+ snapshot!(stmt, @r###"
+ Stmt::Local {
+ pat: Pat::Wild,
+ init: Some(LocalInit {
+ expr: Expr::Reference {
+ expr: Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "raw",
+ },
+ ],
+ },
+ },
+ },
+ }),
+ }
+ "###);
+}
+
+#[test]
+fn test_raw_invalid() {
+ assert!(syn::parse_str::<Stmt>("let _ = &raw x;").is_err());
+}
+
+#[test]
+fn test_none_group() {
+ // «∅ async fn f() {} ∅»
+ let tokens = TokenStream::from_iter([TokenTree::Group(Group::new(
+ Delimiter::None,
+ TokenStream::from_iter([
+ TokenTree::Ident(Ident::new("async", Span::call_site())),
+ TokenTree::Ident(Ident::new("fn", Span::call_site())),
+ TokenTree::Ident(Ident::new("f", Span::call_site())),
+ TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),
+ TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
+ ]),
+ ))]);
+ snapshot!(tokens as Stmt, @r###"
+ Stmt::Item(Item::Fn {
+ vis: Visibility::Inherited,
+ sig: Signature {
+ asyncness: Some,
+ ident: "f",
+ generics: Generics,
+ output: ReturnType::Default,
+ },
+ block: Block {
+ stmts: [],
+ },
+ })
+ "###);
+
+ let tokens = Group::new(Delimiter::None, quote!(let None = None)).to_token_stream();
+ let stmts = Block::parse_within.parse2(tokens).unwrap();
+ snapshot!(stmts, @r###"
+ [
+ Stmt::Expr(
+ Expr::Group {
+ expr: Expr::Let {
+ pat: Pat::Ident {
+ ident: "None",
+ },
+ expr: Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "None",
+ },
+ ],
+ },
+ },
+ },
+ },
+ None,
+ ),
+ ]
+ "###);
+}
+
+#[test]
+fn test_let_dot_dot() {
+ let tokens = quote! {
+ let .. = 10;
+ };
+
+ snapshot!(tokens as Stmt, @r###"
+ Stmt::Local {
+ pat: Pat::Rest,
+ init: Some(LocalInit {
+ expr: Expr::Lit {
+ lit: 10,
+ },
+ }),
+ }
+ "###);
+}
+
+#[test]
+fn test_let_else() {
+ let tokens = quote! {
+ let Some(x) = None else { return 0; };
+ };
+
+ snapshot!(tokens as Stmt, @r###"
+ Stmt::Local {
+ pat: Pat::TupleStruct {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Some",
+ },
+ ],
+ },
+ elems: [
+ Pat::Ident {
+ ident: "x",
+ },
+ ],
+ },
+ init: Some(LocalInit {
+ expr: Expr::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "None",
+ },
+ ],
+ },
+ },
+ diverge: Some(Expr::Block {
+ block: Block {
+ stmts: [
+ Stmt::Expr(
+ Expr::Return {
+ expr: Some(Expr::Lit {
+ lit: 0,
+ }),
+ },
+ Some,
+ ),
+ ],
+ },
+ }),
+ }),
+ }
+ "###);
+}
+
+#[test]
+fn test_macros() {
+ let tokens = quote! {
+ fn main() {
+ macro_rules! mac {}
+ thread_local! { static FOO }
+ println!("");
+ vec![]
+ }
+ };
+
+ snapshot!(tokens as Stmt, @r###"
+ Stmt::Item(Item::Fn {
+ vis: Visibility::Inherited,
+ sig: Signature {
+ ident: "main",
+ generics: Generics,
+ output: ReturnType::Default,
+ },
+ block: Block {
+ stmts: [
+ Stmt::Item(Item::Macro {
+ ident: Some("mac"),
+ mac: Macro {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "macro_rules",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Brace,
+ tokens: TokenStream(``),
+ },
+ }),
+ Stmt::Macro {
+ mac: Macro {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "thread_local",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Brace,
+ tokens: TokenStream(`static FOO`),
+ },
+ },
+ Stmt::Macro {
+ mac: Macro {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "println",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Paren,
+ tokens: TokenStream(`""`),
+ },
+ semi_token: Some,
+ },
+ Stmt::Expr(
+ Expr::Macro {
+ mac: Macro {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "vec",
+ },
+ ],
+ },
+ delimiter: MacroDelimiter::Bracket,
+ tokens: TokenStream(``),
+ },
+ },
+ None,
+ ),
+ ],
+ },
+ })
+ "###);
+}
+
+#[test]
+fn test_early_parse_loop() {
+ // The following is an Expr::Loop followed by Expr::Tuple. It is not an
+ // Expr::Call.
+ let tokens = quote! {
+ loop {}
+ ()
+ };
+
+ let stmts = Block::parse_within.parse2(tokens).unwrap();
+
+ snapshot!(stmts, @r###"
+ [
+ Stmt::Expr(
+ Expr::Loop {
+ body: Block {
+ stmts: [],
+ },
+ },
+ None,
+ ),
+ Stmt::Expr(
+ Expr::Tuple,
+ None,
+ ),
+ ]
+ "###);
+
+ let tokens = quote! {
+ 'a: loop {}
+ ()
+ };
+
+ let stmts = Block::parse_within.parse2(tokens).unwrap();
+
+ snapshot!(stmts, @r###"
+ [
+ Stmt::Expr(
+ Expr::Loop {
+ label: Some(Label {
+ name: Lifetime {
+ ident: "a",
+ },
+ }),
+ body: Block {
+ stmts: [],
+ },
+ },
+ None,
+ ),
+ Stmt::Expr(
+ Expr::Tuple,
+ None,
+ ),
+ ]
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_token_trees.rs b/rust/hw/char/pl011/vendor/syn/tests/test_token_trees.rs
new file mode 100644
index 0000000000..f5a067fd23
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_token_trees.rs
@@ -0,0 +1,32 @@
+#![allow(clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+use proc_macro2::TokenStream;
+use quote::quote;
+use syn::Lit;
+
+#[test]
+fn test_struct() {
+ let input = "
+ #[derive(Debug, Clone)]
+ pub struct Item {
+ pub ident: Ident,
+ pub attrs: Vec<Attribute>,
+ }
+ ";
+
+ snapshot!(input as TokenStream, @r###"
+ TokenStream(
+ `# [derive (Debug , Clone)] pub struct Item { pub ident : Ident , pub attrs : Vec < Attribute >, }`,
+ )
+ "###);
+}
+
+#[test]
+fn test_literal_mangling() {
+ let code = "0_4";
+ let parsed: Lit = syn::parse_str(code).unwrap();
+ assert_eq!(code, quote!(#parsed).to_string());
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_ty.rs b/rust/hw/char/pl011/vendor/syn/tests/test_ty.rs
new file mode 100644
index 0000000000..f1ced9ea37
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_ty.rs
@@ -0,0 +1,397 @@
+#![allow(clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
+use quote::{quote, ToTokens as _};
+use syn::punctuated::Punctuated;
+use syn::{parse_quote, token, Token, Type, TypeTuple};
+
+#[test]
+fn test_mut_self() {
+ syn::parse_str::<Type>("fn(mut self)").unwrap();
+ syn::parse_str::<Type>("fn(mut self,)").unwrap();
+ syn::parse_str::<Type>("fn(mut self: ())").unwrap();
+ syn::parse_str::<Type>("fn(mut self: ...)").unwrap_err();
+ syn::parse_str::<Type>("fn(mut self: mut self)").unwrap_err();
+ syn::parse_str::<Type>("fn(mut self::T)").unwrap_err();
+}
+
+#[test]
+fn test_macro_variable_type() {
+ // mimics the token stream corresponding to `$ty<T>`
+ let tokens = TokenStream::from_iter([
+ TokenTree::Group(Group::new(Delimiter::None, quote! { ty })),
+ TokenTree::Punct(Punct::new('<', Spacing::Alone)),
+ TokenTree::Ident(Ident::new("T", Span::call_site())),
+ TokenTree::Punct(Punct::new('>', Spacing::Alone)),
+ ]);
+
+ snapshot!(tokens as Type, @r###"
+ Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "ty",
+ arguments: PathArguments::AngleBracketed {
+ args: [
+ GenericArgument::Type(Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "T",
+ },
+ ],
+ },
+ }),
+ ],
+ },
+ },
+ ],
+ },
+ }
+ "###);
+
+ // mimics the token stream corresponding to `$ty::<T>`
+ let tokens = TokenStream::from_iter([
+ TokenTree::Group(Group::new(Delimiter::None, quote! { ty })),
+ TokenTree::Punct(Punct::new(':', Spacing::Joint)),
+ TokenTree::Punct(Punct::new(':', Spacing::Alone)),
+ TokenTree::Punct(Punct::new('<', Spacing::Alone)),
+ TokenTree::Ident(Ident::new("T", Span::call_site())),
+ TokenTree::Punct(Punct::new('>', Spacing::Alone)),
+ ]);
+
+ snapshot!(tokens as Type, @r###"
+ Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "ty",
+ arguments: PathArguments::AngleBracketed {
+ colon2_token: Some,
+ args: [
+ GenericArgument::Type(Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "T",
+ },
+ ],
+ },
+ }),
+ ],
+ },
+ },
+ ],
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_group_angle_brackets() {
+ // mimics the token stream corresponding to `Option<$ty>`
+ let tokens = TokenStream::from_iter([
+ TokenTree::Ident(Ident::new("Option", Span::call_site())),
+ TokenTree::Punct(Punct::new('<', Spacing::Alone)),
+ TokenTree::Group(Group::new(Delimiter::None, quote! { Vec<u8> })),
+ TokenTree::Punct(Punct::new('>', Spacing::Alone)),
+ ]);
+
+ snapshot!(tokens as Type, @r###"
+ Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Option",
+ arguments: PathArguments::AngleBracketed {
+ args: [
+ GenericArgument::Type(Type::Group {
+ elem: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Vec",
+ arguments: PathArguments::AngleBracketed {
+ args: [
+ GenericArgument::Type(Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "u8",
+ },
+ ],
+ },
+ }),
+ ],
+ },
+ },
+ ],
+ },
+ },
+ }),
+ ],
+ },
+ },
+ ],
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_group_colons() {
+ // mimics the token stream corresponding to `$ty::Item`
+ let tokens = TokenStream::from_iter([
+ TokenTree::Group(Group::new(Delimiter::None, quote! { Vec<u8> })),
+ TokenTree::Punct(Punct::new(':', Spacing::Joint)),
+ TokenTree::Punct(Punct::new(':', Spacing::Alone)),
+ TokenTree::Ident(Ident::new("Item", Span::call_site())),
+ ]);
+
+ snapshot!(tokens as Type, @r###"
+ Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Vec",
+ arguments: PathArguments::AngleBracketed {
+ args: [
+ GenericArgument::Type(Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "u8",
+ },
+ ],
+ },
+ }),
+ ],
+ },
+ },
+ Token![::],
+ PathSegment {
+ ident: "Item",
+ },
+ ],
+ },
+ }
+ "###);
+
+ let tokens = TokenStream::from_iter([
+ TokenTree::Group(Group::new(Delimiter::None, quote! { [T] })),
+ TokenTree::Punct(Punct::new(':', Spacing::Joint)),
+ TokenTree::Punct(Punct::new(':', Spacing::Alone)),
+ TokenTree::Ident(Ident::new("Element", Span::call_site())),
+ ]);
+
+ snapshot!(tokens as Type, @r###"
+ Type::Path {
+ qself: Some(QSelf {
+ ty: Type::Slice {
+ elem: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "T",
+ },
+ ],
+ },
+ },
+ },
+ position: 0,
+ }),
+ path: Path {
+ leading_colon: Some,
+ segments: [
+ PathSegment {
+ ident: "Element",
+ },
+ ],
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_trait_object() {
+ let tokens = quote!(dyn for<'a> Trait<'a> + 'static);
+ snapshot!(tokens as Type, @r###"
+ Type::TraitObject {
+ dyn_token: Some,
+ bounds: [
+ TypeParamBound::Trait(TraitBound {
+ lifetimes: Some(BoundLifetimes {
+ lifetimes: [
+ GenericParam::Lifetime(LifetimeParam {
+ lifetime: Lifetime {
+ ident: "a",
+ },
+ }),
+ ],
+ }),
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Trait",
+ arguments: PathArguments::AngleBracketed {
+ args: [
+ GenericArgument::Lifetime(Lifetime {
+ ident: "a",
+ }),
+ ],
+ },
+ },
+ ],
+ },
+ }),
+ Token![+],
+ TypeParamBound::Lifetime {
+ ident: "static",
+ },
+ ],
+ }
+ "###);
+
+ let tokens = quote!(dyn 'a + Trait);
+ snapshot!(tokens as Type, @r###"
+ Type::TraitObject {
+ dyn_token: Some,
+ bounds: [
+ TypeParamBound::Lifetime {
+ ident: "a",
+ },
+ Token![+],
+ TypeParamBound::Trait(TraitBound {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Trait",
+ },
+ ],
+ },
+ }),
+ ],
+ }
+ "###);
+
+ // None of the following are valid Rust types.
+ syn::parse_str::<Type>("for<'a> dyn Trait<'a>").unwrap_err();
+ syn::parse_str::<Type>("dyn for<'a> 'a + Trait").unwrap_err();
+}
+
+#[test]
+fn test_trailing_plus() {
+ #[rustfmt::skip]
+ let tokens = quote!(impl Trait +);
+ snapshot!(tokens as Type, @r###"
+ Type::ImplTrait {
+ bounds: [
+ TypeParamBound::Trait(TraitBound {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Trait",
+ },
+ ],
+ },
+ }),
+ Token![+],
+ ],
+ }
+ "###);
+
+ #[rustfmt::skip]
+ let tokens = quote!(dyn Trait +);
+ snapshot!(tokens as Type, @r###"
+ Type::TraitObject {
+ dyn_token: Some,
+ bounds: [
+ TypeParamBound::Trait(TraitBound {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Trait",
+ },
+ ],
+ },
+ }),
+ Token![+],
+ ],
+ }
+ "###);
+
+ #[rustfmt::skip]
+ let tokens = quote!(Trait +);
+ snapshot!(tokens as Type, @r###"
+ Type::TraitObject {
+ bounds: [
+ TypeParamBound::Trait(TraitBound {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "Trait",
+ },
+ ],
+ },
+ }),
+ Token![+],
+ ],
+ }
+ "###);
+}
+
+#[test]
+fn test_tuple_comma() {
+ let mut expr = TypeTuple {
+ paren_token: token::Paren::default(),
+ elems: Punctuated::new(),
+ };
+ snapshot!(expr.to_token_stream() as Type, @"Type::Tuple");
+
+ expr.elems.push_value(parse_quote!(_));
+ // Must not parse to Type::Paren
+ snapshot!(expr.to_token_stream() as Type, @r###"
+ Type::Tuple {
+ elems: [
+ Type::Infer,
+ Token![,],
+ ],
+ }
+ "###);
+
+ expr.elems.push_punct(<Token![,]>::default());
+ snapshot!(expr.to_token_stream() as Type, @r###"
+ Type::Tuple {
+ elems: [
+ Type::Infer,
+ Token![,],
+ ],
+ }
+ "###);
+
+ expr.elems.push_value(parse_quote!(_));
+ snapshot!(expr.to_token_stream() as Type, @r###"
+ Type::Tuple {
+ elems: [
+ Type::Infer,
+ Token![,],
+ Type::Infer,
+ ],
+ }
+ "###);
+
+ expr.elems.push_punct(<Token![,]>::default());
+ snapshot!(expr.to_token_stream() as Type, @r###"
+ Type::Tuple {
+ elems: [
+ Type::Infer,
+ Token![,],
+ Type::Infer,
+ Token![,],
+ ],
+ }
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/test_visibility.rs b/rust/hw/char/pl011/vendor/syn/tests/test_visibility.rs
new file mode 100644
index 0000000000..e6e8bd7291
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/test_visibility.rs
@@ -0,0 +1,185 @@
+#![allow(clippy::uninlined_format_args)]
+
+#[macro_use]
+mod macros;
+
+use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
+use quote::quote;
+use syn::parse::{Parse, ParseStream};
+use syn::{DeriveInput, Result, Visibility};
+
+#[derive(Debug)]
+struct VisRest {
+ vis: Visibility,
+ rest: TokenStream,
+}
+
+impl Parse for VisRest {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Ok(VisRest {
+ vis: input.parse()?,
+ rest: input.parse()?,
+ })
+ }
+}
+
+macro_rules! assert_vis_parse {
+ ($input:expr, Ok($p:pat)) => {
+ assert_vis_parse!($input, Ok($p) + "");
+ };
+
+ ($input:expr, Ok($p:pat) + $rest:expr) => {
+ let expected = $rest.parse::<TokenStream>().unwrap();
+ let parse: VisRest = syn::parse_str($input).unwrap();
+
+ match parse.vis {
+ $p => {}
+ _ => panic!("expected {}, got {:?}", stringify!($p), parse.vis),
+ }
+
+ // NOTE: Round-trips through `to_string` to avoid potential whitespace
+ // diffs.
+ assert_eq!(parse.rest.to_string(), expected.to_string());
+ };
+
+ ($input:expr, Err) => {
+ syn::parse2::<VisRest>($input.parse().unwrap()).unwrap_err();
+ };
+}
+
+#[test]
+fn test_pub() {
+ assert_vis_parse!("pub", Ok(Visibility::Public(_)));
+}
+
+#[test]
+fn test_inherited() {
+ assert_vis_parse!("", Ok(Visibility::Inherited));
+}
+
+#[test]
+fn test_in() {
+ assert_vis_parse!("pub(in foo::bar)", Ok(Visibility::Restricted(_)));
+}
+
+#[test]
+fn test_pub_crate() {
+ assert_vis_parse!("pub(crate)", Ok(Visibility::Restricted(_)));
+}
+
+#[test]
+fn test_pub_self() {
+ assert_vis_parse!("pub(self)", Ok(Visibility::Restricted(_)));
+}
+
+#[test]
+fn test_pub_super() {
+ assert_vis_parse!("pub(super)", Ok(Visibility::Restricted(_)));
+}
+
+#[test]
+fn test_missing_in() {
+ assert_vis_parse!("pub(foo::bar)", Ok(Visibility::Public(_)) + "(foo::bar)");
+}
+
+#[test]
+fn test_missing_in_path() {
+ assert_vis_parse!("pub(in)", Err);
+}
+
+#[test]
+fn test_crate_path() {
+ assert_vis_parse!(
+ "pub(crate::A, crate::B)",
+ Ok(Visibility::Public(_)) + "(crate::A, crate::B)"
+ );
+}
+
+#[test]
+fn test_junk_after_in() {
+ assert_vis_parse!("pub(in some::path @@garbage)", Err);
+}
+
+#[test]
+fn test_inherited_vis_named_field() {
+ // mimics `struct S { $vis $field: () }` where $vis is empty
+ let tokens = TokenStream::from_iter([
+ TokenTree::Ident(Ident::new("struct", Span::call_site())),
+ TokenTree::Ident(Ident::new("S", Span::call_site())),
+ TokenTree::Group(Group::new(
+ Delimiter::Brace,
+ TokenStream::from_iter([
+ TokenTree::Group(Group::new(Delimiter::None, TokenStream::new())),
+ TokenTree::Group(Group::new(Delimiter::None, quote!(f))),
+ TokenTree::Punct(Punct::new(':', Spacing::Alone)),
+ TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),
+ ]),
+ )),
+ ]);
+
+ snapshot!(tokens as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Inherited,
+ ident: "S",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Named {
+ named: [
+ Field {
+ vis: Visibility::Inherited,
+ ident: Some("f"),
+ colon_token: Some,
+ ty: Type::Tuple,
+ },
+ ],
+ },
+ },
+ }
+ "###);
+}
+
+#[test]
+fn test_inherited_vis_unnamed_field() {
+ // mimics `struct S($vis $ty);` where $vis is empty
+ let tokens = TokenStream::from_iter([
+ TokenTree::Ident(Ident::new("struct", Span::call_site())),
+ TokenTree::Ident(Ident::new("S", Span::call_site())),
+ TokenTree::Group(Group::new(
+ Delimiter::Parenthesis,
+ TokenStream::from_iter([
+ TokenTree::Group(Group::new(Delimiter::None, TokenStream::new())),
+ TokenTree::Group(Group::new(Delimiter::None, quote!(str))),
+ ]),
+ )),
+ TokenTree::Punct(Punct::new(';', Spacing::Alone)),
+ ]);
+
+ snapshot!(tokens as DeriveInput, @r###"
+ DeriveInput {
+ vis: Visibility::Inherited,
+ ident: "S",
+ generics: Generics,
+ data: Data::Struct {
+ fields: Fields::Unnamed {
+ unnamed: [
+ Field {
+ vis: Visibility::Inherited,
+ ty: Type::Group {
+ elem: Type::Path {
+ path: Path {
+ segments: [
+ PathSegment {
+ ident: "str",
+ },
+ ],
+ },
+ },
+ },
+ },
+ ],
+ },
+ semi_token: Some,
+ },
+ }
+ "###);
+}
diff --git a/rust/hw/char/pl011/vendor/syn/tests/zzz_stable.rs b/rust/hw/char/pl011/vendor/syn/tests/zzz_stable.rs
new file mode 100644
index 0000000000..a1a670d9ed
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/syn/tests/zzz_stable.rs
@@ -0,0 +1,33 @@
+#![cfg(syn_disable_nightly_tests)]
+
+use std::io::{self, Write};
+use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
+
+const MSG: &str = "\
+‖
+‖ WARNING:
+‖ This is not a nightly compiler so not all tests were able to
+‖ run. Syn includes tests that compare Syn's parser against the
+‖ compiler's parser, which requires access to unstable librustc
+‖ data structures and a nightly compiler.
+‖
+";
+
+#[test]
+fn notice() -> io::Result<()> {
+ let header = "WARNING";
+ let index_of_header = MSG.find(header).unwrap();
+ let before = &MSG[..index_of_header];
+ let after = &MSG[index_of_header + header.len()..];
+
+ let mut stderr = StandardStream::stderr(ColorChoice::Auto);
+ stderr.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
+ write!(&mut stderr, "{}", before)?;
+ stderr.set_color(ColorSpec::new().set_bold(true).set_fg(Some(Color::Yellow)))?;
+ write!(&mut stderr, "{}", header)?;
+ stderr.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
+ write!(&mut stderr, "{}", after)?;
+ stderr.reset()?;
+
+ Ok(())
+}
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/.cargo-checksum.json b/rust/hw/char/pl011/vendor/unicode-ident/.cargo-checksum.json
new file mode 100644
index 0000000000..9a708d8fed
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"7b10355305359d5feefb120329396a8823ce903cd66612d7d27612d51e6ceced","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","LICENSE-UNICODE":"68f5b9f5ea36881a0942ba02f558e9e1faf76cc09cb165ad801744c61b738844","README.md":"eff1f30712e93cc160101c25bf31738448c284b90636deb3e3a651cb9ad20dd1","benches/xid.rs":"a61f61ecc7d5124c759cdeb55ab74470ab69f2f3ca37613da65f16e0e5e33487","src/lib.rs":"2673969775cff349816e3fb30f62476a802523fe4940482288b75bd747cbe748","src/tables.rs":"ffe8e252eabccf261385865cb781b3d76c9f32f6f9503d00196a30fb92d80b29","tests/compare.rs":"62471ffb157744cac6faae1adafdbdf785349d7eb6dc2ff4b4941c9d618397f9","tests/fst/mod.rs":"69a3aaf59acd8bca962ecc6234be56be8c0934ab79b253162f10eb881523901f","tests/fst/xid_continue.fst":"41fc751514b8bde658544d5fe7e100115d299d41897af855934b9f4ebda9d3a2","tests/fst/xid_start.fst":"ffa5e2bfe7dd5f6738fbe4b7a3e6e2083c9777191c54f8291a80d558ec4e2dd2","tests/roaring/mod.rs":"784f65a48477fab7549620c7843c7ad6da533f69a18abca1172f6acb95045e53","tests/static_size.rs":"4524332c1e424cb987d7cee1f47a98aea9ed7b256303a3828eda5aa1d06da240","tests/tables/mod.rs":"e6949172d10fc4b2431ce7546269bfd4f9146454c8c3e31faf5e5d80c16a8ab6","tests/tables/tables.rs":"011404dab8a3958da6e18a1fe9406c191675e6f49bf30ce813e3d05f582e750b","tests/trie/mod.rs":"d4acbb716bcbaf80660039797f45e138ed8bbd66749fa3b19b1a971574679cc9","tests/trie/trie.rs":"3c1ca56062f1b3ffdf2ae2063d3fee8d362b90082778056181b5c95e2e242ad8"},"package":"3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/Cargo.toml b/rust/hw/char/pl011/vendor/unicode-ident/Cargo.toml
new file mode 100644
index 0000000000..1c40dde818
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/Cargo.toml
@@ -0,0 +1,63 @@
+# 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 = "2018"
+rust-version = "1.31"
+name = "unicode-ident"
+version = "1.0.12"
+authors = ["David Tolnay <dtolnay@gmail.com>"]
+description = "Determine whether characters have the XID_Start or XID_Continue properties according to Unicode Standard Annex #31"
+documentation = "https://docs.rs/unicode-ident"
+readme = "README.md"
+keywords = [
+ "unicode",
+ "xid",
+]
+categories = [
+ "development-tools::procedural-macro-helpers",
+ "no-std",
+ "no-std::no-alloc",
+]
+license = "(MIT OR Apache-2.0) AND Unicode-DFS-2016"
+repository = "https://github.com/dtolnay/unicode-ident"
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--generate-link-to-definition"]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+doc-scrape-examples = false
+
+[[bench]]
+name = "xid"
+harness = false
+
+[dev-dependencies.criterion]
+version = "0.5"
+default-features = false
+
+[dev-dependencies.fst]
+version = "0.4"
+
+[dev-dependencies.rand]
+version = "0.8"
+features = ["small_rng"]
+
+[dev-dependencies.roaring]
+version = "0.10"
+
+[dev-dependencies.ucd-trie]
+version = "0.1"
+default-features = false
+
+[dev-dependencies.unicode-xid]
+version = "0.2.4"
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/LICENSE-APACHE b/rust/hw/char/pl011/vendor/unicode-ident/LICENSE-APACHE
new file mode 100644
index 0000000000..1b5ec8b78e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/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/rust/hw/char/pl011/vendor/unicode-ident/LICENSE-MIT b/rust/hw/char/pl011/vendor/unicode-ident/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/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/rust/hw/char/pl011/vendor/unicode-ident/LICENSE-UNICODE b/rust/hw/char/pl011/vendor/unicode-ident/LICENSE-UNICODE
new file mode 100644
index 0000000000..85d0d580d2
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/LICENSE-UNICODE
@@ -0,0 +1,46 @@
+UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
+
+See Terms of Use <https://www.unicode.org/copyright.html>
+for definitions of Unicode Inc.’s Data Files and Software.
+
+NOTICE TO USER: Carefully read the following legal agreement.
+BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
+DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
+YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
+TERMS AND CONDITIONS OF THIS AGREEMENT.
+IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
+THE DATA FILES OR SOFTWARE.
+
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright © 1991-2022 Unicode, Inc. All rights reserved.
+Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Unicode data files and any associated documentation
+(the "Data Files") or Unicode software and any associated documentation
+(the "Software") to deal in the Data Files or Software
+without restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, and/or sell copies of
+the Data Files or Software, and to permit persons to whom the Data Files
+or Software are furnished to do so, provided that either
+(a) this copyright and permission notice appear with all copies
+of the Data Files or Software, or
+(b) this copyright and permission notice appear in associated
+Documentation.
+
+THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
+NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
+DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THE DATA FILES OR SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale,
+use or other dealings in these Data Files or Software without prior
+written authorization of the copyright holder.
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/README.md b/rust/hw/char/pl011/vendor/unicode-ident/README.md
new file mode 100644
index 0000000000..0e9af827f6
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/README.md
@@ -0,0 +1,283 @@
+Unicode ident
+=============
+
+[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/unicode--ident-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/unicode-ident)
+[<img alt="crates.io" src="https://img.shields.io/crates/v/unicode-ident.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/unicode-ident)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-unicode--ident-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/unicode-ident)
+[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/unicode-ident/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/unicode-ident/actions?query=branch%3Amaster)
+
+Implementation of [Unicode Standard Annex #31][tr31] for determining which
+`char` values are valid in programming language identifiers.
+
+[tr31]: https://www.unicode.org/reports/tr31/
+
+This crate is a better optimized implementation of the older `unicode-xid`
+crate. This crate uses less static storage, and is able to classify both ASCII
+and non-ASCII codepoints with better performance, 2–10× faster than
+`unicode-xid`.
+
+<br>
+
+## Comparison of performance
+
+The following table shows a comparison between five Unicode identifier
+implementations.
+
+- `unicode-ident` is this crate;
+- [`unicode-xid`] is a widely used crate run by the "unicode-rs" org;
+- `ucd-trie` and `fst` are two data structures supported by the [`ucd-generate`] tool;
+- [`roaring`] is a Rust implementation of Roaring bitmap.
+
+The *static storage* column shows the total size of `static` tables that the
+crate bakes into your binary, measured in 1000s of bytes.
+
+The remaining columns show the **cost per call** to evaluate whether a single
+`char` has the XID\_Start or XID\_Continue Unicode property, comparing across
+different ratios of ASCII to non-ASCII codepoints in the input data.
+
+[`unicode-xid`]: https://github.com/unicode-rs/unicode-xid
+[`ucd-generate`]: https://github.com/BurntSushi/ucd-generate
+[`roaring`]: https://github.com/RoaringBitmap/roaring-rs
+
+| | static storage | 0% nonascii | 1% | 10% | 100% nonascii |
+|---|---|---|---|---|---|
+| **`unicode-ident`** | 10.1 K | 0.96 ns | 0.95 ns | 1.09 ns | 1.55 ns |
+| **`unicode-xid`** | 11.5 K | 1.88 ns | 2.14 ns | 3.48 ns | 15.63 ns |
+| **`ucd-trie`** | 10.2 K | 1.29 ns | 1.28 ns | 1.36 ns | 2.15 ns |
+| **`fst`** | 139 K | 55.1 ns | 54.9 ns | 53.2 ns | 28.5 ns |
+| **`roaring`** | 66.1 K | 2.78 ns | 3.09 ns | 3.37 ns | 4.70 ns |
+
+Source code for the benchmark is provided in the *bench* directory of this repo
+and may be repeated by running `cargo criterion`.
+
+<br>
+
+## Comparison of data structures
+
+#### unicode-xid
+
+They use a sorted array of character ranges, and do a binary search to look up
+whether a given character lands inside one of those ranges.
+
+```rust
+static XID_Continue_table: [(char, char); 763] = [
+ ('\u{30}', '\u{39}'), // 0-9
+ ('\u{41}', '\u{5a}'), // A-Z
+ …
+ ('\u{e0100}', '\u{e01ef}'),
+];
+```
+
+The static storage used by this data structure scales with the number of
+contiguous ranges of identifier codepoints in Unicode. Every table entry
+consumes 8 bytes, because it consists of a pair of 32-bit `char` values.
+
+In some ranges of the Unicode codepoint space, this is quite a sparse
+representation – there are some ranges where tens of thousands of adjacent
+codepoints are all valid identifier characters. In other places, the
+representation is quite inefficient. A characater like `µ` (U+00B5) which is
+surrounded by non-identifier codepoints consumes 64 bits in the table, while it
+would be just 1 bit in a dense bitmap.
+
+On a system with 64-byte cache lines, binary searching the table touches 7 cache
+lines on average. Each cache line fits only 8 table entries. Additionally, the
+branching performed during the binary search is probably mostly unpredictable to
+the branch predictor.
+
+Overall, the crate ends up being about 10× slower on non-ASCII input
+compared to the fastest crate.
+
+A potential improvement would be to pack the table entries more compactly.
+Rust's `char` type is a 21-bit integer padded to 32 bits, which means every
+table entry is holding 22 bits of wasted space, adding up to 3.9 K. They could
+instead fit every table entry into 6 bytes, leaving out some of the padding, for
+a 25% improvement in space used. With some cleverness it may be possible to fit
+in 5 bytes or even 4 bytes by storing a low char and an extent, instead of low
+char and high char. I don't expect that performance would improve much but this
+could be the most efficient for space across all the libraries, needing only
+about 7 K to store.
+
+#### ucd-trie
+
+Their data structure is a compressed trie set specifically tailored for Unicode
+codepoints. The design is credited to Raph Levien in [rust-lang/rust#33098].
+
+[rust-lang/rust#33098]: https://github.com/rust-lang/rust/pull/33098
+
+```rust
+pub struct TrieSet {
+ tree1_level1: &'static [u64; 32],
+ tree2_level1: &'static [u8; 992],
+ tree2_level2: &'static [u64],
+ tree3_level1: &'static [u8; 256],
+ tree3_level2: &'static [u8],
+ tree3_level3: &'static [u64],
+}
+```
+
+It represents codepoint sets using a trie to achieve prefix compression. The
+final states of the trie are embedded in leaves or "chunks", where each chunk is
+a 64-bit integer. Each bit position of the integer corresponds to whether a
+particular codepoint is in the set or not. These chunks are not just a compact
+representation of the final states of the trie, but are also a form of suffix
+compression. In particular, if multiple ranges of 64 contiguous codepoints have
+the same Unicode properties, then they all map to the same chunk in the final
+level of the trie.
+
+Being tailored for Unicode codepoints, this trie is partitioned into three
+disjoint sets: tree1, tree2, tree3. The first set corresponds to codepoints \[0,
+0x800), the second \[0x800, 0x10000) and the third \[0x10000, 0x110000). These
+partitions conveniently correspond to the space of 1 or 2 byte UTF-8 encoded
+codepoints, 3 byte UTF-8 encoded codepoints and 4 byte UTF-8 encoded codepoints,
+respectively.
+
+Lookups in this data structure are significantly more efficient than binary
+search. A lookup touches either 1, 2, or 3 cache lines based on which of the
+trie partitions is being accessed.
+
+One possible performance improvement would be for this crate to expose a way to
+query based on a UTF-8 encoded string, returning the Unicode property
+corresponding to the first character in the string. Without such an API, the
+caller is required to tokenize their UTF-8 encoded input data into `char`, hand
+the `char` into `ucd-trie`, only for `ucd-trie` to undo that work by converting
+back into the variable-length representation for trie traversal.
+
+#### fst
+
+Uses a [finite state transducer][fst]. This representation is built into
+[ucd-generate] but I am not aware of any advantage over the `ucd-trie`
+representation. In particular `ucd-trie` is optimized for storing Unicode
+properties while `fst` is not.
+
+[fst]: https://github.com/BurntSushi/fst
+[ucd-generate]: https://github.com/BurntSushi/ucd-generate
+
+As far as I can tell, the main thing that causes `fst` to have large size and
+slow lookups for this use case relative to `ucd-trie` is that it does not
+specialize for the fact that only 21 of the 32 bits in a `char` are meaningful.
+There are some dense arrays in the structure with large ranges that could never
+possibly be used.
+
+#### roaring
+
+This crate is a pure-Rust implementation of [Roaring Bitmap], a data structure
+designed for storing sets of 32-bit unsigned integers.
+
+[Roaring Bitmap]: https://roaringbitmap.org/about/
+
+Roaring bitmaps are compressed bitmaps which tend to outperform conventional
+compressed bitmaps such as WAH, EWAH or Concise. In some instances, they can be
+hundreds of times faster and they often offer significantly better compression.
+
+In this use case the performance was reasonably competitive but still
+substantially slower than the Unicode-optimized crates. Meanwhile the
+compression was significantly worse, requiring 6× as much storage for the
+data structure.
+
+I also benchmarked the [`croaring`] crate which is an FFI wrapper around the C
+reference implementation of Roaring Bitmap. This crate was consistently about
+15% slower than pure-Rust `roaring`, which could just be FFI overhead. I did not
+investigate further.
+
+[`croaring`]: https://crates.io/crates/croaring
+
+#### unicode-ident
+
+This crate is most similar to the `ucd-trie` library, in that it's based on
+bitmaps stored in the leafs of a trie representation, achieving both prefix
+compression and suffix compression.
+
+The key differences are:
+
+- Uses a single 2-level trie, rather than 3 disjoint partitions of different
+ depth each.
+- Uses significantly larger chunks: 512 bits rather than 64 bits.
+- Compresses the XID\_Start and XID\_Continue properties together
+ simultaneously, rather than duplicating identical trie leaf chunks across the
+ two.
+
+The following diagram show the XID\_Start and XID\_Continue Unicode boolean
+properties in uncompressed form, in row-major order:
+
+<table>
+<tr><th>XID_Start</th><th>XID_Continue</th></tr>
+<tr>
+<td><img alt="XID_Start bitmap" width="256" src="https://user-images.githubusercontent.com/1940490/168647353-c6eeb922-afec-49b2-9ef5-c03e9d1e0760.png"></td>
+<td><img alt="XID_Continue bitmap" width="256" src="https://user-images.githubusercontent.com/1940490/168647367-f447cca7-2362-4d7d-8cd7-d21c011d329b.png"></td>
+</tr>
+</table>
+
+Uncompressed, these would take 140 K to store, which is beyond what would be
+reasonable. However, as you can see there is a large degree of similarity
+between the two bitmaps and across the rows, which lends well to compression.
+
+This crate stores one 512-bit "row" of the above bitmaps in the leaf level of a
+trie, and a single additional level to index into the leafs. It turns out there
+are 124 unique 512-bit chunks across the two bitmaps so 7 bits are sufficient to
+index them.
+
+The chunk size of 512 bits is selected as the size that minimizes the total size
+of the data structure. A smaller chunk, like 256 or 128 bits, would achieve
+better deduplication but require a larger index. A larger chunk would increase
+redundancy in the leaf bitmaps. 512 bit chunks are the optimum for total size of
+the index plus leaf bitmaps.
+
+In fact since there are only 124 unique chunks, we can use an 8-bit index with a
+spare bit to index at the half-chunk level. This achieves an additional 8.5%
+compression by eliminating redundancies between the second half of any chunk and
+the first half of any other chunk. Note that this is not the same as using
+chunks which are half the size, because it does not necessitate raising the size
+of the trie's first level.
+
+In contrast to binary search or the `ucd-trie` crate, performing lookups in this
+data structure is straight-line code with no need for branching.
+
+```asm
+is_xid_start:
+ mov eax, edi
+ shr eax, 9
+ lea rcx, [rip + unicode_ident::tables::TRIE_START]
+ add rcx, rax
+ xor eax, eax
+ cmp edi, 201728
+ cmovb rax, rcx
+ test rax, rax
+ lea rcx, [rip + .L__unnamed_1]
+ cmovne rcx, rax
+ movzx eax, byte ptr [rcx]
+ shl rax, 5
+ mov ecx, edi
+ shr ecx, 3
+ and ecx, 63
+ add rcx, rax
+ lea rax, [rip + unicode_ident::tables::LEAF]
+ mov al, byte ptr [rax + rcx]
+ and dil, 7
+ mov ecx, edi
+ shr al, cl
+ and al, 1
+ ret
+```
+
+<br>
+
+## License
+
+Use of the Unicode Character Database, as this crate does, is governed by the <a
+href="LICENSE-UNICODE">Unicode License Agreement – Data Files and Software
+(2016)</a>.
+
+All intellectual property within this crate that is **not generated** using the
+Unicode Character Database as input is licensed under either of <a
+href="LICENSE-APACHE">Apache License, Version 2.0</a> or <a
+href="LICENSE-MIT">MIT license</a> at your option.
+
+The **generated** files incorporate tabular data derived from the Unicode
+Character Database, together with intellectual property from the original source
+code content of the crate. One must comply with the terms of both the Unicode
+License Agreement and either of the Apache license or MIT license when those
+generated files are involved.
+
+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 licensed as just described, without any additional terms or conditions.
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/benches/xid.rs b/rust/hw/char/pl011/vendor/unicode-ident/benches/xid.rs
new file mode 100644
index 0000000000..040c4e1818
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/benches/xid.rs
@@ -0,0 +1,124 @@
+// To run:
+//
+// cargo criterion --features criterion/real_blackbox
+//
+// This benchmarks each of the different libraries at several ratios of ASCII to
+// non-ASCII content. There is one additional benchmark labeled "baseline" which
+// just iterates over characters in a string, converting UTF-8 to 32-bit chars.
+//
+// Criterion will show a time in milliseconds. The non-baseline bench functions
+// each make one million function calls (2 calls per character, 500K characters
+// in the strings created by gen_string). The "time per call" listed in our
+// readme is computed by subtracting this baseline from the other bench
+// functions' time, then dividing by one million (ms -> ns).
+
+#![allow(clippy::needless_pass_by_value)]
+
+#[path = "../tests/fst/mod.rs"]
+mod fst;
+#[path = "../tests/roaring/mod.rs"]
+mod roaring;
+#[path = "../tests/trie/mod.rs"]
+mod trie;
+
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use rand::distributions::{Bernoulli, Distribution, Uniform};
+use rand::rngs::SmallRng;
+use rand::SeedableRng;
+use std::time::Duration;
+
+fn gen_string(p_nonascii: u32) -> String {
+ let mut rng = SmallRng::from_seed([b'!'; 32]);
+ let pick_nonascii = Bernoulli::from_ratio(p_nonascii, 100).unwrap();
+ let ascii = Uniform::new_inclusive('\0', '\x7f');
+ let nonascii = Uniform::new_inclusive(0x80 as char, char::MAX);
+
+ let mut string = String::new();
+ for _ in 0..500_000 {
+ let distribution = if pick_nonascii.sample(&mut rng) {
+ nonascii
+ } else {
+ ascii
+ };
+ string.push(distribution.sample(&mut rng));
+ }
+
+ string
+}
+
+fn bench(c: &mut Criterion, group_name: &str, string: String) {
+ let mut group = c.benchmark_group(group_name);
+ group.measurement_time(Duration::from_secs(10));
+ group.bench_function("baseline", |b| {
+ b.iter(|| {
+ for ch in string.chars() {
+ black_box(ch);
+ }
+ });
+ });
+ group.bench_function("unicode-ident", |b| {
+ b.iter(|| {
+ for ch in string.chars() {
+ black_box(unicode_ident::is_xid_start(ch));
+ black_box(unicode_ident::is_xid_continue(ch));
+ }
+ });
+ });
+ group.bench_function("unicode-xid", |b| {
+ b.iter(|| {
+ for ch in string.chars() {
+ black_box(unicode_xid::UnicodeXID::is_xid_start(ch));
+ black_box(unicode_xid::UnicodeXID::is_xid_continue(ch));
+ }
+ });
+ });
+ group.bench_function("ucd-trie", |b| {
+ b.iter(|| {
+ for ch in string.chars() {
+ black_box(trie::XID_START.contains_char(ch));
+ black_box(trie::XID_CONTINUE.contains_char(ch));
+ }
+ });
+ });
+ group.bench_function("fst", |b| {
+ let xid_start_fst = fst::xid_start_fst();
+ let xid_continue_fst = fst::xid_continue_fst();
+ b.iter(|| {
+ for ch in string.chars() {
+ let ch_bytes = (ch as u32).to_be_bytes();
+ black_box(xid_start_fst.contains(ch_bytes));
+ black_box(xid_continue_fst.contains(ch_bytes));
+ }
+ });
+ });
+ group.bench_function("roaring", |b| {
+ let xid_start_bitmap = roaring::xid_start_bitmap();
+ let xid_continue_bitmap = roaring::xid_continue_bitmap();
+ b.iter(|| {
+ for ch in string.chars() {
+ black_box(xid_start_bitmap.contains(ch as u32));
+ black_box(xid_continue_bitmap.contains(ch as u32));
+ }
+ });
+ });
+ group.finish();
+}
+
+fn bench0(c: &mut Criterion) {
+ bench(c, "0%-nonascii", gen_string(0));
+}
+
+fn bench1(c: &mut Criterion) {
+ bench(c, "1%-nonascii", gen_string(1));
+}
+
+fn bench10(c: &mut Criterion) {
+ bench(c, "10%-nonascii", gen_string(10));
+}
+
+fn bench100(c: &mut Criterion) {
+ bench(c, "100%-nonascii", gen_string(100));
+}
+
+criterion_group!(benches, bench0, bench1, bench10, bench100);
+criterion_main!(benches);
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/meson.build b/rust/hw/char/pl011/vendor/unicode-ident/meson.build
new file mode 100644
index 0000000000..86b51af097
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/meson.build
@@ -0,0 +1,14 @@
+_unicode_ident_rs = static_library(
+ 'unicode_ident',
+ files('src/lib.rs'),
+ gnu_symbol_visibility: 'hidden',
+ rust_abi: 'rust',
+ rust_args: rust_args + [
+ '--edition', '2021',
+ ],
+ dependencies: [],
+)
+
+dep_unicode_ident = declare_dependency(
+ link_with: _unicode_ident_rs,
+)
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/src/lib.rs b/rust/hw/char/pl011/vendor/unicode-ident/src/lib.rs
new file mode 100644
index 0000000000..f8908866e6
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/src/lib.rs
@@ -0,0 +1,269 @@
+//! [![github]](https://github.com/dtolnay/unicode-ident) [![crates-io]](https://crates.io/crates/unicode-ident) [![docs-rs]](https://docs.rs/unicode-ident)
+//!
+//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
+//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
+//!
+//! <br>
+//!
+//! Implementation of [Unicode Standard Annex #31][tr31] for determining which
+//! `char` values are valid in programming language identifiers.
+//!
+//! [tr31]: https://www.unicode.org/reports/tr31/
+//!
+//! This crate is a better optimized implementation of the older `unicode-xid`
+//! crate. This crate uses less static storage, and is able to classify both
+//! ASCII and non-ASCII codepoints with better performance, 2–10×
+//! faster than `unicode-xid`.
+//!
+//! <br>
+//!
+//! ## Comparison of performance
+//!
+//! The following table shows a comparison between five Unicode identifier
+//! implementations.
+//!
+//! - `unicode-ident` is this crate;
+//! - [`unicode-xid`] is a widely used crate run by the "unicode-rs" org;
+//! - `ucd-trie` and `fst` are two data structures supported by the
+//! [`ucd-generate`] tool;
+//! - [`roaring`] is a Rust implementation of Roaring bitmap.
+//!
+//! The *static storage* column shows the total size of `static` tables that the
+//! crate bakes into your binary, measured in 1000s of bytes.
+//!
+//! The remaining columns show the **cost per call** to evaluate whether a
+//! single `char` has the XID\_Start or XID\_Continue Unicode property,
+//! comparing across different ratios of ASCII to non-ASCII codepoints in the
+//! input data.
+//!
+//! [`unicode-xid`]: https://github.com/unicode-rs/unicode-xid
+//! [`ucd-generate`]: https://github.com/BurntSushi/ucd-generate
+//! [`roaring`]: https://github.com/RoaringBitmap/roaring-rs
+//!
+//! | | static storage | 0% nonascii | 1% | 10% | 100% nonascii |
+//! |---|---|---|---|---|---|
+//! | **`unicode-ident`** | 10.1 K | 0.96 ns | 0.95 ns | 1.09 ns | 1.55 ns |
+//! | **`unicode-xid`** | 11.5 K | 1.88 ns | 2.14 ns | 3.48 ns | 15.63 ns |
+//! | **`ucd-trie`** | 10.2 K | 1.29 ns | 1.28 ns | 1.36 ns | 2.15 ns |
+//! | **`fst`** | 139 K | 55.1 ns | 54.9 ns | 53.2 ns | 28.5 ns |
+//! | **`roaring`** | 66.1 K | 2.78 ns | 3.09 ns | 3.37 ns | 4.70 ns |
+//!
+//! Source code for the benchmark is provided in the *bench* directory of this
+//! repo and may be repeated by running `cargo criterion`.
+//!
+//! <br>
+//!
+//! ## Comparison of data structures
+//!
+//! #### unicode-xid
+//!
+//! They use a sorted array of character ranges, and do a binary search to look
+//! up whether a given character lands inside one of those ranges.
+//!
+//! ```rust
+//! # const _: &str = stringify! {
+//! static XID_Continue_table: [(char, char); 763] = [
+//! ('\u{30}', '\u{39}'), // 0-9
+//! ('\u{41}', '\u{5a}'), // A-Z
+//! # "
+//! …
+//! # "
+//! ('\u{e0100}', '\u{e01ef}'),
+//! ];
+//! # };
+//! ```
+//!
+//! The static storage used by this data structure scales with the number of
+//! contiguous ranges of identifier codepoints in Unicode. Every table entry
+//! consumes 8 bytes, because it consists of a pair of 32-bit `char` values.
+//!
+//! In some ranges of the Unicode codepoint space, this is quite a sparse
+//! representation – there are some ranges where tens of thousands of
+//! adjacent codepoints are all valid identifier characters. In other places,
+//! the representation is quite inefficient. A characater like `µ` (U+00B5)
+//! which is surrounded by non-identifier codepoints consumes 64 bits in the
+//! table, while it would be just 1 bit in a dense bitmap.
+//!
+//! On a system with 64-byte cache lines, binary searching the table touches 7
+//! cache lines on average. Each cache line fits only 8 table entries.
+//! Additionally, the branching performed during the binary search is probably
+//! mostly unpredictable to the branch predictor.
+//!
+//! Overall, the crate ends up being about 10× slower on non-ASCII input
+//! compared to the fastest crate.
+//!
+//! A potential improvement would be to pack the table entries more compactly.
+//! Rust's `char` type is a 21-bit integer padded to 32 bits, which means every
+//! table entry is holding 22 bits of wasted space, adding up to 3.9 K. They
+//! could instead fit every table entry into 6 bytes, leaving out some of the
+//! padding, for a 25% improvement in space used. With some cleverness it may be
+//! possible to fit in 5 bytes or even 4 bytes by storing a low char and an
+//! extent, instead of low char and high char. I don't expect that performance
+//! would improve much but this could be the most efficient for space across all
+//! the libraries, needing only about 7 K to store.
+//!
+//! #### ucd-trie
+//!
+//! Their data structure is a compressed trie set specifically tailored for
+//! Unicode codepoints. The design is credited to Raph Levien in
+//! [rust-lang/rust#33098].
+//!
+//! [rust-lang/rust#33098]: https://github.com/rust-lang/rust/pull/33098
+//!
+//! ```rust
+//! pub struct TrieSet {
+//! tree1_level1: &'static [u64; 32],
+//! tree2_level1: &'static [u8; 992],
+//! tree2_level2: &'static [u64],
+//! tree3_level1: &'static [u8; 256],
+//! tree3_level2: &'static [u8],
+//! tree3_level3: &'static [u64],
+//! }
+//! ```
+//!
+//! It represents codepoint sets using a trie to achieve prefix compression. The
+//! final states of the trie are embedded in leaves or "chunks", where each
+//! chunk is a 64-bit integer. Each bit position of the integer corresponds to
+//! whether a particular codepoint is in the set or not. These chunks are not
+//! just a compact representation of the final states of the trie, but are also
+//! a form of suffix compression. In particular, if multiple ranges of 64
+//! contiguous codepoints have the same Unicode properties, then they all map to
+//! the same chunk in the final level of the trie.
+//!
+//! Being tailored for Unicode codepoints, this trie is partitioned into three
+//! disjoint sets: tree1, tree2, tree3. The first set corresponds to codepoints
+//! \[0, 0x800), the second \[0x800, 0x10000) and the third \[0x10000,
+//! 0x110000). These partitions conveniently correspond to the space of 1 or 2
+//! byte UTF-8 encoded codepoints, 3 byte UTF-8 encoded codepoints and 4 byte
+//! UTF-8 encoded codepoints, respectively.
+//!
+//! Lookups in this data structure are significantly more efficient than binary
+//! search. A lookup touches either 1, 2, or 3 cache lines based on which of the
+//! trie partitions is being accessed.
+//!
+//! One possible performance improvement would be for this crate to expose a way
+//! to query based on a UTF-8 encoded string, returning the Unicode property
+//! corresponding to the first character in the string. Without such an API, the
+//! caller is required to tokenize their UTF-8 encoded input data into `char`,
+//! hand the `char` into `ucd-trie`, only for `ucd-trie` to undo that work by
+//! converting back into the variable-length representation for trie traversal.
+//!
+//! #### fst
+//!
+//! Uses a [finite state transducer][fst]. This representation is built into
+//! [ucd-generate] but I am not aware of any advantage over the `ucd-trie`
+//! representation. In particular `ucd-trie` is optimized for storing Unicode
+//! properties while `fst` is not.
+//!
+//! [fst]: https://github.com/BurntSushi/fst
+//! [ucd-generate]: https://github.com/BurntSushi/ucd-generate
+//!
+//! As far as I can tell, the main thing that causes `fst` to have large size
+//! and slow lookups for this use case relative to `ucd-trie` is that it does
+//! not specialize for the fact that only 21 of the 32 bits in a `char` are
+//! meaningful. There are some dense arrays in the structure with large ranges
+//! that could never possibly be used.
+//!
+//! #### roaring
+//!
+//! This crate is a pure-Rust implementation of [Roaring Bitmap], a data
+//! structure designed for storing sets of 32-bit unsigned integers.
+//!
+//! [Roaring Bitmap]: https://roaringbitmap.org/about/
+//!
+//! Roaring bitmaps are compressed bitmaps which tend to outperform conventional
+//! compressed bitmaps such as WAH, EWAH or Concise. In some instances, they can
+//! be hundreds of times faster and they often offer significantly better
+//! compression.
+//!
+//! In this use case the performance was reasonably competitive but still
+//! substantially slower than the Unicode-optimized crates. Meanwhile the
+//! compression was significantly worse, requiring 6× as much storage for
+//! the data structure.
+//!
+//! I also benchmarked the [`croaring`] crate which is an FFI wrapper around the
+//! C reference implementation of Roaring Bitmap. This crate was consistently
+//! about 15% slower than pure-Rust `roaring`, which could just be FFI overhead.
+//! I did not investigate further.
+//!
+//! [`croaring`]: https://crates.io/crates/croaring
+//!
+//! #### unicode-ident
+//!
+//! This crate is most similar to the `ucd-trie` library, in that it's based on
+//! bitmaps stored in the leafs of a trie representation, achieving both prefix
+//! compression and suffix compression.
+//!
+//! The key differences are:
+//!
+//! - Uses a single 2-level trie, rather than 3 disjoint partitions of different
+//! depth each.
+//! - Uses significantly larger chunks: 512 bits rather than 64 bits.
+//! - Compresses the XID\_Start and XID\_Continue properties together
+//! simultaneously, rather than duplicating identical trie leaf chunks across
+//! the two.
+//!
+//! The following diagram show the XID\_Start and XID\_Continue Unicode boolean
+//! properties in uncompressed form, in row-major order:
+//!
+//! <table>
+//! <tr><th>XID_Start</th><th>XID_Continue</th></tr>
+//! <tr>
+//! <td><img alt="XID_Start bitmap" width="256" src="https://user-images.githubusercontent.com/1940490/168647353-c6eeb922-afec-49b2-9ef5-c03e9d1e0760.png"></td>
+//! <td><img alt="XID_Continue bitmap" width="256" src="https://user-images.githubusercontent.com/1940490/168647367-f447cca7-2362-4d7d-8cd7-d21c011d329b.png"></td>
+//! </tr>
+//! </table>
+//!
+//! Uncompressed, these would take 140 K to store, which is beyond what would be
+//! reasonable. However, as you can see there is a large degree of similarity
+//! between the two bitmaps and across the rows, which lends well to
+//! compression.
+//!
+//! This crate stores one 512-bit "row" of the above bitmaps in the leaf level
+//! of a trie, and a single additional level to index into the leafs. It turns
+//! out there are 124 unique 512-bit chunks across the two bitmaps so 7 bits are
+//! sufficient to index them.
+//!
+//! The chunk size of 512 bits is selected as the size that minimizes the total
+//! size of the data structure. A smaller chunk, like 256 or 128 bits, would
+//! achieve better deduplication but require a larger index. A larger chunk
+//! would increase redundancy in the leaf bitmaps. 512 bit chunks are the
+//! optimum for total size of the index plus leaf bitmaps.
+//!
+//! In fact since there are only 124 unique chunks, we can use an 8-bit index
+//! with a spare bit to index at the half-chunk level. This achieves an
+//! additional 8.5% compression by eliminating redundancies between the second
+//! half of any chunk and the first half of any other chunk. Note that this is
+//! not the same as using chunks which are half the size, because it does not
+//! necessitate raising the size of the trie's first level.
+//!
+//! In contrast to binary search or the `ucd-trie` crate, performing lookups in
+//! this data structure is straight-line code with no need for branching.
+
+#![no_std]
+#![doc(html_root_url = "https://docs.rs/unicode-ident/1.0.12")]
+#![allow(clippy::doc_markdown, clippy::must_use_candidate)]
+
+#[rustfmt::skip]
+mod tables;
+
+use crate::tables::{ASCII_CONTINUE, ASCII_START, CHUNK, LEAF, TRIE_CONTINUE, TRIE_START};
+
+pub fn is_xid_start(ch: char) -> bool {
+ if ch.is_ascii() {
+ return ASCII_START.0[ch as usize];
+ }
+ let chunk = *TRIE_START.0.get(ch as usize / 8 / CHUNK).unwrap_or(&0);
+ let offset = chunk as usize * CHUNK / 2 + ch as usize / 8 % CHUNK;
+ unsafe { LEAF.0.get_unchecked(offset) }.wrapping_shr(ch as u32 % 8) & 1 != 0
+}
+
+pub fn is_xid_continue(ch: char) -> bool {
+ if ch.is_ascii() {
+ return ASCII_CONTINUE.0[ch as usize];
+ }
+ let chunk = *TRIE_CONTINUE.0.get(ch as usize / 8 / CHUNK).unwrap_or(&0);
+ let offset = chunk as usize * CHUNK / 2 + ch as usize / 8 % CHUNK;
+ unsafe { LEAF.0.get_unchecked(offset) }.wrapping_shr(ch as u32 % 8) & 1 != 0
+}
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/src/tables.rs b/rust/hw/char/pl011/vendor/unicode-ident/src/tables.rs
new file mode 100644
index 0000000000..bb691b5e9c
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/src/tables.rs
@@ -0,0 +1,651 @@
+// @generated by ../generate. To regenerate, run the following in the repo root:
+//
+// $ curl -LO https://www.unicode.org/Public/zipped/15.0.0/UCD.zip
+// $ unzip UCD.zip -d UCD
+// $ cargo run --manifest-path generate/Cargo.toml
+
+const T: bool = true;
+const F: bool = false;
+
+#[repr(C, align(8))]
+pub(crate) struct Align8<T>(pub(crate) T);
+#[repr(C, align(64))]
+pub(crate) struct Align64<T>(pub(crate) T);
+
+pub(crate) static ASCII_START: Align64<[bool; 128]> = Align64([
+ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ F, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, F, F, F, F,
+ F, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, F, F, F, F,
+]);
+
+pub(crate) static ASCII_CONTINUE: Align64<[bool; 128]> = Align64([
+ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, T, T, T, T, T, T, T, T, T, T, F, F, F, F, F, F,
+ F, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, F, F, F, T,
+ F, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, F, F, F, F,
+]);
+
+pub(crate) const CHUNK: usize = 64;
+
+pub(crate) static TRIE_START: Align8<[u8; 402]> = Align8([
+ 0x04, 0x0B, 0x0F, 0x13, 0x17, 0x1B, 0x1F, 0x23, 0x27, 0x2D, 0x31, 0x34, 0x38, 0x3C, 0x40, 0x02,
+ 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x00, 0x4D, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x51, 0x54, 0x58, 0x5C, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x60, 0x64, 0x66,
+ 0x6A, 0x6E, 0x72, 0x28, 0x76, 0x78, 0x7C, 0x80, 0x84, 0x88, 0x8C, 0x90, 0x94, 0x98, 0x9E, 0xA2,
+ 0x05, 0x2B, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x99, 0x05, 0x05, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0xB1, 0x00, 0xB5, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x32, 0x05, 0x05, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x43, 0xBB, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC8, 0x00, 0x00, 0x00, 0xAF,
+ 0xCE, 0xD2, 0xD6, 0xBC, 0xDA, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0xE0, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x52, 0xE3, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE6, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0xE1, 0x05, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x05, 0xEB, 0x00, 0x00,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE4, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0xE7,
+]);
+
+pub(crate) static TRIE_CONTINUE: Align8<[u8; 1793]> = Align8([
+ 0x08, 0x0D, 0x11, 0x15, 0x19, 0x1D, 0x21, 0x25, 0x2A, 0x2F, 0x31, 0x36, 0x3A, 0x3E, 0x42, 0x02,
+ 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x4F, 0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x51, 0x56, 0x5A, 0x5E, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x64, 0x68,
+ 0x6C, 0x70, 0x74, 0x28, 0x76, 0x7A, 0x7E, 0x82, 0x86, 0x8A, 0x8E, 0x92, 0x96, 0x9B, 0xA0, 0xA4,
+ 0x05, 0x2B, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x99, 0x05, 0x05, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x05, 0xAE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0xB3, 0x00, 0xB7, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x32, 0x05, 0x05, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x43, 0xBB, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0xAC, 0xC4, 0xC6, 0xCA, 0x00, 0xCC, 0x00, 0xAF,
+ 0xD0, 0xD4, 0xD8, 0xBC, 0xDC, 0x00, 0x00, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0xE0, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x52, 0xE3, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE6, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0xE1, 0x05, 0xE9, 0x00, 0x00, 0x00, 0x00, 0x05, 0xEB, 0x00, 0x00,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xE4, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC2,
+]);
+
+pub(crate) static LEAF: Align64<[u8; 7584]> = Align64([
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xAA, 0xFF, 0xFF, 0xFF, 0x3F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x5F, 0xDC, 0x1F, 0xCF, 0x0F, 0xFF, 0x1F, 0xDC, 0x1F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x04, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xA0, 0x04, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0x03, 0x00, 0x1F, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDF, 0xB8,
+ 0x40, 0xD7, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0x03, 0x00, 0x1F, 0x50, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xB8,
+ 0xC0, 0xD7, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x03, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x87, 0x07, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFB, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x02, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x01, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xB6, 0x00, 0xFF, 0xFF, 0xFF, 0x87, 0x07, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xC0, 0xFE, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2F, 0x00, 0x60, 0xC0, 0x00, 0x9C,
+ 0x00, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x02, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x07, 0x30, 0x04,
+ 0x00, 0x00, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x9F, 0xFF, 0xFD, 0xFF, 0x9F,
+ 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x24,
+ 0xFF, 0xFF, 0x3F, 0x04, 0x10, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x07, 0xFF, 0xFF,
+ 0xFF, 0x7E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x23, 0x00, 0x00, 0x01, 0xFF, 0x03, 0x00, 0xFE, 0xFF,
+ 0xE1, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xC5, 0x23, 0x00, 0x40, 0x00, 0xB0, 0x03, 0x00, 0x03, 0x10,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x07, 0xFF, 0xFF,
+ 0xFF, 0x7E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0xFF,
+ 0xEF, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xC5, 0xF3, 0x9F, 0x79, 0x80, 0xB0, 0xCF, 0xFF, 0x03, 0x50,
+ 0xE0, 0x87, 0xF9, 0xFF, 0xFF, 0xFD, 0x6D, 0x03, 0x00, 0x00, 0x00, 0x5E, 0x00, 0x00, 0x1C, 0x00,
+ 0xE0, 0xBF, 0xFB, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x02,
+ 0xE0, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x00, 0xB0, 0x03, 0x00, 0x02, 0x00,
+ 0xE8, 0xC7, 0x3D, 0xD6, 0x18, 0xC7, 0xFF, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xEE, 0x87, 0xF9, 0xFF, 0xFF, 0xFD, 0x6D, 0xD3, 0x87, 0x39, 0x02, 0x5E, 0xC0, 0xFF, 0x3F, 0x00,
+ 0xEE, 0xBF, 0xFB, 0xFF, 0xFF, 0xFD, 0xED, 0xF3, 0xBF, 0x3B, 0x01, 0x00, 0xCF, 0xFF, 0x00, 0xFE,
+ 0xEE, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0xF3, 0x9F, 0x39, 0xE0, 0xB0, 0xCF, 0xFF, 0x02, 0x00,
+ 0xEC, 0xC7, 0x3D, 0xD6, 0x18, 0xC7, 0xFF, 0xC3, 0xC7, 0x3D, 0x81, 0x00, 0xC0, 0xFF, 0x00, 0x00,
+ 0xE0, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xFF, 0x23, 0x00, 0x00, 0x00, 0x27, 0x03, 0x00, 0x00, 0x00,
+ 0xE1, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xEF, 0x23, 0x00, 0x00, 0x00, 0x60, 0x03, 0x00, 0x06, 0x00,
+ 0xF0, 0xDF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0x27, 0x00, 0x40, 0x70, 0x80, 0x03, 0x00, 0x00, 0xFC,
+ 0xE0, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFB, 0x2F, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xFF, 0xF3, 0xDF, 0x3D, 0x60, 0x27, 0xCF, 0xFF, 0x00, 0x00,
+ 0xEF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFD, 0xEF, 0xF3, 0xDF, 0x3D, 0x60, 0x60, 0xCF, 0xFF, 0x0E, 0x00,
+ 0xFF, 0xDF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x7D, 0xF0, 0x80, 0xCF, 0xFF, 0x00, 0xFC,
+ 0xEE, 0xFF, 0x7F, 0xFC, 0xFF, 0xFF, 0xFB, 0x2F, 0x7F, 0x84, 0x5F, 0xFF, 0xC0, 0xFF, 0x0C, 0x00,
+ 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xD6, 0xF7, 0xFF, 0xFF, 0xAF, 0xFF, 0x05, 0x20, 0x5F, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00,
+ 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x7F, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0xD6, 0xF7, 0xFF, 0xFF, 0xAF, 0xFF, 0xFF, 0x3F, 0x5F, 0x7F, 0xFF, 0xF3, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x03, 0xFF, 0x03, 0xA0, 0xC2, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0xFE, 0xFF,
+ 0xDF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x80, 0x00, 0x00, 0x3F, 0x3C, 0x62, 0xC0, 0xE1, 0xFF,
+ 0x03, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0x00, 0x00, 0x00,
+ 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0x3D, 0x7F, 0x3D, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0xFE, 0x03, 0x00,
+ 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F,
+ 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF,
+ 0xFE, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0x01,
+ 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xDF, 0x01, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF,
+ 0xFE, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0x01,
+ 0xFF, 0xFF, 0x3F, 0x80, 0xFF, 0xFF, 0x1F, 0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xDF, 0x0D, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x30, 0xFF, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xB8, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x0F, 0xFF, 0x0F, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xF8, 0xFF, 0xFF, 0xFF, 0x01, 0xC0, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x9F,
+ 0xFF, 0x03, 0xFF, 0x03, 0x80, 0x00, 0xFF, 0xBF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0x03, 0x00, 0xF8, 0x0F, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x3F,
+ 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0x6F, 0x04,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
+ 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0x00, 0x00, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x27, 0x00, 0xF0, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80,
+ 0x00, 0x00, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x84, 0xFC, 0x2F, 0x3F, 0x50, 0xFD, 0xFF, 0xF3, 0xE0, 0x43, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x80,
+ 0x00, 0x00, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x1F, 0xE2, 0xFF, 0x01, 0x00,
+ 0x84, 0xFC, 0x2F, 0x3F, 0x50, 0xFD, 0xFF, 0xF3, 0xE0, 0x43, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x78, 0x0C, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00,
+ 0xFF, 0xFF, 0x7F, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xF8, 0x0F, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x80,
+ 0xFF, 0xFF, 0x7F, 0x00, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xE0, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x3E, 0x1F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x7F, 0xE0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7,
+ 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xE0, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x3E, 0x1F, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x7F, 0xE6, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x1F, 0xFF, 0xFF, 0x00, 0x0C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x80,
+ 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xEB, 0x03, 0x00, 0x00, 0xFC, 0xFF,
+ 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xBF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
+ 0x00, 0x00, 0x80, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xEB, 0x03, 0x00, 0x00, 0xFC, 0xFF,
+ 0xBB, 0xF7, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00,
+ 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x68,
+ 0x00, 0xFC, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F,
+ 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x80, 0x00, 0x00, 0xDF, 0xFF, 0x00, 0x7C,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xE8,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0xFF, 0x1F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x7F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF7, 0x0F, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0xC4,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x62, 0x3E, 0x05, 0x00, 0x00, 0x38, 0xFF, 0x07, 0x1C, 0x00,
+ 0x7E, 0x7E, 0x7E, 0x00, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0x03, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0x3F, 0xFF, 0x03, 0xFF, 0xFF, 0x7F, 0xFC,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x38, 0xFF, 0xFF, 0x7C, 0x00,
+ 0x7E, 0x7E, 0x7E, 0x00, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0x03, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x37, 0xFF, 0x03,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0x00, 0xF8, 0xA0, 0xFF, 0xFD, 0x7F, 0x5F, 0xDB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0x00, 0xF8, 0xE0, 0xFF, 0xFD, 0x7F, 0x5F, 0xDB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xAA,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F,
+ 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x07, 0xFE, 0xFF, 0xFF, 0x07, 0xC0, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFC, 0xFC, 0x1C, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x18, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xAA,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F,
+ 0x00, 0x00, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFC, 0xFC, 0xFC, 0x1C, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xEF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xB7, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xEF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xB7, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
+ 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xF7,
+ 0xFF, 0xF7, 0xB7, 0xFF, 0xFB, 0xFF, 0xFB, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xF7,
+ 0xFF, 0xF7, 0xB7, 0xFF, 0xFB, 0xFF, 0xFB, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3F, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x91, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x7F, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x37, 0x00,
+ 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0xEF, 0xFE, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F,
+ 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x07, 0x00,
+ 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x6F, 0xF0, 0xEF, 0xFE, 0xFF, 0xFF, 0x3F, 0x87, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F,
+ 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0xFF, 0xFF, 0x07, 0x00,
+ 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1B, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0,
+ 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00,
+ 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00,
+ 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00,
+ 0xF8, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x90, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x47, 0x00,
+ 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x1E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0x80,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x04, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x03,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xDE, 0xFF, 0x17, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0x0F, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xBD, 0xFF, 0xBF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00,
+ 0xE0, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0x23, 0x00, 0x00, 0x01, 0xE0, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xBD, 0xFF, 0xBF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x03,
+ 0xEF, 0x9F, 0xF9, 0xFF, 0xFF, 0xFD, 0xED, 0xFB, 0x9F, 0x39, 0x81, 0xE0, 0xCF, 0x1F, 0x1F, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x80, 0x07, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xC3, 0x03, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0x01, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x11, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0x0F, 0xFF, 0x03, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80,
+ 0x7F, 0xF2, 0x6F, 0xFF, 0xFF, 0xFF, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x0A, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x80,
+ 0x7F, 0xF2, 0x6F, 0xFF, 0xFF, 0xFF, 0xBF, 0xF9, 0x0F, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x1B, 0x00, 0x00, 0x00,
+ 0x01, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x04, 0x00, 0x00, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x03, 0x00, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x23, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF, 0x6F,
+ 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
+ 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0xBF, 0xFD, 0xFF, 0xFF,
+ 0xFF, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x01, 0x00, 0xFF, 0x03, 0x00, 0x00, 0xFC, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xB4, 0xFF, 0x00, 0xFF, 0x03, 0xBF, 0xFD, 0xFF, 0xFF,
+ 0xFF, 0x7F, 0xFB, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x07, 0x00,
+ 0xF4, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7F, 0x00,
+ 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x07, 0x00, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE3, 0x07, 0xF8,
+ 0xE7, 0x0F, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x7F, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xE0,
+ 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x03, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x0F, 0x00, 0xFF, 0x03, 0xF8, 0xFF, 0xFF, 0xE0,
+ 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x03, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x6F, 0xFF, 0x7F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x1F,
+ 0xFF, 0x01, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x1F,
+ 0xFF, 0x01, 0xFF, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xDF, 0x64, 0xDE, 0xFF, 0xEB, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xBF, 0xE7, 0xDF, 0xDF, 0xFF, 0xFF, 0xFF, 0x7B, 0x5F, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xF7,
+ 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
+ 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xF7,
+ 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
+ 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x20, 0x00,
+ 0x10, 0x00, 0x00, 0xF8, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x80, 0x3F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x7F, 0xFF, 0xFF, 0xF9, 0xDB, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0x3F, 0xFF, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xEF, 0xFF, 0xFF, 0xFF, 0x96, 0xFE, 0xF7, 0x0A, 0x84, 0xEA, 0x96, 0xAA, 0x96, 0xF7, 0xF7, 0x5E,
+ 0xFF, 0xFB, 0xFF, 0x0F, 0xEE, 0xFB, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+]);
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/tests/compare.rs b/rust/hw/char/pl011/vendor/unicode-ident/tests/compare.rs
new file mode 100644
index 0000000000..14ee22fa5a
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/tests/compare.rs
@@ -0,0 +1,67 @@
+mod fst;
+mod roaring;
+mod trie;
+
+#[test]
+fn compare_all_implementations() {
+ let xid_start_fst = fst::xid_start_fst();
+ let xid_continue_fst = fst::xid_continue_fst();
+ let xid_start_roaring = roaring::xid_start_bitmap();
+ let xid_continue_roaring = roaring::xid_continue_bitmap();
+
+ for ch in '\0'..=char::MAX {
+ let thought_to_be_start = unicode_ident::is_xid_start(ch);
+ let thought_to_be_continue = unicode_ident::is_xid_continue(ch);
+
+ // unicode-xid
+ // FIXME: unicode-xid does not support Unicode 15.1.0 yet.
+ /*
+ assert_eq!(
+ thought_to_be_start,
+ unicode_xid::UnicodeXID::is_xid_start(ch),
+ "{ch:?}",
+ );
+ assert_eq!(
+ thought_to_be_continue,
+ unicode_xid::UnicodeXID::is_xid_continue(ch),
+ "{ch:?}",
+ );
+ */
+
+ // ucd-trie
+ assert_eq!(
+ thought_to_be_start,
+ trie::XID_START.contains_char(ch),
+ "{ch:?}",
+ );
+ assert_eq!(
+ thought_to_be_continue,
+ trie::XID_CONTINUE.contains_char(ch),
+ "{ch:?}",
+ );
+
+ // fst
+ assert_eq!(
+ thought_to_be_start,
+ xid_start_fst.contains((ch as u32).to_be_bytes()),
+ "{ch:?}",
+ );
+ assert_eq!(
+ thought_to_be_continue,
+ xid_continue_fst.contains((ch as u32).to_be_bytes()),
+ "{ch:?}",
+ );
+
+ // roaring
+ assert_eq!(
+ thought_to_be_start,
+ xid_start_roaring.contains(ch as u32),
+ "{ch:?}",
+ );
+ assert_eq!(
+ thought_to_be_continue,
+ xid_continue_roaring.contains(ch as u32),
+ "{ch:?}",
+ );
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/tests/fst/mod.rs b/rust/hw/char/pl011/vendor/unicode-ident/tests/fst/mod.rs
new file mode 100644
index 0000000000..5195efb13d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/tests/fst/mod.rs
@@ -0,0 +1,11 @@
+#![allow(clippy::module_name_repetitions)]
+
+pub fn xid_start_fst() -> fst::Set<&'static [u8]> {
+ let data = include_bytes!("xid_start.fst");
+ fst::Set::from(fst::raw::Fst::new(data.as_slice()).unwrap())
+}
+
+pub fn xid_continue_fst() -> fst::Set<&'static [u8]> {
+ let data = include_bytes!("xid_continue.fst");
+ fst::Set::from(fst::raw::Fst::new(data.as_slice()).unwrap())
+}
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/tests/fst/xid_continue.fst b/rust/hw/char/pl011/vendor/unicode-ident/tests/fst/xid_continue.fst
new file mode 100644
index 0000000000000000000000000000000000000000..3024c8189a9f5a1feeeca3cb0957fa21ac08d9f9
GIT binary patch
literal 73249
zcmeHQ3E)*@7XO#6qWWxOnJ6tvidLk|zl~%qN<t}W6dKC3X;73I*|Ud`HA_m88L2SV
zv1H3Kn36#wm2EPVGw0iv``zum``-V(^x}W_@7{O6^Uim^^E>Bvwx}qv5B#!m!_Pnc
z@5lfC@cnn+ezR`vny*)X^`BK=e)0LgKU?|fisk?M<l~S2`QZoeFMIc$x8Hhm=^L-V
z_Ub=gdHJOmUwHoS&prFhlD{pO|KR!K$Bi8``j6+08hP$He;9H0S!WI(cE<0A4mtg_
z!Ka?o|HOVL^zC!}alLyTd(6>C9eG60!+RWdX!mYiyL33{zysR1Yul!ED@ggNs8)T8
zEw|cwn;JF6g|)Wbu6CWeWcwX<+-c|E?6T`_yZ^S{9(&eruvf!I^n}LHWbdZU_G!Lv
zi<bNC->P++w(Z&<aNt254({0Lkl&@ebEQ7NGjsvy%C@_8KlHF3hxa_<$fJ%v=Gb1n
zk2}6k-xK<s*dI<h`IG?zPaQP)w9|(S{rwrkhM#%X*(3gN&bcE;o%hGlW5$ky@#jzY
z(*+k^G?7dyF^MSt<474?A0veCg-GGzMNcn$>TiF2a={bxAD{Qw+&PcVe&peY9-Q^S
z{rBB_&)qZcy7P`1x8HW_^jmJe>Bbwbzi!&K*Ia$ol~-Io^|HVG`O+zqFS&Tq#EUMx
z;7=36#dy%E0|%UPa=0vauKe90ojM+@MSB1JTDI7?`995>?%kwuqlSAmsK4hP^?tki
zZoBUCo1J&safj_m-8!|m+qPEC8ry8W)s|aSuU4T&I$V|;hl_D#=Pq4Cq%cMZr3_BG
z_>##}F8%XgE}MG!6<1z$^)=T{yYBiMZoKK{Tc+Q7+wC*%xbv==ci(gGefK{w>%oT}
zeq{EebLKua@A3IhEO_#-e|u`-(~A}_dFI*Y{{H+6FTV8hEB|=)wb$QR`sQ12zw_?0
z_ul{D!+(DC@hAUUzT(rBpZ)vuFTPy$pRZPby=LvYZ@&HR`yc+h{>T6Q^z(*|zW~8k
zuql4ltY$jYRGZH%*(|J8Ev!^+n*yuVI$dMpD|WpN@7M=%i@dujifZ(CQVKfSNXSV)
z`_%IlOgUeKT6ydkpJB0SYGfEa2IXt)xbbj4mpW!3z(nw=XDEPv2Bo0MH_-yIsUKAW
zUsQ{P*(00Hk%^Ol*&_f|W08=Jo1l2pxt(WTCsp=~&;R||XBMY2qZ6CY{ryuw*K97d
z)eO$;FT`vHIDu<loWvzFpZVzk6McF*OijZhF#A!MGZ!9{mq(b?^b~5B$Wz&pytN66
zsq>Y9`6ldnq4rHM&jd=a&ohy|nXTL!d0QXGRM6^C+%Tqs>`<t0BlUccHpe^@$%HzU
zFxzuNkds0HJuL*!ybxeHS>g2frn9;6r`)XNqWCYgC(c#Ft>W}BlS|`|A+l+u6@a?o
zLKHFeqGcni#>3)jZr%*q#xj8Sa02-LrX!<)ZxU(vYIm?S8(e>IQmxA!aAE#8?Li(C
z<#sEilg$<xx)tyq8)8e38xCN)8LDf6dx6<G^bdCjXW@y1NLL*BFwoiMzvGt;CS<_?
zi;q8gkAf60y~qFxDv;DM{FrbG`+dUKTrK^<9(S+?H4xIsd+aX-Uoe1%B*4HVq!22H
z1Hffd0sKB;5Kduu0EL)3h5?ir0Pw^D0O}r=V!n{BJiQ2*uNc7e7RyrrmcpA*MpmuR
zl^Qam^0yRa5AiV$k4fp9KQCJT5Ry=c1WKR_rVXU%LvO^-4)4*m3y#;FIvjLB`?hVw
zNbQFiNL>yvAihA2O5m6oeb+T>0r&@MK+KHVmC$S-XudDBXo*@67-&YXYu6qCp)*|T
zKsWJ2K{SvknxPJvD&(iIzX*$g#Klem#Kpi5i~&Q&#-9%p{sa^nn*`huz}x_U$OIrX
z0Wi&Inyyl;0zjh`>adVd@<8b+IxRHsQHgm45mkg!7cVkFEJU#Gx%-Y8w@tr=!d8e{
zamebDi$^*tX}~FnvNG|Y&?+<N7#I~RA`*qNg@g+TfFD%_CL&Toa8v|Ps45i+0FA7o
zOwi8g+6@>;3ZP+9I9_#=Sn1OjxXFjx2%Q4OPI2}0Autqve+I4%8;*YvM#aAtl8W0*
zbKw$&hAA(ADY%87OZh_n)ea@OM=r^=r6(jwo(MsEElX4Zee&_LcZEb*BOvM^IkWH&
zf>grHVbB(`0f>JxAv*#gd|S*IjL&BceqFQ!BA!yzf`BKLGw{LpsEWXa?g1otUkM0%
z0>wQ=7xp-uiWk6902GM_P+0s)vXkYKLi0?%C^ioW&Qq~6WhyWd;yB2LK>!7g0-~cp
z;Zf1*op<q-nRf#PO93=o3W%4=d($PEpQLL`_?+*))k3F2M0kYAD<U-HX@$s3v2y|W
zAR3QjAIIWt**ld6k+Ap?Q}&W0?m3H}D}74#gy;c_{9rvx!#_k9vnUV%9tT2auwp+h
z__#;SFDiA8(BW|@cdjQ96e17P0R$+I=g*`~b8H@Ffkfx&PM|U;FnWN6PxF2JFIiN=
zqGdiB6|E26my=Bqd-MWRYay=cd&A;A*w{Jw;z>Fp$qq>BoO}F+>9q43R>H0dh9R;3
zV6jNrd@=_~v)97ckM9Fw?4-t(*S3Q5q;bWgj<kRY`yQ^5G6p*A0|g9)EBwa%2)WPf
zv#MQxAxR)mFb>EU24qIEg-!cJG#i>+9S&@-1AcbfwW1>At)VH-J|cz<1AdGXYeOBV
zOSkoK2s)fC+~rFz@ww5o)ve^hnEH8UenKp0d+hTUxsrNGE~{EWDE{5)bPxk6ZLlI3
zNh!72YsMT=4VB77(_>|}p=&AtGqu~da6xNawhaGS1~3H}S}ZDf4HmJxF9t{v#0E5q
zjjS!ch*jwwBVEJcp~BP?vP1-E((ugK=uGMfNsKMiz)YN%un=P!U@YT{OGmufaL%VB
zI3WQXs&SSJkQmxvE)bl^>Zz-;1+C~zpy8PSB0v*iWorHbI6<0_G)j}KsZwDp#Lao2
zdv2gy9I)Yr6suTxj2+G(a+t;q$A=9Aje!SnqTs{L2A|2m{d53`y{R!@8xLw1UC~Zt
zZb?`NaYK0XT!Yi^PEH(R48Vho(MVca2q`J2Hj}DkX>;TX*98sck_ep7W8&q^xwKzW
zq;F&cJm&^ACk~t^P)@>{!Lu61bwn&%S}70D3<)HLB$*SIo(Ymfx^162_oq_`#-AC&
zRK4~SL|NF0(nGL4BSS<CB;{#>=oud((S?XiJ8u-`*;#_<$*=2dIOVlpqJEnEBhd>0
zc2b=*C)8m;pfDI5VH~E8dYzv{o%4Wzpz%@IpfWUE(;~eofz97XZ*f1u(>iU*xT	
z=4GIpO0$V<tlbp3bYZ!mVIH)^+R{j$!|XYu_cXd)lcvw{BmRU?DZ4&_wS?44<+N-8
zapR!(KFoEGfHi)yNvIPy$3?jYp<ybqG)8q6u{*g+le@{%gRHFM2uU*`BQrrWzx+&K
z$;LvqXcw8e#=6T)@JOq}pripuCiR7ZiB^<0q?aj(GLXN?8<jYbgGw5Av{%avu5@zL
zoveoYbsn&h0UVkCn`ioOuBpGY6J#oTj+!eJ4`NY=0OPdQ;$5!ufGrWYQf}GF!3_R3
zCpq%8#7pvUX^xwDK2;Qzg4BO$rzvq+?23RvL!2h#Lg{!!>2w4IL~Fi)w5Z5$^GGO_
zf|g+|y%}Y(oA)R0<S7)Td3i#}3duikm`*{mpj`N=xfL`<B{@RkQWCPlret>ueh?nM
zX3Sl*$SMi-NTm_eEgED*A0bm|XBJIoEVJZu$R&-gRl&8<ybJ7-O;l9*4@jhhAzh8d
zR6|*6-djc|+=8J7ai>Kh8XzZDkQligaB_diZNr&u7_UvNmgP(!>E_{l0-n?upz)S8
z+!8>t(m*f309=T1Z2|~tnsoY<;ZBG;!E6*gqy~|3N4Q1lL1@%B4f>{Xsk6Z_8I0}#
zWC{U66@pu-Qxr_Pq7^b5kcFXHd@mP`?9;ijwi#%Fo?~|ZG=HjZ;W>Lt&px$lE44;f
zwzjr#11XF&--~-N!L~(rM9<#~|K}0hJkrQ%gX~wZ5lAWffXCEkgc@`VQ|^>7$EC|@
zws&Lk+t3s_+hDK^3#7r`lB`d)wgv1-9-GX+;Eu2p>>Th?0Z`s2b_OGVqHFu}3yi<X
za)KFRYg|>lRnos;eO8(cE6drUA1jp294D@unV<4@?XUcd|5_CPllkK*PZxjmFDDL^
zwHftfP%BRu5^*wu$4t<e2^O<pxHOMiJV&tYMfkn^rb)}DS<;ii-mGJr0%i|++4gjV
zYX}}C1Y?jXAh;gNpeN50_KM_RkgOpfd=-)@M>;D+ytE3JhB!7e@@900m+jFwNtKcP
zIci^YSWLeqOltF^++%cmj6c$u8X~106AKCogne}AEwdtk5k~?r>PUJ`o<6q_5R01E
zEGC9BJPGc{WK+VFynAF>*$QNZE0HcT;4(WFmdMeOttcKxCTl5}5G;%!DKZewCh7`Q
zK=k979RnA{?9h-Z&oUu@EnlG%PaY?0asJoMwxmB+#Bp$iYO@%Li#<%1l(Pu(;MAna
z12Rw3m$%}wFsHT)Q>eXQHm5&nSmX@nW*2%~tl^{?v0@T`LOSdK-BwSPv*1NMyUDF#
z(}Cw`5ymqyYp1JD0cBj`u~KZ}`7X&uMDnq8B?ZXC8RF^_mb9}Q+J=ty$9#4l9k@Gy
z$BozS_#4T@Y=4V#wht{~wT(p<Sn~FpOAU7VoJRD-uFU*=LrO&L&QV*+mZXFoDYHs*
z3vLEb<n%d8BYSv8X~>L1^<A75n>L)hV0CI)Z=gi}95#gOz$eWO6P5QDXKpIE-(bs%
z6Ui1?Gt$$ZZRT_@-At<^seUw@@h35dkNW;0Teqm`>-oMgFcptJPgA7G%VjNx(GM>w
ze#8sv8+nt}M}}4T!j|1q3Weo(3x+KRqd>I~fhV2X7|iiRUEU)f4XW;F)LG#BB(bIi
zr0Qx5=>gPeL8-!{jCWgejBx7{OVKcrq!8|hRMkHG6>A3R*eMR`%LIQ>tfoj)BP9X0
zX9z%-n&GDy1!v4CWjyF9Ig^`As%LRlDAX^per0`%!V2nC@?sUrP;qXpGycC`oncZ^
z-0<&un{0OC6e*{oR*fiC!z<MA`ZT;cjYzV?_yrcP0Kls)sV){}mq65A0$O+}VYDjP
zHIsOgda6|PnG(G7E|R>evNim9$nxUIQHk7z)&dK&47_-dpnG!XT46jqo9ixN@vjt`
zSpCj$C8P!uJtf962-abu7m?K^B6Qh5hMsL@9cJw+-lVxFehj`y28C@$Xe%Pbevrlk
z_}F0!0$MIZV(lcKa?N}4NVx63it)9Eap>t}7MFp-mDA+@)b8E7bp9Pf*e$Eq<aT70
z?Ck1wX73400e6|D8Nsa0DC#mob3{U+rJ$KLYBR=0i=;vYZ2y4ysNVHdRqx14p3eQX
z>`EoXo&ut-+28{FY0Y3$%FDTEBNt0Am0wyfnD%{zdA)Kf-AH~aa~aomuB>L8P8jo5
zxK&v*G^q8$xqy;Y;b7d$IhY2)C-Lu*T&9xAv}`y`@mJz0Vx(CjypyVYK`gVl?FAFY
zk3DZB)?aSd*0na{@}}Ib(6p4Cl@gCPph*Yb54r)o`^}wASkx#I&I2;e7dR#=4pPPE
zBD2a&r(w<uhvNAxhbyweRYMMUD^-Tm=W5~xv*+o$!Z@=m<y|<#5ucbR)C2I6$N;=3
zGGpCyzno{A%&w?bF{t|dE!%CgZ>>e!tr|D7?y7Nx_;=I}b$7mVmwvmit~a6ns&UO5
z7UCX-YV+>K>092r>8<-5(PHg>ueZLW?TU8v`kN2zcJP``Ju9E+GQ9g+hpienx94L=
z^*wggxOT_w+_!nZ@%?{1dFa5YgFZfO^3aaM)|@$S#7XD&JFnB2RpVAq5EgC0B3$wd
ze75onTeoW2B8%$cT2vc00%+WXr%n|iSj(Q4rJ8lU^s;{HkTp?^yul_JzMs}jo1sNv
z&#P>ltn!dfo{>O+3o7P?qYRYLa$8=dCJ;wxISwqp0h$a!T7Kwouv<#bs>p?$t06*S
z>`rFrhLfTt4RrM|4YQ{pZ|7)zY|N=fw(-q#TGgX>iuk0Q?o@z_u$B=yAjj7ocG>c!
zX?@LBma;paEWo!;)nsJ<VoQ7MY4RSKoJS$vX6Np*T!yn-ZIWZdUUbRtf0yQ<OJR5}
zLCiul$@}@^6SJyC*Y)%$;PB8`Pb9bM8@dt=^s-Y^I2G9WZbcLuCrefjoHis#usH`d
zR-#M#Ay1aPXl4C?N$}nzES7~TSb%<u(q%D9#s`zaVGA&WPc2yiDJr(Qh?K79v(PE@
zNzZ%LQ(t-cicbwz)irDBd1PJI5>$Zp7Ct5F;5o3@T{?l_hU=$c)kMtyGhJOcw=#5P
zF6BB45g<!ndoDTA^g8)5%KEsKqd)`{V97)<2zz0wO|&k27k6O&W7%jPOER+n-JVaA
zikT|5zJ#)~IET5+p64|rTy<k1pazj{evFY}hLh?LzXhcZEABMC$6n(VRHE7ctSA(i
zA`48|4du8+uF9t`3wrGj-+vp#+Gj)?U?IVxevzr{bkKn;H9fYHI(NU<*vgpwQko!(
z7sw*{35M1|+jiJRyfSMCPu_>_zmTy?onS;V`@)#jdAY85xcT75n{;dB=7M&+-T2}~
z3k1hTTEN+*Ez&w69jBN4;(l^%N>D7%$ZwgL;K+%)<acEySMz!Ra;E*}OJeKu$ZSRl
z2S?7%BQqN)8WO1jFn&g|Ty4D-R^P3llWo|Nb64;{TV%3E5^Gk{CA6Rmt4dG1r*&K(
zwP_m>TZ0!z27<*kj>l#7)R>|#p)HYV#TN{2Kbirlqg2_RVbNwmWasY6qN8@$KE7ZN
zt=ALUxiUFLzcZ}9?a}f2IF=xF`%xdnwIF|lb-3UgWMuI>Ilnu4OoceS-c!OaE{G{H
z2Y$Z(n`oDf;jPJ06herdqC)koJEh=Bl{6C8_2khUx?7Lvg`fOcPg}Mdq)qDAjHv3|
zIS)Uiy+m=piK>1%k=}31^$pGU#fNRtGQ%fE)lXWde#co~z;f_{b0t+(-ppS1*8}V2
zPN&`U&ZhNpCC9I)U-uqzH5QPNCx$Hjp(7zDdv<&4mU_;UyPW#p(%UT$1DTX{mlmr%
z9b5V37a_*>v&v)RIQeE8UcNB)xX}*cd00thSEvs3uk?_-%)PK6C{~GAXGM{U$2pNj
zBiE_M=*sms+<220l@@2|fMC9ZEGU+M6zV=783ktEc%3qVd(~CiS^t<MYzs73SSvVx
z0j@&$4WYf77|?E{T1@mWMAey*vjKoJ<moUh8i9+eLCcLY+8UKCn^;p+T2{C6u8_rr
z5{zuy)%q=ul-~#Lml^Ah_mNdVzLXECT`=M+Q5l3J(@jow$%rl^NG^HL(7C3!j}q_f
z*y#{DrGTzX48c)*fTY^O=OkK;nkK}|3|I>~evCIr?#;H-RcmbU5f%6Z$keYF!jy;i
z=-#a>?Jx}OXS0g7ZG;cl%$?FE52-8Bcf$pw)2x9yfIKb&jL>5tP&{*L|5mL*dv^dj
z9Rh%_9iR(;3tSfnMWBMB@E99>_&Fu<mz<zpaOtn;{L&Y*q4ODx1ZSFjB07wtMHJUr
zTui@DqLSw8Q#sK&`*e#JGpB1|AIGnp;|K$H$o6%)DY++lNgm8bnvi@1Z41SSLrdAG
zH(aA1weUxi&uY!+UjWO%@H{4;Ie88^yU3y0bVhcq=qiLy<_ZbvpKW(5JiBe1)(IiN
znl+HO+CTv%0^ryGk-t`a;X?7VSFei~IXw}w>2V=TJ2ATCrD#vV$XA8jAZ9nYI-jl;
z(?IRfa}?$7Iu|8{ngsZ*Z7tF7pno6y8wq$N=IfR2VbU?57oXj=kX>e+ClEbr53eVz
zrzl-4Ol$q?&i8j~KlK!HX?8uDPfMSzT(O)3F6r`d<jhK|W@VVi1!rhvwx+F<v0xK`
zEZGEP`<TfTpk1yFbMyV`&NKJszAouJ%#w;~ZWS@90+=ACRdC7Vh})AX`E+5)UYm~Q
zC?bF6_UuSFdeEt3)#xoMl~M>Q<w}qaG1pq{*y2>#s$SY5ih**)Mxo;Q3CbQ~bZbe~
z=(IzOq)xJtFBOd_{5>{pi`HMtvP>0`7_=+Xu?dG7{u(OLooTN{W5MWj^v(n^h}DQ;
z^+=3;lf+x(@)FWR8U?-iCW>%edrhJ`Cd1C)Oz2uDBs(R|x=SM$HETFS+cq^)$pyal
z_9z;l!ck;DbWs)w-@}~+=xT~9KFLc@Vm)f$rEx@q6BVO`yhFB2GBr#rLcmY5OV|bJ
z_s`KC$-IV%^?rO{QFPdtj4YzFdVHTOY}9(M@xN~C^wb+YQ(qB%0XZW5+b`M`*;xm1
zXu3=9QM7QOXkG8u^tPgR41wtG&gv+cUNj*nksDPtU6)f0Hjb}eqp8IVxKz$gtp<|`
zct9?Ff%Kj@_z;j@qw@>wk_kvq|FR%Ac=Ih$J~_znx%%rhWNjvLr{>OyN2nxVWRlod
zyDI|kw~Tg>?wNE&WFuxd?1GffEw%TZ8=PSa6)lzS1mtMviSvcY;K=u%{GdN`sL<oL
z^KH;WrGaCP)l>7`J*#xL$zjRgc=VZN6+c$O9nvHEHJAO-?`e7RuUCH+5%r@1#f*8_
zG{gTun}Nrj795l)UMREt6jY}|B0b3|CN2Ro-e=HYe!*$kGW;9yX1x7qQgnb1sL^En
zn#d=`6;O}wZ>%rXRQn02C6>m~6T+@!vNGG`N&#*q^?KZRFb|619Z6XOW^ochF0L9b
z(h3=ocjwx^*<h|%+;k@2Z<?>UlkffWy`FT=y9)}~z&GnC+Gu;{F-7ptUdMcb&M(~<
zE*-+<%~%LYOF&nw5P-=#%H!&5uAO$>_4x|M4L8C~Hye%IGTqp~RdQ<q`@OWAPF0H~
z0;EhE@t&`)D>K(kReNgIuKVWO@4o-xzw4#olOIc4E^~f5#*LPmDKDUw6Cq~WWR4q}
zH;e1Do}z+M7~_{_QDFr-lbV*4U~yE=T1qETq_%ae%r>gpkM3$`%2v?#xZb_mG|Ykz
zxS`YEND3VB!EjW7ruGRmE>7;DTqb@`Q-tGfaK>}PxtcwVEG#o&%l2`T5dNhLw$tGZ
zo3(V|#MUMKOG5Z3jfx-t_tVex=SVhWD@*ydHp2*=Q+3xZW}Otpt;=W#XR7fm$(i%V
z(PPHq9>vGTjsmFA7a9e1`4wVs;TGh|e7lohAL2`|l1k2nds_u=IW|$|k%u38P*4|L
zJZU1c2RM5Xvw6v$*cX_LNVdqPPs^*7JghT8)-3r)S&A3F=~?&PJM)eik%VBbNoH0e
zvzbWyBq@AeXe=<1MaI(mGDzTq+ipi@TUs^+;I5f>-y`a#aGGYAE6YfOsw3^2jOfC=
zF0U;e=E(QuC8HTVZ62bY2{A%)si%;);Db4grAezS=@6y_kte;AAj+dqhM6PB>QMv8
z+5<8hL)M}8Qe82o1gsT-*agsFcM;$NRWlLE)uQ{Ain{p4P>GKzeqwQeyhcetUgDgN
zDtp&W^}P3<&Go9YDmDplpCo5{bdE9aMsbJ5p4ulYfDPVfVC*OV^67T;i^6)G!;qgd
z(wb%0OnNmhg+8?Sgk~S{k{_$-n5*GqLO4U|`a`t*9*&xqj2PkB&=A9z3874<iZ(k0
z_EIdSbVjD8V{{&->9Mckh?hgG6jqx3sf8f9`T^3HStaYMT2dX@h&gyBj~3h~JRK#G
zYrXhE3tp~NGaN-nqX?&soYD=KD|~sTy(zcY^c~I}$un1kw8(>5Ey+d61fV&iq0Wz7
zia#@_rqAm6OR62xB-zW%^Q@~!r2lysfz_-l8#fYu`~a75AaSdvw19a$HOMOKP`?2%
zzIfILfw-PjKabdM91?p*#wU=WdG?aL{Ft7Keb-LCEgZ=Xz6u)>0i$*ueNSZ+f-AZ;
zyGUHwFM6rD*4D0x4!x8Ww<Ll4Z0aNnM<>Lym&_t2yesgWVO2!pf7-k$(qF&i*tO)n
z5O~fq-x1R-MlXoh+C1uI;_TH#;MROiV~GVtDybKBWw{+&#v?tdz|GV<mUp-$ysIIz
z5EB-%CLwOroihiyhZm!kweRLV?ouWgze6z<G4@2Sl2;2PeLA%H$kL3LJd(Z`J#C17
zO{H?Q)Tk6qrf@c+WP>ug+-{xjWJh17{0<jV9GHf~i=rG92_ACV;8O>j+`nI+<9cJ#
z!;w9EbnV!ICOc@NwWf_5?iG>t9N^jXM8Y$}8K5CFQbcRaUc(|QZFmQ_rHgiy0s(NW
z#r%2b1VBB?mCza4*SdCt?r6lJQyE0wC{U(nK&t0{a3W|t1p@gGtbO!80CPV;fc2E$
zKfk{g&Z~!YQmb0UE*0&nuiWCot)JYwPL1bk9=C1%+Go`{n+(|Tgx_@8twp_d^+wf$
zJ?b^srO}l2)0)g~@@$hS>-oQt&E#6L<&b@EZ`ok~jjia}3)|AaN4J+(essWH2eml3
z_91+`d*wenZ`-9|w~mK?-s8KT)sH&==v$9%*88I4_v<^M--iApP8l_D*{Pid-+ubV
zLuZ{aarnHmrmTN!#BS$q7<JBQGWNo8Kd(VHvClq54yg}mNDJ0vT}Tl<%CD;h&2?~{
z^M|ug))2+!9;+se8;PK*9NFVEd7SDu!QZO3*$P(BwRd>7Xe5=vDy4HUtket7h4wB=
z;-mIx{&BSn#k4=roDG11bSI?%gwp}AMi|}He9^cujP7YLyg=ha=`<Tx_hoU$>0aUZ
zu|IjVjKW{6$d^n_oCp^y71O8>SzbD_R`e%Hk1v?8+B2cJnxFG3Sa>U_gVQ<DG~;LS
zEPF0Yo|=onDqP7ZRP(j(BZNN$RYOpX{8V&dE3F%ryXeR1eF?CoDNiYjQUb)5)Je;c
zQZk7)G$wY#M)FH(Nn=r-CTo#TP_PFpbK`VwoHxDsG|GJ+ozfmB<PlT8a3DDbM-GLN
z3!>j`(*$GW;=DPjv_1K@D1uc|H*uw05DDwb4K7@;*@9Q>jX7rs2U3I6Iw_;X+Ww8e
ziceR5_V3TX_;S^MzCy06wd=??1(v^Z)=|#8E5S`NFsA#WEg7;WR#85*RyF*uQm*_`
zP3+<Ov--Po%Y2)CWt)nZYo%^vN$u2^Wc8Idw^LPb0ApQK!rq(5u@WE0?14+EV&ni|
z>#cr;#+p|BuGyA0=%d)uUz)Hb6Qt6#;%w<x#24im-|fW5-nlsgI@=6rr5rO_A#*Cw
zOgww1YRUf_Qa#=IX3G*f%(=?7s5G9@w=c<NS~b?n|JSir>O-1KD7oo--?H_$xj!?q
suA<tKY89VXf2ZbN^{3ochen|^*s5Ylhep+zz;8#VuK2mKPJ;{n4>vWH!~g&Q
literal 0
HcmV?d00001
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/tests/fst/xid_start.fst b/rust/hw/char/pl011/vendor/unicode-ident/tests/fst/xid_start.fst
new file mode 100644
index 0000000000000000000000000000000000000000..3f5a46b168cc233fe408f420dfdc921768e85ba2
GIT binary patch
literal 65487
zcmeHQ2b>f&7e9)?o%j(HD^i4`Nbf}j4mm(Y5Rl#xMC2%f0%8MHz=C2yMMO{$3l^{!
zis)zWidaEGuwX$zK)~|8w3$gV$+Vrl-SxZW$8C~HGPB8><mHwBE0L83ANc3*zy3UU
zVE?|odw$=&Yv*q}e*NX=pSJ(_!}s59+xqR6&EI^zY2#O4e)0LI8$Mb8@kbwi@cw)6
zzVr55Z@%&RYp?$Im6zAO_{{Q4rd>RB%H)eKoHX%*3FF6&Ef{nD=<`OMJ95N1!w2;5
z*SAmaUT630(fzD$UC-=t#_6YZ?$j~A!>R2d(N9*f;w4HRQmS;B?3_c(9`>JdsQlqa
zR5<deqmMb3^?Y2#<11CJQuTyt)pKjqtX2EOI(6&SZ_uz&<0ef*-np4mzd1>^p!t@q
zTAy_CDQ()e%WHpXhy0G6I-hp>8C}lo3f<1?-lON)y?XcQ+pqtCfrADQ89HqEIU`1%
zJL<gA=Z`5E3**L5xM1R>3ok;G(_rRP`v?}@{ozA+pBX6crL}8TuX^!?=bwA_nWvw6
z@`;rz9)Il7N0vYQ(1Q;wyMO6@_ujK)@!gB=T6pJzJ8r*i{;jv%eAB!eZ<u@ib=O`q
zXZEbCuex&PjOkZge%YmF+8s7@$lyT(%@my1u5FuBPClu1tClUAH*4CYaifL}>es7V
z=fv8zYSzfDUhRacRVr6HzT$Dm9&_|jM^-rE@bakKe-0~qXij#S(xnb5S)zEcEHee0
zX}4MP76!`mAv}xjCQq4q@w7`Wz3lQUrq7sp<yBYDnmy;5Yp=V0?hQB2yXodzZk>PI
z?RPA=bKzZ!?q0m)o_p_GdjGNq9(?HG<&Ql2*yAf!KJnyJPe1eQbI-r<;;Pka*1ojv
z<yZdu>T9pR@#b4^zw_>U?|<;&M<1{MWW%SQeg4IlUv1p<^*5Whe7kkqci;c;<My9^
z{^i#lzwO+$`}aM2_x-W|z`;NN`uiV1cnJQDpB=x@byHj_UtU*4tl~163SuS8wn(sa
z8MpsX^5wbp@QGb+CD4YHld8R5dhgSbmP_4gITx>$v!~-Va_SViw_8I|Sl@JgghNW<
z`{7+4a@c(j1-#osIdJxSXSD=%tB+y11be+iGg3|hsd@mL^a^#WF504J%(Py%)NIvg
zf2t@h=zYn7MRQoO7Qw*GUVr^DMP>4m&Eo+%p!ly^0DTx?=ua6MX3wId1iw9aM$$9k
z8>Ks-B|#^$@aq9S_5QZw`|mdBj<qrKYZJyhM_-kuTn7hf1T~ou2M0}SwWw}A;0I%W
zx-*<=HT0$u3f!dJ_vTx8!L9S1EBN#QumIgz_{0$AjtBSd@mO-0faHm!ok6{qAmj`t
zOJ#vkP(m3ewZ4?s%1`1T6X7lw3u!6odrY-!FT9H+7tuVrJIqujudX8@^IJ-oSi&Tg
zaD-{YOtQ4R+PTMt5iyW)I*JY!`ExY>e~g`z6UREdwai-cYQkPcOI-3We$WFZ50g8`
zIk$k!w3N7-1}Z?ak~hI2d;V+JPAp5^wDJ8lL}K+MmsaV8RX5GE1XZe#YPc<x>fR=r
z<cW-1hz-P+nl>ZCPbT}6hQ1}wIr32HGJtySCzmY=DZqe%04^yhB?7=wQX;K_X}AHA
zSmCcLNMrFcUCaPxmoc9#6~V08PJRwfqH97<T=eP(wru{8&h|4;dCxbNP1>SKeAFI7
z#Ez|7wP@b73Fi&;GDTF5NfYT0WOGWArAh<1rQ+mG1}+eX8a1I-Z8)(GZE5~PCLbDV
zu467$Ew#B;z*2Eg#NzTYFc8l;P{BCvWQ5ugz(}R&+)+w_l|7Fo(CFxM<lFK?QNWC)
z%l9u`vUt(LJBdgcOO%;7`KpQdy&OD<y^+3?W(k4m!&|Q+nKA%XmBE%@;93keXLwR@
z%LdjM=)W5_0=K3^&}8sd&4G!Nan_nOoa~Sf9idZaoI34v{0Hkb@ZYY2%noNYpZ=OM
zuOc+Scktt{uzS~*&0lY_-bzbppkIc`1ltSo@L_|oF2J?u>fg-6v9Mo1&G^LxMPFs@
zv7oA|@Zh;#GiN~Y3r82^maUvJU8*%Hv~*QuH3nN-B}^$+Rtf7cP<0h<SD@=rC>uKt
z#!nFPBzeI^sQ^uie-=aa$Q6}qY+aEx>#C~AttVnCBK&e==|HzOfptB??3W~CVZG#K
z04pnr{8G?XTC=ZCK4z@|sKQYkO<VbB72=7tlIk~O#%QUap|qA_;5?a|1+#UOlVJ*2
z;!m~nz<G2<sL6_<GErE+PIc33tZf(1^fHr5kS^g@UpbTMrSq&UH?SVhnO&DAT0ghY
zNE$pY@R7<wWm>g{lYr`?K~_dPuQ&7qM;k3}xp=Fks%aRby=B4JapScYghDhS!kp1%
zRkRea`C7$ZfSU{CWn~GsjFPlY!Q>V6eFHsiKxHK!*OPS#HHk3Hh1-N^39ubWP<{S;
zZ!ilI-}AAg2f!vKqs|>pH1o`^q+N0}?z(BLs}?eg5>iSI!uX3U&-Q+d4MfN#$w-70
zSRcY$$sb}t;=Ht40}^~Rf(vLXyvy<vlCPiy>+^vq^wGVAOAsl)TTs1~Vqrq)avirW
zA+{yHrX}R`7Fg9lXty6%HxQdB%OuKIE?j5^B|vPMY?dE-QC0zjEyOWs(#mVdDSQ@y
zuW1Po+Y$h7T>?)6u`dBoEKDG%i3!?~a)OKF0hl#j5|sSdCQ7w|iov{zNFM!dn}C?-
z0Z;=yJzEq^^VO%Xykr`3>e{JRqsDkz+D$~!3c#$Qu$1Z5I4B{L`v|)9TAEtbuGEh!
zNOSAH(5Hf+<gZe8aws`r>pldTOuP}EU0{2Cm4m@`LuT_;m-T9p(^UGg8q{jqhvx-H
zB4Jstg4ukPF7+|mu;Ts%GgiKlq?*;(_*oQ-XMA>&sKjNJpQo{64q~`0ZLgLczOc<p
z*Rl3Nvd72zWcj*e;SAWgUcL<6*4~F|<lSBALYKXi6kevgqLiV_BdiZ;+9Vz}bGbo)
z?l!tNd5W0iKY>>)WsY1~TLv3M{u9O^hTqANulXL1Xp4AE@138C-bxz^GjDHU+%u@n
zvE)tUqLIWLES#|mnDVxU0iXhRp)XbQZE3wVenI0%GwvFsanTSu4Uvpn)%~E(k;_+V
z5zhO?{(0DuOV~i%TZXhrSPocr>(~-R^_i3p>Y5JktL)<EeHL5sxVKA{<=z+47mAK<
z$ko|3Bh<0a#YniS849$tWQ$^@M!owu*}%rP*cj4jrKZqT=|BkLGaTHvmpOtGKTv!Q
z58-2H3qgap)?t^>xcubQK{e*F8JlxWWkYpz0ALH{c|)Ufr_6B@A3Ff-W#`<_Cq<>E
zOlS&oZ@`srqz%wKadI*;o#DcqjCa-aAw1v9XkA8<U9g9y&hLNh!_M!L-#hVn|LjxZ
z8^HbDu~KL)cQ}sZZ|t)q4j$Ow(tR^edFm(c%U&@b<8bD`#7q9TiU1}LdD+6-GT|iV
zU`#^^-Ju8c1hbnvT?s?!CmnxdsuaR1A$S~<C3ZRn?sbfF#PJw_xgHammE4a>0bn0w
z;7-UmhrU!PKynD5J`t5uE5w$!cS4t-PKHPr){SB!5NC4Lptp9-Tt2&w`*`W%*qn&`
z(qaG(00NW+U{*!s62K8q0gePV&CVnP5Wx$rK+zCL%5B{lSP)G+D*QjFe{6G<0UiCm
zo4|2MKpfs&x@fLigohA<S1TMm1oplVR0N#b{*(Cnpr12<9_2@rp<y^O47a!B_7fbO
zgJW}WXb!ifB}L?zz+q!tf*u7t#<eNduN5cc2CySSEdUWVM&1;?WjlOYhl$fm(jpX$
za9XgdacB;5Y7h<sbAh9C0Eg$GewG-Y12{kjaD)!KA5#LYl;<zgb0ICxLh6{YirGM@
zetWtPbPR=!p`bCgl_>^=p_7IMA*RU#8}EqMpk|CfEh~;BMe2U<QnTpJxAy7Qv{bU2
z5kpXhT%-|CCX65h1VRSAm$~GqT08h1c#{i7<n1CVDfH;<hLFC2;1HGsC?ZB|!e2jZ
zBB5%aq>5#PUdUXc%gSP=VnGdVEnk)*^eYwpDiG;-R|*H9h0ms|GMVtQvP>|6QBNm6
zSZ&Io*=K{zt6N7kmbKim+|X-yUR94AXR0ezcG6DDTNCK=f_56Rl#k_t#@@wj?h?q-
zMSTFYCbNmpetLP|B?7w*>p%KXfT#4^h_z;ffn_&-WateMXp^WqJv?u3%Mi$EC5+L6
z!CHYh?}czGaD;X?NFaT5BDABn+|L<)8ORud=yiKS(<JfF-+!`QHN2UX1_sslJZnIU
zB<|f9E0RD(5@8?4LMu&O2zCBTrje%QIv7;H^Q_#V>2!e41%_jR+&*lMtHA)s;TO_W
z1xA5$osE!6={^XFMCu7a%6$^mWyDL^;S99Bd}u75oLY`}SUN5`6_k|i=P&s+S&9Kx
z*%JcSO)$zGr0jGlhci?%f>9kT*iz>@1uz9PKTVbp&0}B{lVBT+VU=H5M<HyVeddYq
z;I)_NA(w|)Aj_w=&oeluO9wzVKcq54B8;*#+ENOmD}xujvSF>keRRS9ZA%LiYO;%D
zC=kf>830U72D4#~^gKca%O(H>d|Q4A!`up$(j9S1LrY#o0%~_uc3jIBd4MO|kl%E#
z3*lD8L6bRVGBXxqK*<aynLAPtSQ7$j0^EJxo;+@C4BT4G!paC_+9AunSeFLQC{e!1
z3q0BWExH7H*K4N#b=L?GeNcG@73XqogUaWdy#0#+z%3VwU`I-kBn@ETq)KQ&aMB3<
z@~<Ob>j%-3s5V}LN~qyCe%X%1+d|q;aTY>S9F9>C;w>09e|hoMF1ubP(FyAu6x4b`
zkp3U^xi!O?{w+&R%waz$17SkUNk(vm{0{B&+ENXf6j#CFWh>Eu3UUwyappLmfQ!ls
zf<2H7${A8PoCuV01r``2I-#1*!1gIc2(BPLsx}=e`T}|*(+M$w=MP20n%FgQuf<~Y
zn@o-!!pKqyUE?~01!Eu#OhagfL5?7T4kkc0>Cn{Sa;-p0;fPTMatLdYkjl_C?p03>
zqvWF?agicM290FC<$e-<i4*pQT}NxvfrhfU<#IeeoS_-f%P*Za^+FlzPd|F`mSR9_
z++lGj0azf;r2;yEcodm;SSdGt5Oj4~kb>7k;P7os48-i8*n;B|Jj+KNYYd%bmi(B}
z6MgB!EXig~&5nXX*HO7U0JDyR@^|<iOuh)fB4`1y7+OF;w}dA!CDA=u#j^5?pH=ex
zQm<wADVtM}T`s2}8UMDGpI+hVqrN#NtKz&$IR#~_CgUE->T_u0@IB9}b};vjS_e;D
zU+<a*4>ias7~1&TrX^aGZS`>L)hG98+bu7rpniu2onAOCr(i*sO<g;jmD{8G**U#m
z?lZsNg9Dx(v};Js;pdGQFlzAVoPxu~b6&Hs<f$Sni32J6Y7j*gQR7DS>%|d%&Y{<8
z)d8QFnE!wiNHOXg<?}uX!ulw|=$xlEq<FNtsvmi+nVEVmtoSrhQwc#OAfI@oXrFoQ
z+MJ?U|IL9CO>q)Ez;mf{i$a{xnj@n+z^D|@T0mJe5Q$KnLc}Hd6li@kV$=m>^<77V
z-yJDw-m1-;v>TT^(ye1@gqlYiY*Q;&yj;Iyp5&pXp7LV(i3xP#IlH)DQB@pB0vz&L
zP&d;!r*k<CoNW0XkeJDSG~msAYa=bYUTp7pQ?}_@ICKtMhAPdQ_eqOZ4R*kHdbI;4
zyN>$gpbr#aR3}^&Wv8S!D|#)^@U>3=ekt@+Iulfk&lW`A8YDiNH_3*TPGz>*DvUOO
z5UiURg9KkDt;Be?rU1;O9{N5;l1Wxqt5<Q~RYlt*#HPJ%K9A!qu$_dqgecx&4@(5C
zChmycWXQ=Uiu)jI$^Hs~k$}aIx0gfUYJ9*TBZBA?lu+KlV|fF17EJtu?n~C(N9@-|
zrtwASwmB&l``vOhWf=16aw91oZ5O>{1$4LPMem+xU$#T=I3;q52U&AR^suQ$vHft&
zDCLeK=Fp81r!o1>_U<8pVu>rgV1T*Ud($%5SL#Wo-6^eFQjbnoG*3ONRR-I27bk|@
z1jGRww~-Ln0RmGn8-F0NVMuTog9n~7f5JgmJjU7;y!k8-)GE6N?}P^B5J-$q>w^{~
zf9~x&ytMW??u{N+*P$YFIBP;U;1%m<n>}@{8i{=e#_&+gZrEK%pP$&>F~2d!9`qC@
zyihYNt*hs8+tW7R^KHi_Dg?8|6}5)E?!=A55TMVB&lh<7J#i6nFP<<30q!z%7=tWO
z*$-(W@#rTN;C61%*+~;I^090vr(eZA=kyqAcZ6rP9J5a@gMIdeMV#3u2iHV8qo!ZQ
zo$DI=c;_NcS(D_jh|=YxXVAnHzT}Z^tzia8)G!A5Ma4BPxm`%No~y2$IU_K3v7SZ1
z&R+=;n1-w(l0p!Wc7?~3?u3yLg)@qBMByitd+z06Cd@-$YL8X~n&m<VlawAZGcqVQ
z&`|P9Ppnj9B$_QgQ~morWz&*inmsAD{EYR3>V+BEc<S!coBq(?hpLcSilRn!LwbP0
zTE|yB?$~I1oim=5tR&}X6h6he>i_N5G5fa>Yjn~D3lJ+PX~W^!u9fm=ra%7hy&kkV
z)R|`Tq=_w~NICF01b@#2Wvo4ZVG|@agcV|(wRHlGdos6-De}7=4SqR>gt=6_m<<gJ
zKbom)q1gB(dA-B3BU3ayu!>&LIp3_1ci=Pd$OIt)!vM14TmWoM!akDQvEI8FSCoP!
z28)yExa?WCV&6QLyj)0fSd!{4bd{hPt|=+>0v}#gUHYBq9E!w?#x0!9M51}^>Y74n
z208M8ChQAa^<5(f7(_}_7^aA0T|hHvj@evn=0W4%T2>x5P;K`fyi>2x3+k(nc~##>
zK{KPxIW^?!p5j3966Pxv75V<&lvaq_Cc}5?aA4X{yD2{F;fW<0_huo3A4HcQxMzgE
z3GQO@a%f70A{~;07leb*)J~E>@OCC-B2onDEOJ=qsG<*YSW!Qx^^ngMd-WjuCJs<w
z`K|}PKZ$-3q%vyiOZtgacz${C(_((IJx_JxAqQU9)i9UwFzrFOPpOkZQZ9N14Gu6h
z94{u?`7O}1Rb+TEf$FAXB~&fIFveE}{KSeXtETQdMxHD|Idm%K#zKg3pXs%ybk|Yb
z=b6W%aq&%@uBWYATvB2E^jZ5+`*x;Pj;V);A|YFr@dA_vTR8-%ypgR|2BQwdEY4E;
z7vOyYPM_MrK=51&1FdhmSt-=AaM&as#`Sk!8wzBw`$^bL$wW+&UP@FsQsaUEdMQ3t
zEHs2VZ*_!%aNxf}Lo3<eN;u!TXn2|<8AW>XH2LIRqNVXtgl##*&&jeaV;;vZ@-`uJ
zYjT1iIy$4oQw>}teg#%!G(Y1azkcGmp3JCs3;bTG(dV5zl9&f}3ic*tmr<5xGx(xn
z0j(V?>C`RNVAdMgm<Rm0OQ{+3le0<7=_9Uabg1Zv(68P~{{yq6Z>QmJq;(DcQx26k
z3ZLkTm9&uw&~YMX4qf-Cap*BFv<7D7puA|h%`sF_v}%zlx;Oe$Ob~gcH^oFXpc;L?
zPMP4P{npKK{AFlip%Fov+$h!9Fp9m=zl^|L6soAtyeMAu(Xsq<sC&*+4$Q{dm)5-;
z#JK^-QQH2~&lnp9{T2(|b-<{p>9E$g#y5isP<|{^;n|7HmOD{7iz+%!xA6`sI`-!J
zbynfZ4@Sd1$KQOBi68?VRSCSg%wh*Nf>)jvfb-C<@(d|JEzBbt>WTp|JlXSM;FmIF
z^xcn%I)@tdw5=>Vyr_$$4+fCBCVERkCSEW^Mu1Rx_*RiDj%+8H0CFtV<($u}VjW;b
zv9(m3uGtqoWqcfDH2y6v%o11scCZXBD733Opx2U0Uz%y1s`Gs!yiu~(5%tHDbww>x
z@>+2;t)nqpR@x>#iv}e;b%`FG6a9^eavq7^KhgFmFX1Wh>R{`Z&C)vA-5YqJUa}N=
zKFT#ZiX_-Vf*;8jCBeR+{{R^1)kh3(kJr?t^R-YI_#S#DRi7-;DtD$Y!o-){*@Eop
z-dp%<ufOr80x$mg7hit0ansk|Y~J$i)@>yGGZS0<wsY6+-}mg@_lNZwp#AAgl?gnX
z-m6NlKM!t3l<4M|4ziy7j={_y+(zojlCoLE=>LsAbx6WK%%g0l5T|e~HHJ#}J60K?
z!=!5&mPxfxStWM@W6`^3kM2zj0pv_DdIm35Wxg@!qsIpuDgxjb>Eed~o>+Mwh9p4v
zhe%ccOHF{|Xmy4WTfC1O1n4Ofz)k;M+P|deLTsjD|AB*llGhRa6)!C%)|;axwoRZU
zpoKAVEU|%RNa?gt)dbwW>9Qy}n&Fa*rx9l)$Kk{=a-!9f{s*i>d{>jbuO4&P`&
zl~FgmM;}@K@B_>4Te8>_OhnzgRYVF$L)`0Zyrrws)3oGNA#lV-Z&nou2;O3VCHDXj
z8~|7*D24$?6K1Mmc;Us!aYN9a3?<gY9y<Y2*LsmBSDwJBzEeJtHMhkvO3c7ZRVs5o
z^$G-N2U}9}V9B<=fQE(uut2peLuxBfq++ti6sCeVA+*J-Z#(8u2<dh}`}8v}dBXoG
zsq+_wP`nQcI`$mXv${rP-eva}1(b{{9+ZR1>$3U*quCF55j+;4!5^5}MSmu?Sf)$s
zcep^;2o>!(bZapTZN6INIed)Lx+$RjWCf<M{XTB3))MT11lX&vqP2x1&CqvL*QeFy
z5k;PjeraGi%u!k#l*=21FnrF*3rrG&)v$)!p+#ZDgKBM=(|zSi(P39ARc6muh3;ul
zo;B^;pc;w2n=<&D!)ohc;8b2a?C>O}G7WpT<kv@SBaMDHzI-H4=jr@(3lPF7p{aBV
zEulP`AsZ*yfe3c1+WuJa2rMAX$H*zxxUU!<Hf6=$Z<zbB^e|NV&BomtOVG~nd;`1&
z8XfP|6f>)$WOm1|q$`f_<lWM%*R;Bpf^%esh))cxOwts6I?4`M7L=Ruqr5I@W?`Qn
z@b{-xHPq2>m<#v%DjSENhi;%72|h93wa^jvQ!_)yMe_<G^CxzO9GHwq{YRcNeCXhT
z{rmRn*#nC|yPV$n)RS8iqfy8AxmIqq6FksTEl71Ji7}Q9fa*}CDx3gN4XWEvD?qph
zXbc=gg<2e9WGQF?*lQLre9kEVZLmP79ppiKjHwKmYKYPvxP>7QQ&J$oL$Ob$1E~!o
zRO?YnMHfw;0#k|PA6&SoaZnk$0Y{UpT>Oy|tx8QQ^=PRMWmaU@KXh8zQstohPZc&C
zz2n&J$M@SbvdWAq^Q-jR#Qt@tW~G9Cx2UnJ=0&v|)*-c5*CT(sHn3W*YB;0up-q2j
z&hph;&1t=&^~jTpwK=0*>Gs=Bt&{&l$Fn*&I(^X@_nvuwx24^$>$&ah2EFI?y{P}?
z1A7ggGqm5P2ZsMTV)dvR=f66p(byf^fBa$Fw_7%UL!>pUiL9LfmN_(}9&aa%FTiAk
zP2kyiwMMRm2pbU)g@c_`tB&#N_(uzAhMi2U>&9;qVjiH09^lTlR5doYE)XCyD-C_@
zl$_{`Etq);0nvb=02s%cl#JlT&R5lug}YXy;BJ1bZ;=sF03=N#Ql__NXAus8t3W%i
z(3-t_*vvV^s!yTKDIltJxn*W4c-)M+mxd=HnHZCXIcREvOB^F388cG#3W?bXBzA+*
z{Rhy&bfLi%Jx8XKzA9!^oof;ye}FI|kFbEc+-k)!S4l8tGY`r9(Z}mQ+2F0)B(~DT
ztm&`6(LX67yHwsbZju*b>)n3a{9B700wUlT$V`b8#UeDT<8}`~yHiPTskygG<(rE*
zczg!cvN9RM#K`Xms7^3wSCR?M+cVj3BleIuMF(&uaLqoR$&3e8#x4!BXo%1Bd2=$T
za<Q!Jo!L9v(ZBx`Bk3srww4Uu>h02R<@nWJcbH#|qU*s&0NZ3K@i&WB^$cIt<z?Jn
zn6Uo=O;`OtWL=zvP-SA&=(FiY{pswtE_t0h3Ko}s1*=x5X2qpgxj}FGWwiXV48J_2
zl5SR=dGcna9b$6ry4_;G^k%u@GIe#l80^I{rUY7vwR~+4c>Nn$-0P}y%~Fy@4*SM~
s>&5iT(z2VXxy7>HDOIy#{kcTNT(xA@x}8TAr)&L-z?S^%5gYgX52PAb82|tP
literal 0
HcmV?d00001
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/tests/roaring/mod.rs b/rust/hw/char/pl011/vendor/unicode-ident/tests/roaring/mod.rs
new file mode 100644
index 0000000000..3f558fffe8
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/tests/roaring/mod.rs
@@ -0,0 +1,21 @@
+use roaring::RoaringBitmap;
+
+pub fn xid_start_bitmap() -> RoaringBitmap {
+ let mut bitmap = RoaringBitmap::new();
+ for ch in '\0'..=char::MAX {
+ if unicode_ident::is_xid_start(ch) {
+ bitmap.insert(ch as u32);
+ }
+ }
+ bitmap
+}
+
+pub fn xid_continue_bitmap() -> RoaringBitmap {
+ let mut bitmap = RoaringBitmap::new();
+ for ch in '\0'..=char::MAX {
+ if unicode_ident::is_xid_continue(ch) {
+ bitmap.insert(ch as u32);
+ }
+ }
+ bitmap
+}
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/tests/static_size.rs b/rust/hw/char/pl011/vendor/unicode-ident/tests/static_size.rs
new file mode 100644
index 0000000000..2df35373c9
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/tests/static_size.rs
@@ -0,0 +1,95 @@
+#![allow(clippy::let_underscore_untyped, clippy::unreadable_literal)]
+
+use std::mem::size_of_val;
+
+#[test]
+fn test_size() {
+ #[allow(dead_code)]
+ #[path = "../src/tables.rs"]
+ mod tables;
+
+ let size = size_of_val(&tables::ASCII_START)
+ + size_of_val(&tables::ASCII_CONTINUE)
+ + size_of_val(&tables::TRIE_START)
+ + size_of_val(&tables::TRIE_CONTINUE)
+ + size_of_val(&tables::LEAF);
+ assert_eq!(10080, size);
+}
+
+#[test]
+fn test_xid_size() {
+ #[deny(dead_code)]
+ #[path = "tables/mod.rs"]
+ mod tables;
+
+ let size = size_of_val(tables::XID_START) + size_of_val(tables::XID_CONTINUE);
+ assert_eq!(11544, size);
+
+ let _ = tables::BY_NAME;
+}
+
+#[cfg(target_pointer_width = "64")]
+#[test]
+fn test_trieset_size() {
+ #[deny(dead_code)]
+ #[allow(clippy::redundant_static_lifetimes)]
+ #[path = "trie/trie.rs"]
+ mod trie;
+
+ let ucd_trie::TrieSet {
+ tree1_level1,
+ tree2_level1,
+ tree2_level2,
+ tree3_level1,
+ tree3_level2,
+ tree3_level3,
+ } = *trie::XID_START;
+
+ let start_size = size_of_val(trie::XID_START)
+ + size_of_val(tree1_level1)
+ + size_of_val(tree2_level1)
+ + size_of_val(tree2_level2)
+ + size_of_val(tree3_level1)
+ + size_of_val(tree3_level2)
+ + size_of_val(tree3_level3);
+
+ let ucd_trie::TrieSet {
+ tree1_level1,
+ tree2_level1,
+ tree2_level2,
+ tree3_level1,
+ tree3_level2,
+ tree3_level3,
+ } = *trie::XID_CONTINUE;
+
+ let continue_size = size_of_val(trie::XID_CONTINUE)
+ + size_of_val(tree1_level1)
+ + size_of_val(tree2_level1)
+ + size_of_val(tree2_level2)
+ + size_of_val(tree3_level1)
+ + size_of_val(tree3_level2)
+ + size_of_val(tree3_level3);
+
+ assert_eq!(10200, start_size + continue_size);
+
+ let _ = trie::BY_NAME;
+}
+
+#[test]
+fn test_fst_size() {
+ let xid_start_fst = include_bytes!("fst/xid_start.fst");
+ let xid_continue_fst = include_bytes!("fst/xid_continue.fst");
+ let size = xid_start_fst.len() + xid_continue_fst.len();
+ assert_eq!(138736, size);
+}
+
+#[test]
+fn test_roaring_size() {
+ #[path = "roaring/mod.rs"]
+ mod roaring;
+
+ let xid_start_bitmap = roaring::xid_start_bitmap();
+ let xid_continue_bitmap = roaring::xid_continue_bitmap();
+ let size = xid_start_bitmap.serialized_size() + xid_continue_bitmap.serialized_size();
+ assert_eq!(66104, size);
+}
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/tests/tables/mod.rs b/rust/hw/char/pl011/vendor/unicode-ident/tests/tables/mod.rs
new file mode 100644
index 0000000000..72bfd8bd7b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/tests/tables/mod.rs
@@ -0,0 +1,7 @@
+#![allow(clippy::module_inception)]
+
+#[allow(clippy::redundant_static_lifetimes)]
+#[rustfmt::skip]
+mod tables;
+
+pub(crate) use self::tables::*;
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/tests/tables/tables.rs b/rust/hw/char/pl011/vendor/unicode-ident/tests/tables/tables.rs
new file mode 100644
index 0000000000..ba7b0612db
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/tests/tables/tables.rs
@@ -0,0 +1,347 @@
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+// ucd-generate property-bool UCD --include XID_Start,XID_Continue
+//
+// Unicode version: 15.1.0.
+//
+// ucd-generate 0.3.0 is available on crates.io.
+
+pub const BY_NAME: &'static [(&'static str, &'static [(u32, u32)])] = &[
+ ("XID_Continue", XID_CONTINUE), ("XID_Start", XID_START),
+];
+
+pub const XID_CONTINUE: &'static [(u32, u32)] = &[
+ (48, 57), (65, 90), (95, 95), (97, 122), (170, 170), (181, 181), (183, 183),
+ (186, 186), (192, 214), (216, 246), (248, 705), (710, 721), (736, 740),
+ (748, 748), (750, 750), (768, 884), (886, 887), (891, 893), (895, 895),
+ (902, 906), (908, 908), (910, 929), (931, 1013), (1015, 1153), (1155, 1159),
+ (1162, 1327), (1329, 1366), (1369, 1369), (1376, 1416), (1425, 1469),
+ (1471, 1471), (1473, 1474), (1476, 1477), (1479, 1479), (1488, 1514),
+ (1519, 1522), (1552, 1562), (1568, 1641), (1646, 1747), (1749, 1756),
+ (1759, 1768), (1770, 1788), (1791, 1791), (1808, 1866), (1869, 1969),
+ (1984, 2037), (2042, 2042), (2045, 2045), (2048, 2093), (2112, 2139),
+ (2144, 2154), (2160, 2183), (2185, 2190), (2200, 2273), (2275, 2403),
+ (2406, 2415), (2417, 2435), (2437, 2444), (2447, 2448), (2451, 2472),
+ (2474, 2480), (2482, 2482), (2486, 2489), (2492, 2500), (2503, 2504),
+ (2507, 2510), (2519, 2519), (2524, 2525), (2527, 2531), (2534, 2545),
+ (2556, 2556), (2558, 2558), (2561, 2563), (2565, 2570), (2575, 2576),
+ (2579, 2600), (2602, 2608), (2610, 2611), (2613, 2614), (2616, 2617),
+ (2620, 2620), (2622, 2626), (2631, 2632), (2635, 2637), (2641, 2641),
+ (2649, 2652), (2654, 2654), (2662, 2677), (2689, 2691), (2693, 2701),
+ (2703, 2705), (2707, 2728), (2730, 2736), (2738, 2739), (2741, 2745),
+ (2748, 2757), (2759, 2761), (2763, 2765), (2768, 2768), (2784, 2787),
+ (2790, 2799), (2809, 2815), (2817, 2819), (2821, 2828), (2831, 2832),
+ (2835, 2856), (2858, 2864), (2866, 2867), (2869, 2873), (2876, 2884),
+ (2887, 2888), (2891, 2893), (2901, 2903), (2908, 2909), (2911, 2915),
+ (2918, 2927), (2929, 2929), (2946, 2947), (2949, 2954), (2958, 2960),
+ (2962, 2965), (2969, 2970), (2972, 2972), (2974, 2975), (2979, 2980),
+ (2984, 2986), (2990, 3001), (3006, 3010), (3014, 3016), (3018, 3021),
+ (3024, 3024), (3031, 3031), (3046, 3055), (3072, 3084), (3086, 3088),
+ (3090, 3112), (3114, 3129), (3132, 3140), (3142, 3144), (3146, 3149),
+ (3157, 3158), (3160, 3162), (3165, 3165), (3168, 3171), (3174, 3183),
+ (3200, 3203), (3205, 3212), (3214, 3216), (3218, 3240), (3242, 3251),
+ (3253, 3257), (3260, 3268), (3270, 3272), (3274, 3277), (3285, 3286),
+ (3293, 3294), (3296, 3299), (3302, 3311), (3313, 3315), (3328, 3340),
+ (3342, 3344), (3346, 3396), (3398, 3400), (3402, 3406), (3412, 3415),
+ (3423, 3427), (3430, 3439), (3450, 3455), (3457, 3459), (3461, 3478),
+ (3482, 3505), (3507, 3515), (3517, 3517), (3520, 3526), (3530, 3530),
+ (3535, 3540), (3542, 3542), (3544, 3551), (3558, 3567), (3570, 3571),
+ (3585, 3642), (3648, 3662), (3664, 3673), (3713, 3714), (3716, 3716),
+ (3718, 3722), (3724, 3747), (3749, 3749), (3751, 3773), (3776, 3780),
+ (3782, 3782), (3784, 3790), (3792, 3801), (3804, 3807), (3840, 3840),
+ (3864, 3865), (3872, 3881), (3893, 3893), (3895, 3895), (3897, 3897),
+ (3902, 3911), (3913, 3948), (3953, 3972), (3974, 3991), (3993, 4028),
+ (4038, 4038), (4096, 4169), (4176, 4253), (4256, 4293), (4295, 4295),
+ (4301, 4301), (4304, 4346), (4348, 4680), (4682, 4685), (4688, 4694),
+ (4696, 4696), (4698, 4701), (4704, 4744), (4746, 4749), (4752, 4784),
+ (4786, 4789), (4792, 4798), (4800, 4800), (4802, 4805), (4808, 4822),
+ (4824, 4880), (4882, 4885), (4888, 4954), (4957, 4959), (4969, 4977),
+ (4992, 5007), (5024, 5109), (5112, 5117), (5121, 5740), (5743, 5759),
+ (5761, 5786), (5792, 5866), (5870, 5880), (5888, 5909), (5919, 5940),
+ (5952, 5971), (5984, 5996), (5998, 6000), (6002, 6003), (6016, 6099),
+ (6103, 6103), (6108, 6109), (6112, 6121), (6155, 6157), (6159, 6169),
+ (6176, 6264), (6272, 6314), (6320, 6389), (6400, 6430), (6432, 6443),
+ (6448, 6459), (6470, 6509), (6512, 6516), (6528, 6571), (6576, 6601),
+ (6608, 6618), (6656, 6683), (6688, 6750), (6752, 6780), (6783, 6793),
+ (6800, 6809), (6823, 6823), (6832, 6845), (6847, 6862), (6912, 6988),
+ (6992, 7001), (7019, 7027), (7040, 7155), (7168, 7223), (7232, 7241),
+ (7245, 7293), (7296, 7304), (7312, 7354), (7357, 7359), (7376, 7378),
+ (7380, 7418), (7424, 7957), (7960, 7965), (7968, 8005), (8008, 8013),
+ (8016, 8023), (8025, 8025), (8027, 8027), (8029, 8029), (8031, 8061),
+ (8064, 8116), (8118, 8124), (8126, 8126), (8130, 8132), (8134, 8140),
+ (8144, 8147), (8150, 8155), (8160, 8172), (8178, 8180), (8182, 8188),
+ (8204, 8205), (8255, 8256), (8276, 8276), (8305, 8305), (8319, 8319),
+ (8336, 8348), (8400, 8412), (8417, 8417), (8421, 8432), (8450, 8450),
+ (8455, 8455), (8458, 8467), (8469, 8469), (8472, 8477), (8484, 8484),
+ (8486, 8486), (8488, 8488), (8490, 8505), (8508, 8511), (8517, 8521),
+ (8526, 8526), (8544, 8584), (11264, 11492), (11499, 11507), (11520, 11557),
+ (11559, 11559), (11565, 11565), (11568, 11623), (11631, 11631),
+ (11647, 11670), (11680, 11686), (11688, 11694), (11696, 11702),
+ (11704, 11710), (11712, 11718), (11720, 11726), (11728, 11734),
+ (11736, 11742), (11744, 11775), (12293, 12295), (12321, 12335),
+ (12337, 12341), (12344, 12348), (12353, 12438), (12441, 12442),
+ (12445, 12447), (12449, 12543), (12549, 12591), (12593, 12686),
+ (12704, 12735), (12784, 12799), (13312, 19903), (19968, 42124),
+ (42192, 42237), (42240, 42508), (42512, 42539), (42560, 42607),
+ (42612, 42621), (42623, 42737), (42775, 42783), (42786, 42888),
+ (42891, 42954), (42960, 42961), (42963, 42963), (42965, 42969),
+ (42994, 43047), (43052, 43052), (43072, 43123), (43136, 43205),
+ (43216, 43225), (43232, 43255), (43259, 43259), (43261, 43309),
+ (43312, 43347), (43360, 43388), (43392, 43456), (43471, 43481),
+ (43488, 43518), (43520, 43574), (43584, 43597), (43600, 43609),
+ (43616, 43638), (43642, 43714), (43739, 43741), (43744, 43759),
+ (43762, 43766), (43777, 43782), (43785, 43790), (43793, 43798),
+ (43808, 43814), (43816, 43822), (43824, 43866), (43868, 43881),
+ (43888, 44010), (44012, 44013), (44016, 44025), (44032, 55203),
+ (55216, 55238), (55243, 55291), (63744, 64109), (64112, 64217),
+ (64256, 64262), (64275, 64279), (64285, 64296), (64298, 64310),
+ (64312, 64316), (64318, 64318), (64320, 64321), (64323, 64324),
+ (64326, 64433), (64467, 64605), (64612, 64829), (64848, 64911),
+ (64914, 64967), (65008, 65017), (65024, 65039), (65056, 65071),
+ (65075, 65076), (65101, 65103), (65137, 65137), (65139, 65139),
+ (65143, 65143), (65145, 65145), (65147, 65147), (65149, 65149),
+ (65151, 65276), (65296, 65305), (65313, 65338), (65343, 65343),
+ (65345, 65370), (65381, 65470), (65474, 65479), (65482, 65487),
+ (65490, 65495), (65498, 65500), (65536, 65547), (65549, 65574),
+ (65576, 65594), (65596, 65597), (65599, 65613), (65616, 65629),
+ (65664, 65786), (65856, 65908), (66045, 66045), (66176, 66204),
+ (66208, 66256), (66272, 66272), (66304, 66335), (66349, 66378),
+ (66384, 66426), (66432, 66461), (66464, 66499), (66504, 66511),
+ (66513, 66517), (66560, 66717), (66720, 66729), (66736, 66771),
+ (66776, 66811), (66816, 66855), (66864, 66915), (66928, 66938),
+ (66940, 66954), (66956, 66962), (66964, 66965), (66967, 66977),
+ (66979, 66993), (66995, 67001), (67003, 67004), (67072, 67382),
+ (67392, 67413), (67424, 67431), (67456, 67461), (67463, 67504),
+ (67506, 67514), (67584, 67589), (67592, 67592), (67594, 67637),
+ (67639, 67640), (67644, 67644), (67647, 67669), (67680, 67702),
+ (67712, 67742), (67808, 67826), (67828, 67829), (67840, 67861),
+ (67872, 67897), (67968, 68023), (68030, 68031), (68096, 68099),
+ (68101, 68102), (68108, 68115), (68117, 68119), (68121, 68149),
+ (68152, 68154), (68159, 68159), (68192, 68220), (68224, 68252),
+ (68288, 68295), (68297, 68326), (68352, 68405), (68416, 68437),
+ (68448, 68466), (68480, 68497), (68608, 68680), (68736, 68786),
+ (68800, 68850), (68864, 68903), (68912, 68921), (69248, 69289),
+ (69291, 69292), (69296, 69297), (69373, 69404), (69415, 69415),
+ (69424, 69456), (69488, 69509), (69552, 69572), (69600, 69622),
+ (69632, 69702), (69734, 69749), (69759, 69818), (69826, 69826),
+ (69840, 69864), (69872, 69881), (69888, 69940), (69942, 69951),
+ (69956, 69959), (69968, 70003), (70006, 70006), (70016, 70084),
+ (70089, 70092), (70094, 70106), (70108, 70108), (70144, 70161),
+ (70163, 70199), (70206, 70209), (70272, 70278), (70280, 70280),
+ (70282, 70285), (70287, 70301), (70303, 70312), (70320, 70378),
+ (70384, 70393), (70400, 70403), (70405, 70412), (70415, 70416),
+ (70419, 70440), (70442, 70448), (70450, 70451), (70453, 70457),
+ (70459, 70468), (70471, 70472), (70475, 70477), (70480, 70480),
+ (70487, 70487), (70493, 70499), (70502, 70508), (70512, 70516),
+ (70656, 70730), (70736, 70745), (70750, 70753), (70784, 70853),
+ (70855, 70855), (70864, 70873), (71040, 71093), (71096, 71104),
+ (71128, 71133), (71168, 71232), (71236, 71236), (71248, 71257),
+ (71296, 71352), (71360, 71369), (71424, 71450), (71453, 71467),
+ (71472, 71481), (71488, 71494), (71680, 71738), (71840, 71913),
+ (71935, 71942), (71945, 71945), (71948, 71955), (71957, 71958),
+ (71960, 71989), (71991, 71992), (71995, 72003), (72016, 72025),
+ (72096, 72103), (72106, 72151), (72154, 72161), (72163, 72164),
+ (72192, 72254), (72263, 72263), (72272, 72345), (72349, 72349),
+ (72368, 72440), (72704, 72712), (72714, 72758), (72760, 72768),
+ (72784, 72793), (72818, 72847), (72850, 72871), (72873, 72886),
+ (72960, 72966), (72968, 72969), (72971, 73014), (73018, 73018),
+ (73020, 73021), (73023, 73031), (73040, 73049), (73056, 73061),
+ (73063, 73064), (73066, 73102), (73104, 73105), (73107, 73112),
+ (73120, 73129), (73440, 73462), (73472, 73488), (73490, 73530),
+ (73534, 73538), (73552, 73561), (73648, 73648), (73728, 74649),
+ (74752, 74862), (74880, 75075), (77712, 77808), (77824, 78895),
+ (78912, 78933), (82944, 83526), (92160, 92728), (92736, 92766),
+ (92768, 92777), (92784, 92862), (92864, 92873), (92880, 92909),
+ (92912, 92916), (92928, 92982), (92992, 92995), (93008, 93017),
+ (93027, 93047), (93053, 93071), (93760, 93823), (93952, 94026),
+ (94031, 94087), (94095, 94111), (94176, 94177), (94179, 94180),
+ (94192, 94193), (94208, 100343), (100352, 101589), (101632, 101640),
+ (110576, 110579), (110581, 110587), (110589, 110590), (110592, 110882),
+ (110898, 110898), (110928, 110930), (110933, 110933), (110948, 110951),
+ (110960, 111355), (113664, 113770), (113776, 113788), (113792, 113800),
+ (113808, 113817), (113821, 113822), (118528, 118573), (118576, 118598),
+ (119141, 119145), (119149, 119154), (119163, 119170), (119173, 119179),
+ (119210, 119213), (119362, 119364), (119808, 119892), (119894, 119964),
+ (119966, 119967), (119970, 119970), (119973, 119974), (119977, 119980),
+ (119982, 119993), (119995, 119995), (119997, 120003), (120005, 120069),
+ (120071, 120074), (120077, 120084), (120086, 120092), (120094, 120121),
+ (120123, 120126), (120128, 120132), (120134, 120134), (120138, 120144),
+ (120146, 120485), (120488, 120512), (120514, 120538), (120540, 120570),
+ (120572, 120596), (120598, 120628), (120630, 120654), (120656, 120686),
+ (120688, 120712), (120714, 120744), (120746, 120770), (120772, 120779),
+ (120782, 120831), (121344, 121398), (121403, 121452), (121461, 121461),
+ (121476, 121476), (121499, 121503), (121505, 121519), (122624, 122654),
+ (122661, 122666), (122880, 122886), (122888, 122904), (122907, 122913),
+ (122915, 122916), (122918, 122922), (122928, 122989), (123023, 123023),
+ (123136, 123180), (123184, 123197), (123200, 123209), (123214, 123214),
+ (123536, 123566), (123584, 123641), (124112, 124153), (124896, 124902),
+ (124904, 124907), (124909, 124910), (124912, 124926), (124928, 125124),
+ (125136, 125142), (125184, 125259), (125264, 125273), (126464, 126467),
+ (126469, 126495), (126497, 126498), (126500, 126500), (126503, 126503),
+ (126505, 126514), (126516, 126519), (126521, 126521), (126523, 126523),
+ (126530, 126530), (126535, 126535), (126537, 126537), (126539, 126539),
+ (126541, 126543), (126545, 126546), (126548, 126548), (126551, 126551),
+ (126553, 126553), (126555, 126555), (126557, 126557), (126559, 126559),
+ (126561, 126562), (126564, 126564), (126567, 126570), (126572, 126578),
+ (126580, 126583), (126585, 126588), (126590, 126590), (126592, 126601),
+ (126603, 126619), (126625, 126627), (126629, 126633), (126635, 126651),
+ (130032, 130041), (131072, 173791), (173824, 177977), (177984, 178205),
+ (178208, 183969), (183984, 191456), (191472, 192093), (194560, 195101),
+ (196608, 201546), (201552, 205743), (917760, 917999),
+];
+
+pub const XID_START: &'static [(u32, u32)] = &[
+ (65, 90), (97, 122), (170, 170), (181, 181), (186, 186), (192, 214),
+ (216, 246), (248, 705), (710, 721), (736, 740), (748, 748), (750, 750),
+ (880, 884), (886, 887), (891, 893), (895, 895), (902, 902), (904, 906),
+ (908, 908), (910, 929), (931, 1013), (1015, 1153), (1162, 1327),
+ (1329, 1366), (1369, 1369), (1376, 1416), (1488, 1514), (1519, 1522),
+ (1568, 1610), (1646, 1647), (1649, 1747), (1749, 1749), (1765, 1766),
+ (1774, 1775), (1786, 1788), (1791, 1791), (1808, 1808), (1810, 1839),
+ (1869, 1957), (1969, 1969), (1994, 2026), (2036, 2037), (2042, 2042),
+ (2048, 2069), (2074, 2074), (2084, 2084), (2088, 2088), (2112, 2136),
+ (2144, 2154), (2160, 2183), (2185, 2190), (2208, 2249), (2308, 2361),
+ (2365, 2365), (2384, 2384), (2392, 2401), (2417, 2432), (2437, 2444),
+ (2447, 2448), (2451, 2472), (2474, 2480), (2482, 2482), (2486, 2489),
+ (2493, 2493), (2510, 2510), (2524, 2525), (2527, 2529), (2544, 2545),
+ (2556, 2556), (2565, 2570), (2575, 2576), (2579, 2600), (2602, 2608),
+ (2610, 2611), (2613, 2614), (2616, 2617), (2649, 2652), (2654, 2654),
+ (2674, 2676), (2693, 2701), (2703, 2705), (2707, 2728), (2730, 2736),
+ (2738, 2739), (2741, 2745), (2749, 2749), (2768, 2768), (2784, 2785),
+ (2809, 2809), (2821, 2828), (2831, 2832), (2835, 2856), (2858, 2864),
+ (2866, 2867), (2869, 2873), (2877, 2877), (2908, 2909), (2911, 2913),
+ (2929, 2929), (2947, 2947), (2949, 2954), (2958, 2960), (2962, 2965),
+ (2969, 2970), (2972, 2972), (2974, 2975), (2979, 2980), (2984, 2986),
+ (2990, 3001), (3024, 3024), (3077, 3084), (3086, 3088), (3090, 3112),
+ (3114, 3129), (3133, 3133), (3160, 3162), (3165, 3165), (3168, 3169),
+ (3200, 3200), (3205, 3212), (3214, 3216), (3218, 3240), (3242, 3251),
+ (3253, 3257), (3261, 3261), (3293, 3294), (3296, 3297), (3313, 3314),
+ (3332, 3340), (3342, 3344), (3346, 3386), (3389, 3389), (3406, 3406),
+ (3412, 3414), (3423, 3425), (3450, 3455), (3461, 3478), (3482, 3505),
+ (3507, 3515), (3517, 3517), (3520, 3526), (3585, 3632), (3634, 3634),
+ (3648, 3654), (3713, 3714), (3716, 3716), (3718, 3722), (3724, 3747),
+ (3749, 3749), (3751, 3760), (3762, 3762), (3773, 3773), (3776, 3780),
+ (3782, 3782), (3804, 3807), (3840, 3840), (3904, 3911), (3913, 3948),
+ (3976, 3980), (4096, 4138), (4159, 4159), (4176, 4181), (4186, 4189),
+ (4193, 4193), (4197, 4198), (4206, 4208), (4213, 4225), (4238, 4238),
+ (4256, 4293), (4295, 4295), (4301, 4301), (4304, 4346), (4348, 4680),
+ (4682, 4685), (4688, 4694), (4696, 4696), (4698, 4701), (4704, 4744),
+ (4746, 4749), (4752, 4784), (4786, 4789), (4792, 4798), (4800, 4800),
+ (4802, 4805), (4808, 4822), (4824, 4880), (4882, 4885), (4888, 4954),
+ (4992, 5007), (5024, 5109), (5112, 5117), (5121, 5740), (5743, 5759),
+ (5761, 5786), (5792, 5866), (5870, 5880), (5888, 5905), (5919, 5937),
+ (5952, 5969), (5984, 5996), (5998, 6000), (6016, 6067), (6103, 6103),
+ (6108, 6108), (6176, 6264), (6272, 6312), (6314, 6314), (6320, 6389),
+ (6400, 6430), (6480, 6509), (6512, 6516), (6528, 6571), (6576, 6601),
+ (6656, 6678), (6688, 6740), (6823, 6823), (6917, 6963), (6981, 6988),
+ (7043, 7072), (7086, 7087), (7098, 7141), (7168, 7203), (7245, 7247),
+ (7258, 7293), (7296, 7304), (7312, 7354), (7357, 7359), (7401, 7404),
+ (7406, 7411), (7413, 7414), (7418, 7418), (7424, 7615), (7680, 7957),
+ (7960, 7965), (7968, 8005), (8008, 8013), (8016, 8023), (8025, 8025),
+ (8027, 8027), (8029, 8029), (8031, 8061), (8064, 8116), (8118, 8124),
+ (8126, 8126), (8130, 8132), (8134, 8140), (8144, 8147), (8150, 8155),
+ (8160, 8172), (8178, 8180), (8182, 8188), (8305, 8305), (8319, 8319),
+ (8336, 8348), (8450, 8450), (8455, 8455), (8458, 8467), (8469, 8469),
+ (8472, 8477), (8484, 8484), (8486, 8486), (8488, 8488), (8490, 8505),
+ (8508, 8511), (8517, 8521), (8526, 8526), (8544, 8584), (11264, 11492),
+ (11499, 11502), (11506, 11507), (11520, 11557), (11559, 11559),
+ (11565, 11565), (11568, 11623), (11631, 11631), (11648, 11670),
+ (11680, 11686), (11688, 11694), (11696, 11702), (11704, 11710),
+ (11712, 11718), (11720, 11726), (11728, 11734), (11736, 11742),
+ (12293, 12295), (12321, 12329), (12337, 12341), (12344, 12348),
+ (12353, 12438), (12445, 12447), (12449, 12538), (12540, 12543),
+ (12549, 12591), (12593, 12686), (12704, 12735), (12784, 12799),
+ (13312, 19903), (19968, 42124), (42192, 42237), (42240, 42508),
+ (42512, 42527), (42538, 42539), (42560, 42606), (42623, 42653),
+ (42656, 42735), (42775, 42783), (42786, 42888), (42891, 42954),
+ (42960, 42961), (42963, 42963), (42965, 42969), (42994, 43009),
+ (43011, 43013), (43015, 43018), (43020, 43042), (43072, 43123),
+ (43138, 43187), (43250, 43255), (43259, 43259), (43261, 43262),
+ (43274, 43301), (43312, 43334), (43360, 43388), (43396, 43442),
+ (43471, 43471), (43488, 43492), (43494, 43503), (43514, 43518),
+ (43520, 43560), (43584, 43586), (43588, 43595), (43616, 43638),
+ (43642, 43642), (43646, 43695), (43697, 43697), (43701, 43702),
+ (43705, 43709), (43712, 43712), (43714, 43714), (43739, 43741),
+ (43744, 43754), (43762, 43764), (43777, 43782), (43785, 43790),
+ (43793, 43798), (43808, 43814), (43816, 43822), (43824, 43866),
+ (43868, 43881), (43888, 44002), (44032, 55203), (55216, 55238),
+ (55243, 55291), (63744, 64109), (64112, 64217), (64256, 64262),
+ (64275, 64279), (64285, 64285), (64287, 64296), (64298, 64310),
+ (64312, 64316), (64318, 64318), (64320, 64321), (64323, 64324),
+ (64326, 64433), (64467, 64605), (64612, 64829), (64848, 64911),
+ (64914, 64967), (65008, 65017), (65137, 65137), (65139, 65139),
+ (65143, 65143), (65145, 65145), (65147, 65147), (65149, 65149),
+ (65151, 65276), (65313, 65338), (65345, 65370), (65382, 65437),
+ (65440, 65470), (65474, 65479), (65482, 65487), (65490, 65495),
+ (65498, 65500), (65536, 65547), (65549, 65574), (65576, 65594),
+ (65596, 65597), (65599, 65613), (65616, 65629), (65664, 65786),
+ (65856, 65908), (66176, 66204), (66208, 66256), (66304, 66335),
+ (66349, 66378), (66384, 66421), (66432, 66461), (66464, 66499),
+ (66504, 66511), (66513, 66517), (66560, 66717), (66736, 66771),
+ (66776, 66811), (66816, 66855), (66864, 66915), (66928, 66938),
+ (66940, 66954), (66956, 66962), (66964, 66965), (66967, 66977),
+ (66979, 66993), (66995, 67001), (67003, 67004), (67072, 67382),
+ (67392, 67413), (67424, 67431), (67456, 67461), (67463, 67504),
+ (67506, 67514), (67584, 67589), (67592, 67592), (67594, 67637),
+ (67639, 67640), (67644, 67644), (67647, 67669), (67680, 67702),
+ (67712, 67742), (67808, 67826), (67828, 67829), (67840, 67861),
+ (67872, 67897), (67968, 68023), (68030, 68031), (68096, 68096),
+ (68112, 68115), (68117, 68119), (68121, 68149), (68192, 68220),
+ (68224, 68252), (68288, 68295), (68297, 68324), (68352, 68405),
+ (68416, 68437), (68448, 68466), (68480, 68497), (68608, 68680),
+ (68736, 68786), (68800, 68850), (68864, 68899), (69248, 69289),
+ (69296, 69297), (69376, 69404), (69415, 69415), (69424, 69445),
+ (69488, 69505), (69552, 69572), (69600, 69622), (69635, 69687),
+ (69745, 69746), (69749, 69749), (69763, 69807), (69840, 69864),
+ (69891, 69926), (69956, 69956), (69959, 69959), (69968, 70002),
+ (70006, 70006), (70019, 70066), (70081, 70084), (70106, 70106),
+ (70108, 70108), (70144, 70161), (70163, 70187), (70207, 70208),
+ (70272, 70278), (70280, 70280), (70282, 70285), (70287, 70301),
+ (70303, 70312), (70320, 70366), (70405, 70412), (70415, 70416),
+ (70419, 70440), (70442, 70448), (70450, 70451), (70453, 70457),
+ (70461, 70461), (70480, 70480), (70493, 70497), (70656, 70708),
+ (70727, 70730), (70751, 70753), (70784, 70831), (70852, 70853),
+ (70855, 70855), (71040, 71086), (71128, 71131), (71168, 71215),
+ (71236, 71236), (71296, 71338), (71352, 71352), (71424, 71450),
+ (71488, 71494), (71680, 71723), (71840, 71903), (71935, 71942),
+ (71945, 71945), (71948, 71955), (71957, 71958), (71960, 71983),
+ (71999, 71999), (72001, 72001), (72096, 72103), (72106, 72144),
+ (72161, 72161), (72163, 72163), (72192, 72192), (72203, 72242),
+ (72250, 72250), (72272, 72272), (72284, 72329), (72349, 72349),
+ (72368, 72440), (72704, 72712), (72714, 72750), (72768, 72768),
+ (72818, 72847), (72960, 72966), (72968, 72969), (72971, 73008),
+ (73030, 73030), (73056, 73061), (73063, 73064), (73066, 73097),
+ (73112, 73112), (73440, 73458), (73474, 73474), (73476, 73488),
+ (73490, 73523), (73648, 73648), (73728, 74649), (74752, 74862),
+ (74880, 75075), (77712, 77808), (77824, 78895), (78913, 78918),
+ (82944, 83526), (92160, 92728), (92736, 92766), (92784, 92862),
+ (92880, 92909), (92928, 92975), (92992, 92995), (93027, 93047),
+ (93053, 93071), (93760, 93823), (93952, 94026), (94032, 94032),
+ (94099, 94111), (94176, 94177), (94179, 94179), (94208, 100343),
+ (100352, 101589), (101632, 101640), (110576, 110579), (110581, 110587),
+ (110589, 110590), (110592, 110882), (110898, 110898), (110928, 110930),
+ (110933, 110933), (110948, 110951), (110960, 111355), (113664, 113770),
+ (113776, 113788), (113792, 113800), (113808, 113817), (119808, 119892),
+ (119894, 119964), (119966, 119967), (119970, 119970), (119973, 119974),
+ (119977, 119980), (119982, 119993), (119995, 119995), (119997, 120003),
+ (120005, 120069), (120071, 120074), (120077, 120084), (120086, 120092),
+ (120094, 120121), (120123, 120126), (120128, 120132), (120134, 120134),
+ (120138, 120144), (120146, 120485), (120488, 120512), (120514, 120538),
+ (120540, 120570), (120572, 120596), (120598, 120628), (120630, 120654),
+ (120656, 120686), (120688, 120712), (120714, 120744), (120746, 120770),
+ (120772, 120779), (122624, 122654), (122661, 122666), (122928, 122989),
+ (123136, 123180), (123191, 123197), (123214, 123214), (123536, 123565),
+ (123584, 123627), (124112, 124139), (124896, 124902), (124904, 124907),
+ (124909, 124910), (124912, 124926), (124928, 125124), (125184, 125251),
+ (125259, 125259), (126464, 126467), (126469, 126495), (126497, 126498),
+ (126500, 126500), (126503, 126503), (126505, 126514), (126516, 126519),
+ (126521, 126521), (126523, 126523), (126530, 126530), (126535, 126535),
+ (126537, 126537), (126539, 126539), (126541, 126543), (126545, 126546),
+ (126548, 126548), (126551, 126551), (126553, 126553), (126555, 126555),
+ (126557, 126557), (126559, 126559), (126561, 126562), (126564, 126564),
+ (126567, 126570), (126572, 126578), (126580, 126583), (126585, 126588),
+ (126590, 126590), (126592, 126601), (126603, 126619), (126625, 126627),
+ (126629, 126633), (126635, 126651), (131072, 173791), (173824, 177977),
+ (177984, 178205), (178208, 183969), (183984, 191456), (191472, 192093),
+ (194560, 195101), (196608, 201546), (201552, 205743),
+];
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/tests/trie/mod.rs b/rust/hw/char/pl011/vendor/unicode-ident/tests/trie/mod.rs
new file mode 100644
index 0000000000..3e31c5cc57
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/tests/trie/mod.rs
@@ -0,0 +1,7 @@
+#![allow(clippy::module_inception)]
+
+#[allow(dead_code, clippy::redundant_static_lifetimes, clippy::unreadable_literal)]
+#[rustfmt::skip]
+mod trie;
+
+pub(crate) use self::trie::*;
diff --git a/rust/hw/char/pl011/vendor/unicode-ident/tests/trie/trie.rs b/rust/hw/char/pl011/vendor/unicode-ident/tests/trie/trie.rs
new file mode 100644
index 0000000000..fc805f497f
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/unicode-ident/tests/trie/trie.rs
@@ -0,0 +1,445 @@
+// DO NOT EDIT THIS FILE. IT WAS AUTOMATICALLY GENERATED BY:
+//
+// ucd-generate property-bool UCD --include XID_Start,XID_Continue --trie-set
+//
+// Unicode version: 15.1.0.
+//
+// ucd-generate 0.3.0 is available on crates.io.
+
+pub const BY_NAME: &'static [(&'static str, &'static ::ucd_trie::TrieSet)] = &[
+ ("XID_Continue", XID_CONTINUE), ("XID_Start", XID_START),
+];
+
+pub const XID_CONTINUE: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
+ tree1_level1: &[
+ 0x3FF000000000000, 0x7FFFFFE87FFFFFE, 0x4A0040000000000,
+ 0xFF7FFFFFFF7FFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0x501F0003FFC3,
+ 0xFFFFFFFFFFFFFFFF, 0xB8DFFFFFFFFFFFFF, 0xFFFFFFFBFFFFD7C0,
+ 0xFFBFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFCFB, 0xFFFFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFFF,
+ 0xFFFFFFFF027FFFFF, 0xBFFFFFFFFFFE01FF, 0x787FFFFFF00B6,
+ 0xFFFFFFFF07FF0000, 0xFFFFC3FFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
+ 0x9FFFFDFF9FEFFFFF, 0xFFFFFFFFFFFF0000, 0xFFFFFFFFFFFFE7FF,
+ 0x3FFFFFFFFFFFF, 0x243FFFFFFFFFFFFF,
+ ],
+ tree2_level1: &[
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 4, 32, 33, 34, 4, 4, 4, 4, 4,
+ 35, 36, 37, 38, 39, 40, 41, 42, 4, 4, 4, 4, 4, 4, 4, 4, 43, 44, 45, 46,
+ 47, 4, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 4, 61, 4, 62,
+ 63, 64, 65, 66, 4, 4, 4, 4, 4, 4, 4, 4, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 4, 4, 4, 79, 80, 81, 82, 83, 78, 78, 78,
+ 78, 78, 78, 78, 78, 84, 42, 85, 4, 86, 4, 87, 88, 78, 78, 78, 78, 78, 78,
+ 78, 78, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 78, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 89, 90, 4, 4, 4, 4, 91, 92, 4, 93, 94, 4, 95, 96, 97, 62, 4,
+ 98, 99, 100, 4, 101, 102, 103, 4, 104, 105, 106, 4, 107, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 109, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 4, 4, 4, 4, 4, 99, 4, 110, 111, 112, 93, 113, 4, 114, 4,
+ 4, 115, 116, 117, 118, 119, 120, 4, 121, 122, 123, 124, 125,
+ ],
+ tree2_level2: &[
+ 0x3FFFFFFFFFFF, 0xFFFF07FF0FFFFFFF, 0xFFFFFFFFFF007EFF,
+ 0xFFFFFFFBFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFEFFCFFFFFFFFF,
+ 0xF3C5FDFFFFF99FEF, 0x5003FFCFB080799F, 0xD36DFDFFFFF987EE,
+ 0x3FFFC05E023987, 0xF3EDFDFFFFFBBFEE, 0xFE00FFCF00013BBF,
+ 0xF3EDFDFFFFF99FEE, 0x2FFCFB0E0399F, 0xC3FFC718D63DC7EC, 0xFFC000813DC7,
+ 0xF3FFFDFFFFFDDFFF, 0xFFCF27603DDF, 0xF3EFFDFFFFFDDFEF, 0xEFFCF60603DDF,
+ 0xFFFFFFFFFFFDDFFF, 0xFC00FFCF80F07DDF, 0x2FFBFFFFFC7FFFEE,
+ 0xCFFC0FF5F847F, 0x7FFFFFFFFFFFFFE, 0x3FF7FFF, 0x3FFFFFAFFFFFF7D6,
+ 0xF3FF7F5F, 0xC2A003FF03000001, 0xFFFE1FFFFFFFFEFF, 0x1FFFFFFFFEFFFFDF,
+ 0x40, 0xFFFFFFFFFFFF03FF, 0xFFFFFFFF3FFFFFFF, 0xF7FFFFFFFFFF20BF,
+ 0xFFFFFFFF3D7F3DFF, 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D,
+ 0xFFFFFFFFFF3DFFFF, 0x3FE00E7FFFFFF, 0xFFFFFFFF0000FFFF,
+ 0x3F3FFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE, 0xFFFF9FFFFFFFFFFF,
+ 0xFFFFFFFF07FFFFFE, 0x1FFC7FFFFFFFFFF, 0x1FFFFF803FFFFF, 0xDDFFF000FFFFF,
+ 0x3FF308FFFFF, 0xFFFFFFFF03FFB800, 0x1FFFFFFFFFFFFFF, 0xFFFF07FFFFFFFFFF,
+ 0x3FFFFFFFFFFFFF, 0xFFF0FFF7FFFFFFF, 0x1F3FFFFFFFFFC0, 0xFFFF0FFFFFFFFFFF,
+ 0x7FF03FF, 0xFFFFFFFF0FFFFFFF, 0x9FFFFFFF7FFFFFFF, 0xBFFF008003FF03FF,
+ 0x7FFF, 0xFF80003FF1FFF, 0xFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFF,
+ 0x3FFFFFFFFFFFE3FF, 0xE7FFFFFFFFFF01FF, 0x7FFFFFFFFF70000,
+ 0xFFFFFFFF3F3FFFFF, 0x3FFFFFFFAAFF3F3F, 0x5FDFFFFFFFFFFFFF,
+ 0x1FDC1FFF0FCF1FDC, 0x8000000000003000, 0x8002000000100001, 0x1FFF0000,
+ 0x1FFE21FFF0000, 0xF3FFFD503F2FFC84, 0xFFFFFFFF000043E0, 0x1FF, 0,
+ 0xFF81FFFFFFFFF, 0xFFFF20BFFFFFFFFF, 0x800080FFFFFFFFFF,
+ 0x7F7F7F7F007FFFFF, 0xFFFFFFFF7F7F7F7F, 0x1F3EFFFE000000E0,
+ 0xFFFFFFFEE67FFFFF, 0xFFFEFFFFFFFFFFE0, 0xFFFFFFFF00007FFF,
+ 0xFFFF000000000000, 0x1FFF, 0x3FFFFFFFFFFF0000, 0xFFFFFFF1FFF,
+ 0xBFF0FFFFFFFFFFFF, 0x3FFFFFFFFFFFF, 0xFFFFFFFCFF800000,
+ 0xFFFFFFFFFFFFF9FF, 0xFFFC000003EB07FF, 0x10FFFFFFFFFF,
+ 0xE8FFFFFF03FF003F, 0xFFFF3FFFFFFFFFFF, 0x1FFFFFFF000FFFFF,
+ 0x7FFFFFFF03FF8001, 0x7FFFFFFFFFFFFF, 0xFC7FFFFF03FF3FFF,
+ 0x7CFFFF38000007, 0xFFFF7F7F007E7E7E, 0xFFFF03FFF7FFFFFF,
+ 0x3FF37FFFFFFFFFF, 0xFFFF000FFFFFFFFF, 0xFFFFFFFFFFFF87F, 0x3FFFFFF,
+ 0x5F7FFDFFE0F8007F, 0xFFFFFFFFFFFFFFDB, 0xFFFFFFFFFFF80000,
+ 0xFFFFFFF03FFFFFFF, 0x3FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0000,
+ 0xFFFFFFFFFFFCFFFF, 0x3FF0000000000FF, 0x18FFFF0000FFFF,
+ 0xAA8A00000000E000, 0x1FFFFFFFFFFFFFFF, 0x87FFFFFE03FF0000,
+ 0xFFFFFFE007FFFFFE, 0x7FFFFFFFFFFFFFFF, 0x1CFCFCFC,
+ ],
+ tree3_level1: &[
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 11, 12, 13, 14, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 15, 16, 17, 7, 18, 19, 7, 20, 21, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 22, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ ],
+ tree3_level2: &[
+ 0, 1, 2, 3, 4, 5, 4, 6, 4, 4, 7, 8, 9, 10, 11, 12, 2, 2, 13, 14, 15, 16,
+ 17, 4, 2, 2, 2, 2, 18, 19, 20, 4, 21, 22, 23, 24, 25, 4, 26, 4, 27, 28,
+ 29, 30, 31, 32, 33, 4, 2, 34, 35, 35, 36, 4, 4, 4, 4, 4, 37, 38, 39, 40,
+ 41, 42, 2, 43, 3, 44, 45, 46, 2, 47, 48, 49, 50, 51, 52, 53, 4, 4, 2, 54,
+ 2, 55, 4, 4, 56, 57, 2, 58, 59, 60, 61, 62, 4, 4, 3, 4, 63, 64, 65, 66,
+ 67, 68, 69, 70, 71, 59, 4, 4, 4, 4, 72, 73, 74, 4, 75, 76, 77, 4, 4, 4, 4,
+ 78, 79, 80, 81, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 82, 4, 2, 83,
+ 2, 2, 2, 84, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 85, 86, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 87, 88, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 62, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
+ 2, 2, 2, 2, 2, 2, 2, 59, 89, 69, 90, 18, 91, 92, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 2, 4, 4, 2, 93, 94, 95, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 88, 34, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 97, 2, 2, 2, 2, 98, 99, 2, 2, 2, 2, 2, 100, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 2, 101, 102, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 103, 62, 4, 4, 4, 4, 4, 4, 4, 104, 105, 4, 4, 106, 4,
+ 4, 4, 4, 4, 4, 2, 107, 108, 109, 110, 111, 2, 2, 2, 2, 112, 113, 114, 115,
+ 116, 117, 4, 4, 4, 4, 4, 4, 4, 4, 118, 119, 120, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 121, 4, 4, 4, 122, 123, 124, 4, 125, 126, 4, 4,
+ 4, 4, 127, 128, 4, 4, 4, 4, 4, 4, 4, 129, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 130, 2, 2, 2, 131, 2, 132, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 133, 134, 135, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 136, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 137, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 2, 2, 2,
+ 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 138, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 139, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 140, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2,
+ 2, 2, 2, 2, 140, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 141, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 87, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 87, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ ],
+ tree3_level3: &[
+ 0xB7FFFF7FFFFFEFFF, 0x3FFF3FFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF, 0,
+ 0x1FFFFFFFFFFFFF, 0x2000000000000000, 0xFFFFFFFF1FFFFFFF, 0x10001FFFF,
+ 0xFFFFE000FFFFFFFF, 0x7FFFFFFFFFF07FF, 0xFFFFFFFF3FFFFFFF, 0x3EFF0F,
+ 0xFFFF03FF3FFFFFFF, 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF,
+ 0xF7FF000FFFFFFFFF, 0x1BFBFFFBFFB7F7FF, 0x7FFFFFFFFFFFFF, 0xFF003FFFFF,
+ 0x7FDFFFFFFFFFFBF, 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF, 0x7FFFFFFF,
+ 0x37FFFF00000000, 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF,
+ 0x873FFFFFFEEFF06F, 0x1FFFFFFF00000000, 0x1FFFFFFF, 0x7FFFFFFEFF,
+ 0x3FFFFFFFFFFFFF, 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0x7FFFFFFFFFFFF,
+ 0x3FF00FFFFFFFFFF, 0x31BFFFFFFFFFF, 0xE000000000000000,
+ 0xFFFF00801FFFFFFF, 0xFFFF00000001FFFF, 0xFFFF00000000003F,
+ 0x7FFFFF0000001F, 0x803FFFC00000007F, 0x3FF01FFFFFF0004,
+ 0xFFDFFFFFFFFFFFFF, 0x4FFFFFFFFF00F0, 0x17FFDE1F, 0xC0FFFFFFFFFBFFFF, 0x3,
+ 0xFFFF01FFBFFFBD7F, 0x3FF07FFFFFFFFFF, 0xFBEDFDFFFFF99FEF,
+ 0x1F1FCFE081399F, 0x3C3FF07FF, 0x3FF00BF, 0xFF3FFFFFFFFFFFFF, 0x3F000001,
+ 0x3FF0011, 0x1FFFFFFFFFFFFFF, 0x3FF, 0x3FF0FFFE7FFFFFF, 0x7F,
+ 0xFFFFFFFF00000000, 0x800003FFFFFFFFFF, 0xF9BFFFFFFF6FF27F, 0x3FF000F,
+ 0xFFFFFCFF00000000, 0x1BFCFFFFFF, 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0080,
+ 0xFFFF000023FFFFFF, 0xFF7FFFFFFFFFFDFF, 0xFFFC000003FF0001,
+ 0x7FFEFFFFFCFFFF, 0xB47FFFFFFFFFFB7F, 0xFFFFFDBF03FF00FF, 0x3FF01FB7FFF,
+ 0x7FFFFF00000000, 0xC7FFFFFFFFFDFFFF, 0x3FF0007, 0x1000000000000,
+ 0x3FFFFFF, 0x7FFFFFFFFFFF, 0xF, 0xFFFFFFFFFFFF0000, 0x1FFFFFFFFFFFF,
+ 0xFFFFFFFFFFFF, 0x3FFFFF, 0xFFFF03FF7FFFFFFF, 0x1F3FFFFFFF03FF,
+ 0xE0FFFFF803FF000F, 0xFFFF, 0xFFFFFFFFFFFF87FF, 0xFFFF80FF,
+ 0x3001B00000000, 0xFFFFFFFFFFFFFF, 0x6FEF000000000000, 0x40007FFFFFFFF,
+ 0xFFFF00F000270000, 0xFFFFFFFFFFFFFFF, 0x1FFF07FFFFFFFFFF, 0x63FF01FF,
+ 0xFFFF3FFFFFFFFFFF, 0xF807E3E000000000, 0x3C0000000FE7, 0x1C,
+ 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF, 0xFFFFFFFFFFFFFFEF,
+ 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F, 0xFFFFFF3FFFFFFFFF,
+ 0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF, 0xFFFF7FFFFFFF7FFF,
+ 0xFFFFFDFFFFFFFDFF, 0xFFFFFFFFFFFFCFF7, 0xF87FFFFFFFFFFFFF,
+ 0x201FFFFFFFFFFF, 0xFFFEF8000010, 0x7E07FFFFFFF, 0xFFFF07DBF9FFFF7F,
+ 0x3FFFFFFFFFFF, 0x8000, 0x3FFF1FFFFFFFFFFF, 0x43FF, 0x7FFFFFFF0000,
+ 0x3FFFFFFFFFFFFFF, 0x3FFFFFFFFFF0000, 0x7FFF6F7F00000000, 0x7F001F,
+ 0x3FF0FFF, 0xAF7FE96FFFFFFEF, 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF,
+ 0x3FF000000000000, 0xFFFFFFFF, 0xFFFF0003FFFFFFFF, 0xFFFF0001FFFFFFFF,
+ 0x3FFFFFFF, 0xFFFFFFFFFFFF07FF,
+ ],
+};
+
+pub const XID_START: &'static ::ucd_trie::TrieSet = &::ucd_trie::TrieSet {
+ tree1_level1: &[
+ 0, 0x7FFFFFE07FFFFFE, 0x420040000000000, 0xFF7FFFFFFF7FFFFF,
+ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF, 0x501F0003FFC3, 0, 0xB8DF000000000000,
+ 0xFFFFFFFBFFFFD740, 0xFFBFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFC03, 0xFFFFFFFFFFFFFFFF,
+ 0xFFFEFFFFFFFFFFFF, 0xFFFFFFFF027FFFFF, 0x1FF, 0x787FFFFFF0000,
+ 0xFFFFFFFF00000000, 0xFFFEC000000007FF, 0xFFFFFFFFFFFFFFFF,
+ 0x9C00C060002FFFFF, 0xFFFFFFFD0000, 0xFFFFFFFFFFFFE000, 0x2003FFFFFFFFF,
+ 0x43007FFFFFFFC00,
+ ],
+ tree2_level1: &[
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 35,
+ 35, 35, 36, 37, 38, 39, 40, 41, 42, 43, 35, 35, 35, 35, 35, 35, 35, 35,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 3, 58, 59, 60, 30,
+ 61, 62, 63, 64, 65, 66, 67, 68, 35, 35, 35, 30, 35, 35, 35, 35, 69, 70,
+ 71, 72, 30, 73, 74, 30, 75, 76, 77, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 35, 35, 35, 78,
+ 79, 80, 81, 82, 30, 30, 30, 30, 30, 30, 30, 30, 83, 43, 84, 85, 86, 35,
+ 87, 88, 30, 30, 30, 30, 30, 30, 30, 30, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 30, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 89, 90, 35, 35, 35, 35, 91, 92,
+ 93, 94, 95, 35, 96, 97, 98, 49, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 35, 111, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 112, 113, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 35, 35, 35, 35, 35, 114, 35, 115, 116,
+ 117, 118, 119, 35, 120, 35, 35, 121, 122, 123, 124, 30, 125, 35, 126, 127,
+ 128, 129, 130,
+ ],
+ tree2_level2: &[
+ 0x110043FFFFF, 0xFFFF07FF01FFFFFF, 0xFFFFFFFF00007EFF, 0x3FF,
+ 0x23FFFFFFFFFFFFF0, 0xFFFE0003FF010000, 0x23C5FDFFFFF99FE1,
+ 0x10030003B0004000, 0x36DFDFFFFF987E0, 0x1C00005E000000,
+ 0x23EDFDFFFFFBBFE0, 0x200000300010000, 0x23EDFDFFFFF99FE0,
+ 0x20003B0000000, 0x3FFC718D63DC7E8, 0x10000, 0x23FFFDFFFFFDDFE0,
+ 0x327000000, 0x23EFFDFFFFFDDFE1, 0x6000360000000, 0x27FFFFFFFFFDDFF0,
+ 0xFC00000380704000, 0x2FFBFFFFFC7FFFE0, 0x7F, 0x5FFFFFFFFFFFE,
+ 0x2005FFAFFFFFF7D6, 0xF000005F, 0x1, 0x1FFFFFFFFEFF, 0x1F00, 0,
+ 0x800007FFFFFFFFFF, 0xFFE1C0623C3F0000, 0xFFFFFFFF00004003,
+ 0xF7FFFFFFFFFF20BF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFF3D7F3DFF,
+ 0x7F3DFFFFFFFF3DFF, 0xFFFFFFFFFF7FFF3D, 0xFFFFFFFFFF3DFFFF, 0x7FFFFFF,
+ 0xFFFFFFFF0000FFFF, 0x3F3FFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE,
+ 0xFFFF9FFFFFFFFFFF, 0xFFFFFFFF07FFFFFE, 0x1FFC7FFFFFFFFFF,
+ 0x3FFFF8003FFFF, 0x1DFFF0003FFFF, 0xFFFFFFFFFFFFF, 0x10800000,
+ 0xFFFFFFFF00000000, 0x1FFFFFFFFFFFFFF, 0xFFFF05FFFFFFFFFF,
+ 0x3FFFFFFFFFFFFF, 0x7FFFFFFF, 0x1F3FFFFFFF0000, 0xFFFF0FFFFFFFFFFF,
+ 0xFFFFFFFF007FFFFF, 0x1FFFFF, 0x8000000000, 0xFFFFFFFFFFFE0, 0x1FE0,
+ 0xFC00C001FFFFFFF8, 0x3FFFFFFFFF, 0xFFFFFFFFF, 0x3FFFFFFFFC00E000,
+ 0xE7FFFFFFFFFF01FF, 0x46FDE0000000000, 0xFFFFFFFF3F3FFFFF,
+ 0x3FFFFFFFAAFF3F3F, 0x5FDFFFFFFFFFFFFF, 0x1FDC1FFF0FCF1FDC,
+ 0x8002000000000000, 0x1FFF0000, 0xF3FFFD503F2FFC84, 0xFFFFFFFF000043E0,
+ 0x1FF, 0xC781FFFFFFFFF, 0xFFFF20BFFFFFFFFF, 0x80FFFFFFFFFF,
+ 0x7F7F7F7F007FFFFF, 0x7F7F7F7F, 0x1F3E03FE000000E0, 0xFFFFFFFEE07FFFFF,
+ 0xF7FFFFFFFFFFFFFF, 0xFFFEFFFFFFFFFFE0, 0xFFFFFFFF00007FFF,
+ 0xFFFF000000000000, 0x1FFF, 0x3FFFFFFFFFFF0000, 0xC00FFFF1FFF,
+ 0x80007FFFFFFFFFFF, 0xFFFFFFFF3FFFFFFF, 0xFFFFFFFFFFFF,
+ 0xFFFFFFFCFF800000, 0xFFFFFFFFFFFFF9FF, 0xFFFC000003EB07FF, 0x7FFFFF7BB,
+ 0xFFFFFFFFFFFFC, 0x68FC000000000000, 0xFFFF003FFFFFFC00,
+ 0x1FFFFFFF0000007F, 0x7FFFFFFFFFFF0, 0x7C00FFDF00008000, 0x1FFFFFFFFFF,
+ 0xC47FFFFF00000FF7, 0x3E62FFFFFFFFFFFF, 0x1C07FF38000005,
+ 0xFFFF7F7F007E7E7E, 0xFFFF03FFF7FFFFFF, 0x7FFFFFFFF, 0xFFFF000FFFFFFFFF,
+ 0xFFFFFFFFFFFF87F, 0xFFFF3FFFFFFFFFFF, 0x3FFFFFF, 0x5F7FFDFFA0F8007F,
+ 0xFFFFFFFFFFFFFFDB, 0x3FFFFFFFFFFFF, 0xFFFFFFFFFFF80000,
+ 0xFFFFFFF03FFFFFFF, 0x3FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFF0000,
+ 0xFFFFFFFFFFFCFFFF, 0x3FF0000000000FF, 0xAA8A000000000000,
+ 0x1FFFFFFFFFFFFFFF, 0x7FFFFFE00000000, 0xFFFFFFC007FFFFFE,
+ 0x7FFFFFFF3FFFFFFF, 0x1CFCFCFC,
+ ],
+ tree3_level1: &[
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9, 10, 5, 11, 12, 5, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 13, 14, 15, 7, 16, 17, 7, 18, 19, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ ],
+ tree3_level2: &[
+ 0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15,
+ 16, 4, 2, 2, 2, 2, 17, 18, 19, 4, 20, 21, 22, 23, 24, 4, 25, 4, 26, 27,
+ 28, 29, 30, 31, 32, 4, 2, 33, 34, 34, 35, 4, 4, 4, 4, 4, 36, 4, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 22, 52, 53, 4, 4, 5,
+ 54, 55, 56, 4, 4, 57, 58, 55, 59, 60, 4, 61, 62, 4, 4, 63, 4, 64, 65, 66,
+ 67, 68, 69, 70, 71, 72, 73, 4, 4, 4, 4, 74, 75, 76, 4, 77, 78, 79, 4, 4,
+ 4, 4, 80, 81, 4, 82, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 83, 4,
+ 2, 57, 2, 2, 2, 84, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 85, 86,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 55, 87, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 62, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 2, 2, 2, 2, 2, 2, 2, 2, 73, 88, 89, 90, 55, 91, 76, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 2, 4, 4, 2, 92, 93, 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 95, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 96, 33, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 97, 2, 2, 2, 2, 98, 99, 2, 2, 2, 2, 2, 100, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 2, 101, 102, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 103, 104, 105, 106, 107,
+ 2, 2, 2, 2, 108, 109, 110, 111, 112, 113, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 114, 4, 4, 4, 115, 116,
+ 4, 4, 117, 118, 4, 4, 4, 4, 90, 63, 4, 4, 4, 4, 4, 4, 4, 119, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 120, 2, 2, 2, 121, 2, 122, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 123, 124, 125, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 126, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 127, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 128, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 129, 2, 2, 2, 2, 2, 2, 2, 2, 2, 130, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 130, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 131, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 55, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4,
+ ],
+ tree3_level3: &[
+ 0xB7FFFF7FFFFFEFFF, 0x3FFF3FFF, 0xFFFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFF, 0,
+ 0x1FFFFFFFFFFFFF, 0xFFFFFFFF1FFFFFFF, 0x1FFFF, 0xFFFFE000FFFFFFFF,
+ 0x3FFFFFFFFF07FF, 0xFFFFFFFF3FFFFFFF, 0x3EFF0F, 0xFFFF00003FFFFFFF,
+ 0xFFFFFFFFF0FFFFF, 0xFFFF00FFFFFFFFFF, 0xF7FF000FFFFFFFFF,
+ 0x1BFBFFFBFFB7F7FF, 0x7FFFFFFFFFFFFF, 0xFF003FFFFF, 0x7FDFFFFFFFFFFBF,
+ 0x91BFFFFFFFFFFD3F, 0x7FFFFF003FFFFF, 0x7FFFFFFF, 0x37FFFF00000000,
+ 0x3FFFFFF003FFFFF, 0xC0FFFFFFFFFFFFFF, 0x3FFFFFFEEF0001,
+ 0x1FFFFFFF00000000, 0x1FFFFFFF, 0x1FFFFFFEFF, 0x3FFFFFFFFFFFFF,
+ 0x7FFFF003FFFFF, 0x3FFFF, 0x1FF, 0x7FFFFFFFFFFFF, 0xFFFFFFFFF,
+ 0x303FFFFFFFFFF, 0xFFFF00801FFFFFFF, 0xFFFF00000000003F,
+ 0xFFFF000000000003, 0x7FFFFF0000001F, 0xFFFFFFFFFFFFF8, 0x26000000000000,
+ 0xFFFFFFFFFFF8, 0x1FFFFFF0000, 0x7FFFFFFFF8, 0x47FFFFFFFF0090,
+ 0x7FFFFFFFFFFF8, 0x1400001E, 0x80000FFFFFFBFFFF, 0x1, 0xFFFF01FFBFFFBD7F,
+ 0x23EDFDFFFFF99FE0, 0x3E0010000, 0x380000780, 0xFFFFFFFFFFFF, 0xB0,
+ 0x7FFFFFFFFFFF, 0xF000000, 0x10, 0x10007FFFFFFFFFF, 0x7FFFFFF, 0x7F,
+ 0xFFFFFFFFFFF, 0xFFFFFFFF00000000, 0x80000000FFFFFFFF, 0x8000FFFFFF6FF27F,
+ 0x2, 0xFFFFFCFF00000000, 0xA0001FFFF, 0x407FFFFFFFFF801,
+ 0xFFFFFFFFF0010000, 0xFFFF0000200003FF, 0x1FFFFFFFFFFFFFF, 0x7FFFFFFFFDFF,
+ 0xFFFC000000000001, 0xFFFF, 0x1FFFFFFFFFB7F, 0xFFFFFDBF00000040,
+ 0x10003FF, 0x7FFFF00000000, 0xFFFFFFFFDFFF4, 0x1000000000000, 0x3FFFFFF,
+ 0xF, 0xFFFFFFFFFFFF0000, 0x1FFFFFFFFFFFF, 0x7E, 0xFFFF00007FFFFFFF,
+ 0x7FFFFFFFFFFFFFFF, 0x3FFFFFFF0000, 0xE0FFFFF80000000F, 0x107FF,
+ 0xFFF80000, 0xB00000000, 0xFFFFFFFFFFFFFF, 0x3FFFFF, 0x6FEF000000000000,
+ 0x40007FFFFFFFF, 0xFFFF00F000270000, 0xFFFFFFFFFFFFFFF,
+ 0x1FFF07FFFFFFFFFF, 0x3FF01FF, 0xFFFFFFFFFFDFFFFF, 0xEBFFDE64DFFFFFFF,
+ 0xFFFFFFFFFFFFFFEF, 0x7BFFFFFFDFDFE7BF, 0xFFFFFFFFFFFDFC5F,
+ 0xFFFFFF3FFFFFFFFF, 0xF7FFFFFFF7FFFFFD, 0xFFDFFFFFFFDFFFFF,
+ 0xFFFF7FFFFFFF7FFF, 0xFFFFFDFFFFFFFDFF, 0xFF7, 0x7E07FFFFFFF,
+ 0xFFFF000000000000, 0x3FFFFFFFFFFF, 0x3F801FFFFFFFFFFF, 0x4000,
+ 0xFFFFFFF0000, 0x7FFF6F7F00000000, 0x1F, 0x80F, 0xAF7FE96FFFFFFEF,
+ 0x5EF7F796AA96EA84, 0xFFFFBEE0FFFFBFF, 0xFFFFFFFF, 0x3FFFFFFFFFFFFFF,
+ 0xFFFF0003FFFFFFFF, 0xFFFF0001FFFFFFFF, 0x3FFFFFFF, 0xFFFFFFFFFFFF07FF,
+ ],
+};
diff --git a/rust/hw/char/pl011/vendor/version_check/.cargo-checksum.json b/rust/hw/char/pl011/vendor/version_check/.cargo-checksum.json
new file mode 100644
index 0000000000..dd79d121d3
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/version_check/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"f25d88044914cb3466df43bc39a199e1589dda1aad3226c9c7e7ac4d2f8751d0","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"b7e650f3fce5c53249d1cdc608b54df156a97edd636cf9d23498d0cfe7aec63e","README.md":"ac2a0a360812436bd5798f5fe2affe7d6ed9eb7f15d6e4d73931e95b437560f2","src/channel.rs":"d2443d503d4cc469a171a51a26eca3ec0d2a58b5f7375a84542c36f1421766a8","src/date.rs":"09580a0a2008fad2ccbc43fb42a88f42221b98b01692702022a296dc9c86bf37","src/lib.rs":"760f0d29567ecaa61287088cf23cf74b3c0efbbcd3077cea5fb7c88359e96c7e","src/version.rs":"dba18a25983ec6e37b952f4cdc5219c9e5abba2c3a76cef87465e1fba6f8ac89"},"package":"49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"}
\ No newline at end of file
diff --git a/rust/hw/char/pl011/vendor/version_check/Cargo.toml b/rust/hw/char/pl011/vendor/version_check/Cargo.toml
new file mode 100644
index 0000000000..39fedbd48b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/version_check/Cargo.toml
@@ -0,0 +1,24 @@
+# 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]
+name = "version_check"
+version = "0.9.4"
+authors = ["Sergio Benitez <sb@sergio.bz>"]
+exclude = ["static"]
+description = "Tiny crate to check the version of the installed/running rustc."
+documentation = "https://docs.rs/version_check/"
+readme = "README.md"
+keywords = ["version", "rustc", "minimum", "check"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/SergioBenitez/version_check"
+
+[dependencies]
diff --git a/rust/hw/char/pl011/vendor/version_check/LICENSE-APACHE b/rust/hw/char/pl011/vendor/version_check/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/version_check/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ 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
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/rust/hw/char/pl011/vendor/version_check/LICENSE-MIT b/rust/hw/char/pl011/vendor/version_check/LICENSE-MIT
new file mode 100644
index 0000000000..dfc0e73b19
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/version_check/LICENSE-MIT
@@ -0,0 +1,19 @@
+The MIT License (MIT)
+Copyright (c) 2017-2018 Sergio Benitez
+
+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/rust/hw/char/pl011/vendor/version_check/README.md b/rust/hw/char/pl011/vendor/version_check/README.md
new file mode 100644
index 0000000000..8637d2ab1d
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/version_check/README.md
@@ -0,0 +1,80 @@
+# version\_check
+
+[](https://github.com/SergioBenitez/version_check/actions)
+[](https://crates.io/crates/version_check)
+[](https://docs.rs/version_check)
+
+This tiny crate checks that the running or installed `rustc` meets some version
+requirements. The version is queried by calling the Rust compiler with
+`--version`. The path to the compiler is determined first via the `RUSTC`
+environment variable. If it is not set, then `rustc` is used. If that fails, no
+determination is made, and calls return `None`.
+
+## Usage
+
+Add to your `Cargo.toml` file, typically as a build dependency:
+
+```toml
+[build-dependencies]
+version_check = "0.9"
+```
+
+`version_check` is compatible and compiles with Rust 1.0.0 and beyond.
+
+## Examples
+
+Set a `cfg` flag in `build.rs` if the running compiler was determined to be
+at least version `1.13.0`:
+
+```rust
+extern crate version_check as rustc;
+
+if rustc::is_min_version("1.13.0").unwrap_or(false) {
+ println!("cargo:rustc-cfg=question_mark_operator");
+}
+```
+
+Check that the running compiler was released on or after `2018-12-18`:
+
+```rust
+extern crate version_check as rustc;
+
+match rustc::is_min_date("2018-12-18") {
+ Some(true) => "Yep! It's recent!",
+ Some(false) => "No, it's older.",
+ None => "Couldn't determine the rustc version."
+};
+```
+
+Check that the running compiler supports feature flags:
+
+```rust
+extern crate version_check as rustc;
+
+match rustc::is_feature_flaggable() {
+ Some(true) => "Yes! It's a dev or nightly release!",
+ Some(false) => "No, it's stable or beta.",
+ None => "Couldn't determine the rustc version."
+};
+```
+
+See the [rustdocs](https://docs.rs/version_check) for more examples and complete
+documentation.
+
+## Alternatives
+
+This crate is dead simple with no dependencies. If you need something more and
+don't care about panicking if the version cannot be obtained, or if you don't
+mind adding dependencies, see [rustc_version]. If you'd instead prefer a feature
+detection library that works by dynamically invoking `rustc` with a
+representative code sample, see [autocfg].
+
+[rustc_version]: https://crates.io/crates/rustc_version
+[autocfg]: https://crates.io/crates/autocfg
+
+## License
+
+`version_check` is licensed under either of the following, at your option:
+
+ * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
+ * MIT License ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
diff --git a/rust/hw/char/pl011/vendor/version_check/meson.build b/rust/hw/char/pl011/vendor/version_check/meson.build
new file mode 100644
index 0000000000..9a37495615
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/version_check/meson.build
@@ -0,0 +1,14 @@
+_version_check_rs = static_library(
+ 'version_check',
+ files('src/lib.rs'),
+ gnu_symbol_visibility: 'hidden',
+ rust_abi: 'rust',
+ rust_args: rust_args + [
+ '--edition', '2021',
+ ],
+ dependencies: [],
+)
+
+dep_version_check = declare_dependency(
+ link_with: _version_check_rs,
+)
diff --git a/rust/hw/char/pl011/vendor/version_check/src/channel.rs b/rust/hw/char/pl011/vendor/version_check/src/channel.rs
new file mode 100644
index 0000000000..f84c508d16
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/version_check/src/channel.rs
@@ -0,0 +1,193 @@
+use std::fmt;
+
+#[derive(Debug, PartialEq, Eq, Copy, Clone)]
+enum Kind {
+ Dev,
+ Nightly,
+ Beta,
+ Stable,
+}
+
+/// Release channel: "dev", "nightly", "beta", or "stable".
+#[derive(Debug, PartialEq, Eq, Copy, Clone)]
+pub struct Channel(Kind);
+
+impl Channel {
+ /// Reads the release channel of the running compiler. If it cannot be
+ /// determined (see the [top-level documentation](crate)), returns `None`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Channel;
+ ///
+ /// match Channel::read() {
+ /// Some(c) => format!("The channel is: {}", c),
+ /// None => format!("Failed to read the release channel.")
+ /// };
+ /// ```
+ pub fn read() -> Option<Channel> {
+ ::get_version_and_date()
+ .and_then(|(version, _)| version)
+ .and_then(|version| Channel::parse(&version))
+ }
+
+ /// Parse a Rust release channel from a Rust release version string (of the
+ /// form `major[.minor[.patch[-channel]]]`). Returns `None` if `version` is
+ /// not a valid Rust version string.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Channel;
+ ///
+ /// let dev = Channel::parse("1.3.0-dev").unwrap();
+ /// assert!(dev.is_dev());
+ ///
+ /// let nightly = Channel::parse("1.42.2-nightly").unwrap();
+ /// assert!(nightly.is_nightly());
+ ///
+ /// let beta = Channel::parse("1.32.0-beta").unwrap();
+ /// assert!(beta.is_beta());
+ ///
+ /// let stable = Channel::parse("1.4.0").unwrap();
+ /// assert!(stable.is_stable());
+ /// ```
+ pub fn parse(version: &str) -> Option<Channel> {
+ let version = version.trim();
+ if version.contains("-dev") || version == "dev" {
+ Some(Channel(Kind::Dev))
+ } else if version.contains("-nightly") || version == "nightly" {
+ Some(Channel(Kind::Nightly))
+ } else if version.contains("-beta") || version == "beta" {
+ Some(Channel(Kind::Beta))
+ } else if !version.contains("-") {
+ Some(Channel(Kind::Stable))
+ } else {
+ None
+ }
+ }
+
+ /// Returns the name of the release channel.
+ fn as_str(&self) -> &'static str {
+ match self.0 {
+ Kind::Dev => "dev",
+ Kind::Beta => "beta",
+ Kind::Nightly => "nightly",
+ Kind::Stable => "stable",
+ }
+ }
+
+ /// Returns `true` if this channel supports feature flags. In other words,
+ /// returns `true` if the channel is either `dev` or `nightly`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Channel;
+ ///
+ /// let dev = Channel::parse("1.3.0-dev").unwrap();
+ /// assert!(dev.supports_features());
+ ///
+ /// let nightly = Channel::parse("1.42.2-nightly").unwrap();
+ /// assert!(nightly.supports_features());
+ ///
+ /// let beta = Channel::parse("1.32.0-beta").unwrap();
+ /// assert!(!beta.supports_features());
+ ///
+ /// let stable = Channel::parse("1.4.0").unwrap();
+ /// assert!(!stable.supports_features());
+ /// ```
+ pub fn supports_features(&self) -> bool {
+ match self.0 {
+ Kind::Dev | Kind::Nightly => true,
+ Kind::Beta | Kind::Stable => false
+ }
+ }
+
+ /// Returns `true` if this channel is `dev` and `false` otherwise.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Channel;
+ ///
+ /// let dev = Channel::parse("1.3.0-dev").unwrap();
+ /// assert!(dev.is_dev());
+ ///
+ /// let stable = Channel::parse("1.0.0").unwrap();
+ /// assert!(!stable.is_dev());
+ /// ```
+ pub fn is_dev(&self) -> bool {
+ match self.0 {
+ Kind::Dev => true,
+ _ => false
+ }
+ }
+
+ /// Returns `true` if this channel is `nightly` and `false` otherwise.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Channel;
+ ///
+ /// let nightly = Channel::parse("1.3.0-nightly").unwrap();
+ /// assert!(nightly.is_nightly());
+ ///
+ /// let stable = Channel::parse("1.0.0").unwrap();
+ /// assert!(!stable.is_nightly());
+ /// ```
+ pub fn is_nightly(&self) -> bool {
+ match self.0 {
+ Kind::Nightly => true,
+ _ => false
+ }
+ }
+
+ /// Returns `true` if this channel is `beta` and `false` otherwise.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Channel;
+ ///
+ /// let beta = Channel::parse("1.3.0-beta").unwrap();
+ /// assert!(beta.is_beta());
+ ///
+ /// let stable = Channel::parse("1.0.0").unwrap();
+ /// assert!(!stable.is_beta());
+ /// ```
+ pub fn is_beta(&self) -> bool {
+ match self.0 {
+ Kind::Beta => true,
+ _ => false
+ }
+ }
+
+ /// Returns `true` if this channel is `stable` and `false` otherwise.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Channel;
+ ///
+ /// let stable = Channel::parse("1.0.0").unwrap();
+ /// assert!(stable.is_stable());
+ ///
+ /// let beta = Channel::parse("1.3.0-beta").unwrap();
+ /// assert!(!beta.is_stable());
+ /// ```
+ pub fn is_stable(&self) -> bool {
+ match self.0 {
+ Kind::Stable => true,
+ _ => false
+ }
+ }
+}
+
+impl fmt::Display for Channel {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", self.as_str())
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/version_check/src/date.rs b/rust/hw/char/pl011/vendor/version_check/src/date.rs
new file mode 100644
index 0000000000..de0b2d05d7
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/version_check/src/date.rs
@@ -0,0 +1,203 @@
+use std::fmt;
+
+/// Release date including year, month, and day.
+// Internal storage is: y[31..9] | m[8..5] | d[5...0].
+#[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)]
+pub struct Date(u32);
+
+impl Date {
+ /// Reads the release date of the running compiler. If it cannot be
+ /// determined (see the [top-level documentation](crate)), returns `None`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Date;
+ ///
+ /// match Date::read() {
+ /// Some(d) => format!("The release date is: {}", d),
+ /// None => format!("Failed to read the release date.")
+ /// };
+ /// ```
+ pub fn read() -> Option<Date> {
+ ::get_version_and_date()
+ .and_then(|(_, date)| date)
+ .and_then(|date| Date::parse(&date))
+ }
+
+ /// Parse a release date of the form `%Y-%m-%d`. Returns `None` if `date` is
+ /// not in `%Y-%m-%d` format.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Date;
+ ///
+ /// let date = Date::parse("2016-04-20").unwrap();
+ ///
+ /// assert!(date.at_least("2016-01-10"));
+ /// assert!(date.at_most("2016-04-20"));
+ /// assert!(date.exactly("2016-04-20"));
+ ///
+ /// assert!(Date::parse("2021-12-31").unwrap().exactly("2021-12-31"));
+ ///
+ /// assert!(Date::parse("March 13, 2018").is_none());
+ /// assert!(Date::parse("1-2-3-4-5").is_none());
+ /// assert!(Date::parse("2020-300-23120").is_none());
+ /// assert!(Date::parse("2020-12-12 1").is_none());
+ /// assert!(Date::parse("2020-10").is_none());
+ /// assert!(Date::parse("2020").is_none());
+ /// ```
+ pub fn parse(date: &str) -> Option<Date> {
+ let mut ymd = [0u16; 3];
+ for (i, split) in date.split('-').map(|s| s.parse::<u16>()).enumerate() {
+ ymd[i] = match (i, split) {
+ (3, _) | (_, Err(_)) => return None,
+ (_, Ok(v)) => v,
+ };
+ }
+
+ let (year, month, day) = (ymd[0], ymd[1], ymd[2]);
+ if year == 0 || month == 0 || month > 12 || day == 0 || day > 31 {
+ return None;
+ }
+
+ Some(Date::from_ymd(year, month as u8, day as u8))
+ }
+
+ /// Creates a `Date` from `(year, month, day)` date components.
+ ///
+ /// Does not check the validity of `year`, `month`, or `day`, but `year` is
+ /// truncated to 23 bits (% 8,388,608), `month` to 4 bits (% 16), and `day`
+ /// to 5 bits (% 32).
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Date;
+ ///
+ /// assert!(Date::from_ymd(2021, 7, 30).exactly("2021-07-30"));
+ /// assert!(Date::from_ymd(2010, 3, 23).exactly("2010-03-23"));
+ /// assert!(Date::from_ymd(2090, 1, 31).exactly("2090-01-31"));
+ ///
+ /// // Truncation: 33 % 32 == 0x21 & 0x1F == 1.
+ /// assert!(Date::from_ymd(2090, 1, 33).exactly("2090-01-01"));
+ /// ```
+ pub fn from_ymd(year: u16, month: u8, day: u8) -> Date {
+ let year = (year as u32) << 9;
+ let month = ((month as u32) & 0xF) << 5;
+ let day = (day as u32) & 0x1F;
+ Date(year | month | day)
+ }
+
+ /// Return the original (YYYY, MM, DD).
+ fn to_ymd(&self) -> (u16, u8, u8) {
+ let y = self.0 >> 9;
+ let m = (self.0 >> 5) & 0xF;
+ let d = self.0 & 0x1F;
+ (y as u16, m as u8, d as u8)
+ }
+
+ /// Returns `true` if `self` occurs on or after `date`.
+ ///
+ /// If `date` occurs before `self`, or if `date` is not in `%Y-%m-%d`
+ /// format, returns `false`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Date;
+ ///
+ /// let date = Date::parse("2020-01-01").unwrap();
+ ///
+ /// assert!(date.at_least("2019-12-31"));
+ /// assert!(date.at_least("2020-01-01"));
+ /// assert!(date.at_least("2014-04-31"));
+ ///
+ /// assert!(!date.at_least("2020-01-02"));
+ /// assert!(!date.at_least("2024-08-18"));
+ /// ```
+ pub fn at_least(&self, date: &str) -> bool {
+ Date::parse(date)
+ .map(|date| self >= &date)
+ .unwrap_or(false)
+ }
+
+ /// Returns `true` if `self` occurs on or before `date`.
+ ///
+ /// If `date` occurs after `self`, or if `date` is not in `%Y-%m-%d`
+ /// format, returns `false`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Date;
+ ///
+ /// let date = Date::parse("2020-01-01").unwrap();
+ ///
+ /// assert!(date.at_most("2020-01-01"));
+ /// assert!(date.at_most("2020-01-02"));
+ /// assert!(date.at_most("2024-08-18"));
+ ///
+ /// assert!(!date.at_most("2019-12-31"));
+ /// assert!(!date.at_most("2014-04-31"));
+ /// ```
+ pub fn at_most(&self, date: &str) -> bool {
+ Date::parse(date)
+ .map(|date| self <= &date)
+ .unwrap_or(false)
+ }
+
+ /// Returns `true` if `self` occurs exactly on `date`.
+ ///
+ /// If `date` is not exactly `self`, or if `date` is not in `%Y-%m-%d`
+ /// format, returns `false`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Date;
+ ///
+ /// let date = Date::parse("2020-01-01").unwrap();
+ ///
+ /// assert!(date.exactly("2020-01-01"));
+ ///
+ /// assert!(!date.exactly("2019-12-31"));
+ /// assert!(!date.exactly("2014-04-31"));
+ /// assert!(!date.exactly("2020-01-02"));
+ /// assert!(!date.exactly("2024-08-18"));
+ /// ```
+ pub fn exactly(&self, date: &str) -> bool {
+ Date::parse(date)
+ .map(|date| self == &date)
+ .unwrap_or(false)
+ }
+}
+
+impl fmt::Display for Date {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let (y, m, d) = self.to_ymd();
+ write!(f, "{}-{:02}-{:02}", y, m, d)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::Date;
+
+ macro_rules! reflexive_display {
+ ($string:expr) => (
+ assert_eq!(Date::parse($string).unwrap().to_string(), $string);
+ )
+ }
+
+ #[test]
+ fn display() {
+ reflexive_display!("2019-05-08");
+ reflexive_display!("2000-01-01");
+ reflexive_display!("2000-12-31");
+ reflexive_display!("2090-12-31");
+ reflexive_display!("1999-02-19");
+ reflexive_display!("9999-12-31");
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/version_check/src/lib.rs b/rust/hw/char/pl011/vendor/version_check/src/lib.rs
new file mode 100644
index 0000000000..6c16074822
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/version_check/src/lib.rs
@@ -0,0 +1,493 @@
+//! This tiny crate checks that the running or installed `rustc` meets some
+//! version requirements. The version is queried by calling the Rust compiler
+//! with `--version`. The path to the compiler is determined first via the
+//! `RUSTC` environment variable. If it is not set, then `rustc` is used. If
+//! that fails, no determination is made, and calls return `None`.
+//!
+//! # Examples
+//!
+//! * Set a `cfg` flag in `build.rs` if the running compiler was determined to
+//! be at least version `1.13.0`:
+//!
+//! ```rust
+//! extern crate version_check as rustc;
+//!
+//! if rustc::is_min_version("1.13.0").unwrap_or(false) {
+//! println!("cargo:rustc-cfg=question_mark_operator");
+//! }
+//! ```
+//!
+//! See [`is_max_version`] or [`is_exact_version`] to check if the compiler
+//! is _at most_ or _exactly_ a certain version.
+//!
+//! * Check that the running compiler was released on or after `2018-12-18`:
+//!
+//! ```rust
+//! extern crate version_check as rustc;
+//!
+//! match rustc::is_min_date("2018-12-18") {
+//! Some(true) => "Yep! It's recent!",
+//! Some(false) => "No, it's older.",
+//! None => "Couldn't determine the rustc version."
+//! };
+//! ```
+//!
+//! See [`is_max_date`] or [`is_exact_date`] to check if the compiler was
+//! released _prior to_ or _exactly on_ a certain date.
+//!
+//! * Check that the running compiler supports feature flags:
+//!
+//! ```rust
+//! extern crate version_check as rustc;
+//!
+//! match rustc::is_feature_flaggable() {
+//! Some(true) => "Yes! It's a dev or nightly release!",
+//! Some(false) => "No, it's stable or beta.",
+//! None => "Couldn't determine the rustc version."
+//! };
+//! ```
+//!
+//! * Check that the running compiler supports a specific feature:
+//!
+//! ```rust
+//! extern crate version_check as rustc;
+//!
+//! if let Some(true) = rustc::supports_feature("doc_cfg") {
+//! println!("cargo:rustc-cfg=has_doc_cfg");
+//! }
+//! ```
+//!
+//! * Check that the running compiler is on the stable channel:
+//!
+//! ```rust
+//! extern crate version_check as rustc;
+//!
+//! match rustc::Channel::read() {
+//! Some(c) if c.is_stable() => format!("Yes! It's stable."),
+//! Some(c) => format!("No, the channel {} is not stable.", c),
+//! None => format!("Couldn't determine the rustc version.")
+//! };
+//! ```
+//!
+//! To interact with the version, release date, and release channel as structs,
+//! use [`Version`], [`Date`], and [`Channel`], respectively. The [`triple()`]
+//! function returns all three values efficiently.
+//!
+//! # Alternatives
+//!
+//! This crate is dead simple with no dependencies. If you need something more
+//! and don't care about panicking if the version cannot be obtained, or if you
+//! don't mind adding dependencies, see
+//! [rustc_version](https://crates.io/crates/rustc_version).
+
+#![allow(deprecated)]
+
+mod version;
+mod channel;
+mod date;
+
+use std::env;
+use std::process::Command;
+
+#[doc(inline)] pub use version::*;
+#[doc(inline)] pub use channel::*;
+#[doc(inline)] pub use date::*;
+
+/// Parses (version, date) as available from rustc version string.
+fn version_and_date_from_rustc_version(s: &str) -> (Option<String>, Option<String>) {
+ let last_line = s.lines().last().unwrap_or(s);
+ let mut components = last_line.trim().split(" ");
+ let version = components.nth(1);
+ let date = components.filter(|c| c.ends_with(')')).next()
+ .map(|s| s.trim_right().trim_right_matches(")").trim_left().trim_left_matches('('));
+ (version.map(|s| s.to_string()), date.map(|s| s.to_string()))
+}
+
+/// Parses (version, date) as available from rustc verbose version output.
+fn version_and_date_from_rustc_verbose_version(s: &str) -> (Option<String>, Option<String>) {
+ let (mut version, mut date) = (None, None);
+ for line in s.lines() {
+ let split = |s: &str| s.splitn(2, ":").nth(1).map(|s| s.trim().to_string());
+ match line.trim().split(" ").nth(0) {
+ Some("rustc") => {
+ let (v, d) = version_and_date_from_rustc_version(line);
+ version = version.or(v);
+ date = date.or(d);
+ },
+ Some("release:") => version = split(line),
+ Some("commit-date:") if line.ends_with("unknown") => date = None,
+ Some("commit-date:") => date = split(line),
+ _ => continue
+ }
+ }
+
+ (version, date)
+}
+
+/// Returns (version, date) as available from `rustc --version`.
+fn get_version_and_date() -> Option<(Option<String>, Option<String>)> {
+ let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".to_string());
+ Command::new(rustc).arg("--verbose").arg("--version").output().ok()
+ .and_then(|output| String::from_utf8(output.stdout).ok())
+ .map(|s| version_and_date_from_rustc_verbose_version(&s))
+}
+
+/// Reads the triple of [`Version`], [`Channel`], and [`Date`] of the installed
+/// or running `rustc`.
+///
+/// If any attribute cannot be determined (see the [top-level
+/// documentation](crate)), returns `None`.
+///
+/// To obtain only one of three attributes, use [`Version::read()`],
+/// [`Channel::read()`], or [`Date::read()`].
+pub fn triple() -> Option<(Version, Channel, Date)> {
+ let (version_str, date_str) = match get_version_and_date() {
+ Some((Some(version), Some(date))) => (version, date),
+ _ => return None
+ };
+
+ // Can't use `?` or `try!` for `Option` in 1.0.0.
+ match Version::parse(&version_str) {
+ Some(version) => match Channel::parse(&version_str) {
+ Some(channel) => match Date::parse(&date_str) {
+ Some(date) => Some((version, channel, date)),
+ _ => None,
+ },
+ _ => None,
+ },
+ _ => None
+ }
+}
+
+/// Checks that the running or installed `rustc` was released **on or after**
+/// some date.
+///
+/// The format of `min_date` must be YYYY-MM-DD. For instance: `2016-12-20` or
+/// `2017-01-09`.
+///
+/// If the date cannot be retrieved or parsed, or if `min_date` could not be
+/// parsed, returns `None`. Otherwise returns `true` if the installed `rustc`
+/// was release on or after `min_date` and `false` otherwise.
+pub fn is_min_date(min_date: &str) -> Option<bool> {
+ match (Date::read(), Date::parse(min_date)) {
+ (Some(rustc_date), Some(min_date)) => Some(rustc_date >= min_date),
+ _ => None
+ }
+}
+
+/// Checks that the running or installed `rustc` was released **on or before**
+/// some date.
+///
+/// The format of `max_date` must be YYYY-MM-DD. For instance: `2016-12-20` or
+/// `2017-01-09`.
+///
+/// If the date cannot be retrieved or parsed, or if `max_date` could not be
+/// parsed, returns `None`. Otherwise returns `true` if the installed `rustc`
+/// was release on or before `max_date` and `false` otherwise.
+pub fn is_max_date(max_date: &str) -> Option<bool> {
+ match (Date::read(), Date::parse(max_date)) {
+ (Some(rustc_date), Some(max_date)) => Some(rustc_date <= max_date),
+ _ => None
+ }
+}
+
+/// Checks that the running or installed `rustc` was released **exactly** on
+/// some date.
+///
+/// The format of `date` must be YYYY-MM-DD. For instance: `2016-12-20` or
+/// `2017-01-09`.
+///
+/// If the date cannot be retrieved or parsed, or if `date` could not be parsed,
+/// returns `None`. Otherwise returns `true` if the installed `rustc` was
+/// release on `date` and `false` otherwise.
+pub fn is_exact_date(date: &str) -> Option<bool> {
+ match (Date::read(), Date::parse(date)) {
+ (Some(rustc_date), Some(date)) => Some(rustc_date == date),
+ _ => None
+ }
+}
+
+/// Checks that the running or installed `rustc` is **at least** some minimum
+/// version.
+///
+/// The format of `min_version` is a semantic version: `1.3.0`, `1.15.0-beta`,
+/// `1.14.0`, `1.16.0-nightly`, etc.
+///
+/// If the version cannot be retrieved or parsed, or if `min_version` could not
+/// be parsed, returns `None`. Otherwise returns `true` if the installed `rustc`
+/// is at least `min_version` and `false` otherwise.
+pub fn is_min_version(min_version: &str) -> Option<bool> {
+ match (Version::read(), Version::parse(min_version)) {
+ (Some(rustc_ver), Some(min_ver)) => Some(rustc_ver >= min_ver),
+ _ => None
+ }
+}
+
+/// Checks that the running or installed `rustc` is **at most** some maximum
+/// version.
+///
+/// The format of `max_version` is a semantic version: `1.3.0`, `1.15.0-beta`,
+/// `1.14.0`, `1.16.0-nightly`, etc.
+///
+/// If the version cannot be retrieved or parsed, or if `max_version` could not
+/// be parsed, returns `None`. Otherwise returns `true` if the installed `rustc`
+/// is at most `max_version` and `false` otherwise.
+pub fn is_max_version(max_version: &str) -> Option<bool> {
+ match (Version::read(), Version::parse(max_version)) {
+ (Some(rustc_ver), Some(max_ver)) => Some(rustc_ver <= max_ver),
+ _ => None
+ }
+}
+
+/// Checks that the running or installed `rustc` is **exactly** some version.
+///
+/// The format of `version` is a semantic version: `1.3.0`, `1.15.0-beta`,
+/// `1.14.0`, `1.16.0-nightly`, etc.
+///
+/// If the version cannot be retrieved or parsed, or if `version` could not be
+/// parsed, returns `None`. Otherwise returns `true` if the installed `rustc` is
+/// exactly `version` and `false` otherwise.
+pub fn is_exact_version(version: &str) -> Option<bool> {
+ match (Version::read(), Version::parse(version)) {
+ (Some(rustc_ver), Some(version)) => Some(rustc_ver == version),
+ _ => None
+ }
+}
+
+/// Checks whether the running or installed `rustc` supports feature flags.
+///
+/// In other words, if the channel is either "nightly" or "dev".
+///
+/// Note that support for specific `rustc` features can be enabled or disabled
+/// via the `allow-features` compiler flag, which this function _does not_
+/// check. That is, this function _does not_ check whether a _specific_ feature
+/// is supported, but instead whether features are supported at all. To check
+/// for support for a specific feature, use [`supports_feature()`].
+///
+/// If the version could not be determined, returns `None`. Otherwise returns
+/// `true` if the running version supports feature flags and `false` otherwise.
+pub fn is_feature_flaggable() -> Option<bool> {
+ Channel::read().map(|c| c.supports_features())
+}
+
+/// Checks whether the running or installed `rustc` supports `feature`.
+///
+/// Returns _true_ _iff_ [`is_feature_flaggable()`] returns `true` _and_ the
+/// feature is not disabled via exclusion in `allow-features` via `RUSTFLAGS` or
+/// `CARGO_ENCODED_RUSTFLAGS`. If the version could not be determined, returns
+/// `None`.
+///
+/// # Example
+///
+/// ```rust
+/// use version_check as rustc;
+///
+/// if let Some(true) = rustc::supports_feature("doc_cfg") {
+/// println!("cargo:rustc-cfg=has_doc_cfg");
+/// }
+/// ```
+pub fn supports_feature(feature: &str) -> Option<bool> {
+ match is_feature_flaggable() {
+ Some(true) => { /* continue */ }
+ Some(false) => return Some(false),
+ None => return None,
+ }
+
+ let env_flags = env::var_os("CARGO_ENCODED_RUSTFLAGS")
+ .map(|flags| (flags, '\x1f'))
+ .or_else(|| env::var_os("RUSTFLAGS").map(|flags| (flags, ' ')));
+
+ if let Some((flags, delim)) = env_flags {
+ const ALLOW_FEATURES: &'static str = "allow-features=";
+
+ let rustflags = flags.to_string_lossy();
+ let allow_features = rustflags.split(delim)
+ .map(|flag| flag.trim_left_matches("-Z").trim())
+ .filter(|flag| flag.starts_with(ALLOW_FEATURES))
+ .map(|flag| &flag[ALLOW_FEATURES.len()..]);
+
+ if let Some(allow_features) = allow_features.last() {
+ return Some(allow_features.split(',').any(|f| f.trim() == feature));
+ }
+ }
+
+ // If there are no `RUSTFLAGS` or `CARGO_ENCODED_RUSTFLAGS` or they don't
+ // contain an `allow-features` flag, assume compiler allows all features.
+ Some(true)
+}
+
+#[cfg(test)]
+mod tests {
+ use std::{env, fs};
+
+ use super::version_and_date_from_rustc_version;
+ use super::version_and_date_from_rustc_verbose_version;
+
+ macro_rules! check_parse {
+ (@ $f:expr, $s:expr => $v:expr, $d:expr) => ({
+ if let (Some(v), d) = $f(&$s) {
+ let e_d: Option<&str> = $d.into();
+ assert_eq!((v, d), ($v.to_string(), e_d.map(|s| s.into())));
+ } else {
+ panic!("{:?} didn't parse for version testing.", $s);
+ }
+ });
+ ($f:expr, $s:expr => $v:expr, $d:expr) => ({
+ let warn = "warning: invalid logging spec 'warning', ignoring it";
+ let warn2 = "warning: sorry, something went wrong :(sad)";
+ check_parse!(@ $f, $s => $v, $d);
+ check_parse!(@ $f, &format!("{}\n{}", warn, $s) => $v, $d);
+ check_parse!(@ $f, &format!("{}\n{}", warn2, $s) => $v, $d);
+ check_parse!(@ $f, &format!("{}\n{}\n{}", warn, warn2, $s) => $v, $d);
+ check_parse!(@ $f, &format!("{}\n{}\n{}", warn2, warn, $s) => $v, $d);
+ })
+ }
+
+ macro_rules! check_terse_parse {
+ ($($s:expr => $v:expr, $d:expr,)+) => {$(
+ check_parse!(version_and_date_from_rustc_version, $s => $v, $d);
+ )+}
+ }
+
+ macro_rules! check_verbose_parse {
+ ($($s:expr => $v:expr, $d:expr,)+) => {$(
+ check_parse!(version_and_date_from_rustc_verbose_version, $s => $v, $d);
+ )+}
+ }
+
+ #[test]
+ fn test_version_parse() {
+ check_terse_parse! {
+ "rustc 1.18.0" => "1.18.0", None,
+ "rustc 1.8.0" => "1.8.0", None,
+ "rustc 1.20.0-nightly" => "1.20.0-nightly", None,
+ "rustc 1.20" => "1.20", None,
+ "rustc 1.3" => "1.3", None,
+ "rustc 1" => "1", None,
+ "rustc 1.5.1-beta" => "1.5.1-beta", None,
+ "rustc 1.20.0 (2017-07-09)" => "1.20.0", Some("2017-07-09"),
+ "rustc 1.20.0-dev (2017-07-09)" => "1.20.0-dev", Some("2017-07-09"),
+ "rustc 1.20.0-nightly (d84693b93 2017-07-09)" => "1.20.0-nightly", Some("2017-07-09"),
+ "rustc 1.20.0 (d84693b93 2017-07-09)" => "1.20.0", Some("2017-07-09"),
+ "rustc 1.30.0-nightly (3bc2ca7e4 2018-09-20)" => "1.30.0-nightly", Some("2018-09-20"),
+ };
+ }
+
+ #[test]
+ fn test_verbose_version_parse() {
+ check_verbose_parse! {
+ "rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)\n\
+ binary: rustc\n\
+ commit-hash: a59de37e99060162a2674e3ff45409ac73595c0e\n\
+ commit-date: 2015-05-13\n\
+ build-date: 2015-05-14\n\
+ host: x86_64-unknown-linux-gnu\n\
+ release: 1.0.0" => "1.0.0", Some("2015-05-13"),
+
+ "rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)\n\
+ commit-hash: a59de37e99060162a2674e3ff45409ac73595c0e\n\
+ commit-date: 2015-05-13\n\
+ build-date: 2015-05-14\n\
+ host: x86_64-unknown-linux-gnu\n\
+ release: 1.0.0" => "1.0.0", Some("2015-05-13"),
+
+ "rustc 1.50.0 (cb75ad5db 2021-02-10)\n\
+ binary: rustc\n\
+ commit-hash: cb75ad5db02783e8b0222fee363c5f63f7e2cf5b\n\
+ commit-date: 2021-02-10\n\
+ host: x86_64-unknown-linux-gnu\n\
+ release: 1.50.0" => "1.50.0", Some("2021-02-10"),
+
+ "rustc 1.52.0-nightly (234781afe 2021-03-07)\n\
+ binary: rustc\n\
+ commit-hash: 234781afe33d3f339b002f85f948046d8476cfc9\n\
+ commit-date: 2021-03-07\n\
+ host: x86_64-unknown-linux-gnu\n\
+ release: 1.52.0-nightly\n\
+ LLVM version: 12.0.0" => "1.52.0-nightly", Some("2021-03-07"),
+
+ "rustc 1.41.1\n\
+ binary: rustc\n\
+ commit-hash: unknown\n\
+ commit-date: unknown\n\
+ host: x86_64-unknown-linux-gnu\n\
+ release: 1.41.1\n\
+ LLVM version: 7.0" => "1.41.1", None,
+
+ "rustc 1.49.0\n\
+ binary: rustc\n\
+ commit-hash: unknown\n\
+ commit-date: unknown\n\
+ host: x86_64-unknown-linux-gnu\n\
+ release: 1.49.0" => "1.49.0", None,
+
+ "rustc 1.50.0 (Fedora 1.50.0-1.fc33)\n\
+ binary: rustc\n\
+ commit-hash: unknown\n\
+ commit-date: unknown\n\
+ host: x86_64-unknown-linux-gnu\n\
+ release: 1.50.0" => "1.50.0", None,
+ };
+ }
+
+ fn read_static(verbose: bool, channel: &str, minor: usize) -> String {
+ use std::fs::File;
+ use std::path::Path;
+ use std::io::{BufReader, Read};
+
+ let subdir = if verbose { "verbose" } else { "terse" };
+ let path = Path::new(STATIC_PATH)
+ .join(channel)
+ .join(subdir)
+ .join(format!("rustc-1.{}.0", minor));
+
+ let file = File::open(path).unwrap();
+ let mut buf_reader = BufReader::new(file);
+ let mut contents = String::new();
+ buf_reader.read_to_string(&mut contents).unwrap();
+ contents
+ }
+
+ static STATIC_PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/static");
+
+ static DATES: [&'static str; 51] = [
+ "2015-05-13", "2015-06-19", "2015-08-03", "2015-09-15", "2015-10-27",
+ "2015-12-04", "2016-01-19", "2016-02-29", "2016-04-11", "2016-05-18",
+ "2016-07-03", "2016-08-15", "2016-09-23", "2016-11-07", "2016-12-16",
+ "2017-01-19", "2017-03-10", "2017-04-24", "2017-06-06", "2017-07-17",
+ "2017-08-27", "2017-10-09", "2017-11-20", "2018-01-01", "2018-02-12",
+ "2018-03-25", "2018-05-07", "2018-06-19", "2018-07-30", "2018-09-11",
+ "2018-10-24", "2018-12-04", "2019-01-16", "2019-02-28", "2019-04-10",
+ "2019-05-20", "2019-07-03", "2019-08-13", "2019-09-23", "2019-11-04",
+ "2019-12-16", "2020-01-27", "2020-03-09", "2020-04-20", "2020-06-01",
+ "2020-07-13", "2020-08-24", "2020-10-07", "2020-11-16", "2020-12-29",
+ "2021-02-10",
+ ];
+
+ #[test]
+ fn test_stable_compatibility() {
+ if env::var_os("FORCE_STATIC").is_none() && fs::metadata(STATIC_PATH).is_err() {
+ // We exclude `/static` when we package `version_check`, so don't
+ // run if static files aren't present unless we know they should be.
+ return;
+ }
+
+ // Ensure we can parse all output from all Linux stable releases.
+ for v in 0..DATES.len() {
+ let (version, date) = (&format!("1.{}.0", v), Some(DATES[v]));
+ check_terse_parse!(read_static(false, "stable", v) => version, date,);
+ check_verbose_parse!(read_static(true, "stable", v) => version, date,);
+ }
+ }
+
+ #[test]
+ fn test_parse_current() {
+ let (version, channel) = (::Version::read(), ::Channel::read());
+ assert!(version.is_some());
+ assert!(channel.is_some());
+
+ if let Ok(known_channel) = env::var("KNOWN_CHANNEL") {
+ assert_eq!(channel, ::Channel::parse(&known_channel));
+ }
+ }
+}
diff --git a/rust/hw/char/pl011/vendor/version_check/src/version.rs b/rust/hw/char/pl011/vendor/version_check/src/version.rs
new file mode 100644
index 0000000000..2bc18aae2b
--- /dev/null
+++ b/rust/hw/char/pl011/vendor/version_check/src/version.rs
@@ -0,0 +1,316 @@
+use std::fmt;
+
+/// Version number: `major.minor.patch`, ignoring release channel.
+#[derive(PartialEq, Eq, Copy, Clone, PartialOrd, Ord)]
+pub struct Version(u64);
+
+impl Version {
+ /// Reads the version of the running compiler. If it cannot be determined
+ /// (see the [top-level documentation](crate)), returns `None`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Version;
+ ///
+ /// match Version::read() {
+ /// Some(d) => format!("Version is: {}", d),
+ /// None => format!("Failed to read the version.")
+ /// };
+ /// ```
+ pub fn read() -> Option<Version> {
+ ::get_version_and_date()
+ .and_then(|(version, _)| version)
+ .and_then(|version| Version::parse(&version))
+ }
+
+
+ /// Parse a Rust release version (of the form
+ /// `major[.minor[.patch[-channel]]]`), ignoring the release channel, if
+ /// any. Returns `None` if `version` is not a valid Rust version string.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Version;
+ ///
+ /// let version = Version::parse("1.18.0").unwrap();
+ /// assert!(version.exactly("1.18.0"));
+ ///
+ /// let version = Version::parse("1.20.0-nightly").unwrap();
+ /// assert!(version.exactly("1.20.0"));
+ /// assert!(version.exactly("1.20.0-beta"));
+ ///
+ /// let version = Version::parse("1.3").unwrap();
+ /// assert!(version.exactly("1.3.0"));
+ ///
+ /// let version = Version::parse("1").unwrap();
+ /// assert!(version.exactly("1.0.0"));
+ ///
+ /// assert!(Version::parse("one.two.three").is_none());
+ /// assert!(Version::parse("1.65536.2").is_none());
+ /// assert!(Version::parse("1. 2").is_none());
+ /// assert!(Version::parse("").is_none());
+ /// assert!(Version::parse("1.").is_none());
+ /// assert!(Version::parse("1.2.3.4").is_none());
+ /// ```
+ pub fn parse(version: &str) -> Option<Version> {
+ let splits = version.split('-')
+ .nth(0)
+ .unwrap_or("")
+ .split('.')
+ .map(|s| s.parse::<u16>());
+
+ let mut mmp = [0u16; 3];
+ for (i, split) in splits.enumerate() {
+ mmp[i] = match (i, split) {
+ (3, _) | (_, Err(_)) => return None,
+ (_, Ok(v)) => v,
+ };
+ }
+
+ let (maj, min, patch) = (mmp[0], mmp[1], mmp[2]);
+ Some(Version::from_mmp(maj, min, patch))
+ }
+
+ /// Creates a `Version` from `(major, minor, patch)` version components.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Version;
+ ///
+ /// assert!(Version::from_mmp(1, 35, 0).exactly("1.35.0"));
+ /// assert!(Version::from_mmp(1, 33, 0).exactly("1.33.0"));
+ /// assert!(Version::from_mmp(1, 35, 1).exactly("1.35.1"));
+ /// assert!(Version::from_mmp(1, 13, 2).exactly("1.13.2"));
+ /// ```
+ pub fn from_mmp(major: u16, minor: u16, patch: u16) -> Version {
+ Version(((major as u64) << 32) | ((minor as u64) << 16) | patch as u64)
+ }
+
+ /// Returns the `(major, minor, patch)` version components of `self`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Version;
+ ///
+ /// assert_eq!(Version::parse("1.35.0").unwrap().to_mmp(), (1, 35, 0));
+ /// assert_eq!(Version::parse("1.33.0").unwrap().to_mmp(), (1, 33, 0));
+ /// assert_eq!(Version::parse("1.35.1").unwrap().to_mmp(), (1, 35, 1));
+ /// assert_eq!(Version::parse("1.13.2").unwrap().to_mmp(), (1, 13, 2));
+ /// ```
+ pub fn to_mmp(&self) -> (u16, u16, u16) {
+ let major = self.0 >> 32;
+ let minor = self.0 >> 16;
+ let patch = self.0;
+ (major as u16, minor as u16, patch as u16)
+ }
+
+ /// Returns `true` if `self` is greater than or equal to `version`.
+ ///
+ /// If `version` is greater than `self`, or if `version` is not a valid Rust
+ /// version string, returns `false`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Version;
+ ///
+ /// let version = Version::parse("1.35.0").unwrap();
+ ///
+ /// assert!(version.at_least("1.33.0"));
+ /// assert!(version.at_least("1.35.0"));
+ /// assert!(version.at_least("1.13.2"));
+ ///
+ /// assert!(!version.at_least("1.35.1"));
+ /// assert!(!version.at_least("1.55.0"));
+ ///
+ /// let version = Version::parse("1.12.5").unwrap();
+ ///
+ /// assert!(version.at_least("1.12.0"));
+ /// assert!(!version.at_least("1.35.0"));
+ /// ```
+ pub fn at_least(&self, version: &str) -> bool {
+ Version::parse(version)
+ .map(|version| self >= &version)
+ .unwrap_or(false)
+ }
+
+ /// Returns `true` if `self` is less than or equal to `version`.
+ ///
+ /// If `version` is less than `self`, or if `version` is not a valid Rust
+ /// version string, returns `false`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Version;
+ ///
+ /// let version = Version::parse("1.35.0").unwrap();
+ ///
+ /// assert!(version.at_most("1.35.1"));
+ /// assert!(version.at_most("1.55.0"));
+ /// assert!(version.at_most("1.35.0"));
+ ///
+ /// assert!(!version.at_most("1.33.0"));
+ /// assert!(!version.at_most("1.13.2"));
+ /// ```
+ pub fn at_most(&self, version: &str) -> bool {
+ Version::parse(version)
+ .map(|version| self <= &version)
+ .unwrap_or(false)
+ }
+
+ /// Returns `true` if `self` is exactly equal to `version`.
+ ///
+ /// If `version` is not equal to `self`, or if `version` is not a valid Rust
+ /// version string, returns `false`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use version_check::Version;
+ ///
+ /// let version = Version::parse("1.35.0").unwrap();
+ ///
+ /// assert!(version.exactly("1.35.0"));
+ ///
+ /// assert!(!version.exactly("1.33.0"));
+ /// assert!(!version.exactly("1.35.1"));
+ /// assert!(!version.exactly("1.13.2"));
+ /// ```
+ pub fn exactly(&self, version: &str) -> bool {
+ Version::parse(version)
+ .map(|version| self == &version)
+ .unwrap_or(false)
+ }
+}
+
+impl fmt::Display for Version {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let (major, minor, patch) = self.to_mmp();
+ write!(f, "{}.{}.{}", major, minor, patch)
+ }
+}
+
+impl fmt::Debug for Version {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ // We don't use `debug_*` because it's not available in `1.0.0`.
+ write!(f, "Version({:?}, {:?})", self.0, self.to_mmp())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::Version;
+
+ macro_rules! assert_to_mmp {
+ // We don't use `.into::<Option<_>>` because it's not available in 1.0.
+ // We don't use the message part of `assert!` for the same reason.
+ ($s:expr, None) => (
+ assert_eq!(Version::parse($s), None);
+ );
+ ($s:expr, $mmp:expr) => (
+ assert_eq!(Version::parse($s).map(|v| v.to_mmp()), Some($mmp));
+ )
+ }
+
+ macro_rules! assert_from_mmp {
+ (($x:expr, $y:expr, $z:expr) => $s:expr) => {
+ assert_eq!(Some(Version::from_mmp($x, $y, $z)), Version::parse($s));
+ };
+ }
+
+ #[test]
+ fn test_str_to_mmp() {
+ assert_to_mmp!("1", (1, 0, 0));
+ assert_to_mmp!("1.2", (1, 2, 0));
+ assert_to_mmp!("1.18.0", (1, 18, 0));
+ assert_to_mmp!("3.19.0", (3, 19, 0));
+ assert_to_mmp!("1.19.0-nightly", (1, 19, 0));
+ assert_to_mmp!("1.12.2349", (1, 12, 2349));
+ assert_to_mmp!("0.12", (0, 12, 0));
+ assert_to_mmp!("1.12.5", (1, 12, 5));
+ assert_to_mmp!("1.12", (1, 12, 0));
+ assert_to_mmp!("1", (1, 0, 0));
+ assert_to_mmp!("1.4.4-nightly (d84693b93 2017-07-09))", (1, 4, 4));
+ assert_to_mmp!("1.58879.4478-dev", (1, 58879, 4478));
+ assert_to_mmp!("1.58879.4478-dev (d84693b93 2017-07-09))", (1, 58879, 4478));
+ }
+
+ #[test]
+ fn test_malformed() {
+ assert_to_mmp!("1.65536.2", None);
+ assert_to_mmp!("-1.2.3", None);
+ assert_to_mmp!("1. 2", None);
+ assert_to_mmp!("", None);
+ assert_to_mmp!(" ", None);
+ assert_to_mmp!(".", None);
+ assert_to_mmp!("one", None);
+ assert_to_mmp!("1.", None);
+ assert_to_mmp!("1.2.3.4.5.6", None);
+ }
+
+ #[test]
+ fn test_from_mmp() {
+ assert_from_mmp!((1, 18, 0) => "1.18.0");
+ assert_from_mmp!((3, 19, 0) => "3.19.0");
+ assert_from_mmp!((1, 19, 0) => "1.19.0");
+ assert_from_mmp!((1, 12, 2349) => "1.12.2349");
+ assert_from_mmp!((0, 12, 0) => "0.12");
+ assert_from_mmp!((1, 12, 5) => "1.12.5");
+ assert_from_mmp!((1, 12, 0) => "1.12");
+ assert_from_mmp!((1, 0, 0) => "1");
+ assert_from_mmp!((1, 4, 4) => "1.4.4");
+ assert_from_mmp!((1, 58879, 4478) => "1.58879.4478");
+ }
+
+ #[test]
+ fn test_comparisons() {
+ let version = Version::parse("1.18.0").unwrap();
+ assert!(version.exactly("1.18.0"));
+ assert!(version.at_least("1.12.0"));
+ assert!(version.at_least("1.12"));
+ assert!(version.at_least("1"));
+ assert!(version.at_most("1.18.1"));
+ assert!(!version.exactly("1.19.0"));
+ assert!(!version.exactly("1.18.1"));
+
+ let version = Version::parse("1.20.0-nightly").unwrap();
+ assert!(version.exactly("1.20.0-beta"));
+ assert!(version.exactly("1.20.0-nightly"));
+ assert!(version.exactly("1.20.0"));
+ assert!(!version.exactly("1.19"));
+
+ let version = Version::parse("1.3").unwrap();
+ assert!(version.exactly("1.3.0"));
+ assert!(version.exactly("1.3.0-stable"));
+ assert!(version.exactly("1.3"));
+ assert!(!version.exactly("1.5.0-stable"));
+
+ let version = Version::parse("1").unwrap();
+ assert!(version.exactly("1.0.0"));
+ assert!(version.exactly("1.0"));
+ assert!(version.exactly("1"));
+
+ assert!(Version::parse("one.two.three").is_none());
+ }
+
+ macro_rules! reflexive_display {
+ ($s:expr) => (
+ assert_eq!(Version::parse($s).unwrap().to_string(), $s);
+ )
+ }
+
+ #[test]
+ fn display() {
+ reflexive_display!("1.0.0");
+ reflexive_display!("1.2.3");
+ reflexive_display!("1.12.1438");
+ reflexive_display!("1.44.0");
+ reflexive_display!("2.44.0");
+ reflexive_display!("23459.28923.3483");
+ }
+}
--
γαῖα πυρί μιχθήτω
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 1/8] build-sys: Add rust feature option
2024-07-22 11:43 ` [RFC PATCH v5 1/8] build-sys: Add rust feature option Manos Pitsidianakis
@ 2024-07-23 6:37 ` Zhao Liu
2024-07-23 10:13 ` Manos Pitsidianakis
0 siblings, 1 reply; 35+ messages in thread
From: Zhao Liu @ 2024-07-23 6:37 UTC (permalink / raw)
To: Manos Pitsidianakis
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Bennée, Daniel P. Berrangé, Marc-André Lureau,
Thomas Huth, Markus Armbruster, Philippe Mathieu-Daudé,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson,
Paolo Bonzini
Hi Manos,
On Mon, Jul 22, 2024 at 02:43:31PM +0300, Manos Pitsidianakis wrote:
> Date: Mon, 22 Jul 2024 14:43:31 +0300
> From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> Subject: [RFC PATCH v5 1/8] build-sys: Add rust feature option
> X-Mailer: git-send-email 2.44.0
>
> Add rust feature in meson.build, configure, to prepare for adding Rust
> code in the followup commits.
>
> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
> MAINTAINERS | 5 +++++
> configure | 12 ++++++++++++
> meson.build | 17 ++++++++++++++++-
> Kconfig | 1 +
> Kconfig.host | 3 +++
> meson_options.txt | 5 +++++
> rust/Kconfig | 0
> scripts/meson-buildoptions.sh | 3 +++
> 8 files changed, 45 insertions(+), 1 deletion(-)
> create mode 100644 rust/Kconfig
>
[snip]
> diff --git a/meson.build b/meson.build
> index a1e51277b0..a3f346ab3c 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -70,6 +70,14 @@ if host_os == 'darwin' and \
> all_languages += ['objc']
> objc = meson.get_compiler('objc')
> endif
> +if get_option('have_rust') and meson.version().version_compare('<1.0.0')
> + error('Rust support requires Meson version >=1.0.0')
> +endif
> +have_rust = false
> +if not get_option('disable_rust') and add_languages('rust', required: get_option('have_rust'), native: false)
> + rustc = meson.get_compiler('rust')
> + have_rust = true
> +endif
Only a nit, "disable_rust" seems redundant, and "have_rust" is enough.
Others LGTM,
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 2/8] build deps: update lcitool to include rust bits
2024-07-22 11:43 ` [RFC PATCH v5 2/8] build deps: update lcitool to include rust bits Manos Pitsidianakis
@ 2024-07-23 8:31 ` Richard Henderson
2024-07-23 10:11 ` Manos Pitsidianakis
0 siblings, 1 reply; 35+ messages in thread
From: Richard Henderson @ 2024-07-23 8:31 UTC (permalink / raw)
To: Manos Pitsidianakis, qemu-devel
On 7/22/24 21:43, Manos Pitsidianakis wrote:
> From: Alex Bennée<alex.bennee@linaro.org>
>
> For rust development we need cargo, rustc and bindgen in our various
> development environments. Update the libvirt-ci project to (!495) and
> regenerate the containers and other dependency lists.
The cover letter for v5 says use of cargo eliminated.
Therefore no need to add to qemu.yml, correct?
r~
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 3/8] CI: Add build-system-rust-debian job
2024-07-22 11:43 ` [RFC PATCH v5 3/8] CI: Add build-system-rust-debian job Manos Pitsidianakis
@ 2024-07-23 8:32 ` Richard Henderson
2024-07-23 8:39 ` Daniel P. Berrangé
1 sibling, 0 replies; 35+ messages in thread
From: Richard Henderson @ 2024-07-23 8:32 UTC (permalink / raw)
To: Manos Pitsidianakis, qemu-devel
On 7/22/24 21:43, Manos Pitsidianakis wrote:
> Add job that builds with rust support enabled on debian.
>
> Signed-off-by: Manos Pitsidianakis<manos.pitsidianakis@linaro.org>
> ---
> .gitlab-ci.d/buildtest.yml | 11 +++++++++++
> 1 file changed, 11 insertions(+)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 8/8] rust/pl011: vendor dependencies
2024-07-22 11:43 ` [RFC PATCH v5 8/8] rust/pl011: vendor dependencies Manos Pitsidianakis
@ 2024-07-23 8:37 ` Zhao Liu
2024-07-23 10:19 ` Manos Pitsidianakis
0 siblings, 1 reply; 35+ messages in thread
From: Zhao Liu @ 2024-07-23 8:37 UTC (permalink / raw)
To: Manos Pitsidianakis
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Bennée, Daniel P. Berrangé, Marc-André Lureau,
Thomas Huth, Markus Armbruster, Philippe Mathieu-Daudé,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson
Hi Manos,
(This patch contains too many codes so that mail list rejects to display
it at https://lore.kernel.org/qemu-devel)
Please correct me if I'm wrong...
Is the reason for not using git submodules here because v5 abandoned
compilation through Cargo, so it’s necessary to add meson.build to the
code repository of each dependency, and consequently, all code must be
loaded into QEMU?
It looks like will be difficult to synchronize the dependency changes
in the future.
Best Regards,
Zhao
On Mon, Jul 22, 2024 at 02:43:38PM +0300, Manos Pitsidianakis wrote:
> Date: Mon, 22 Jul 2024 14:43:38 +0300
> From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> Subject: [RFC PATCH v5 8/8] rust/pl011: vendor dependencies
> X-Mailer: git-send-email 2.44.0
>
> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
> rust/hw/char/pl011/vendor/either/README.rst | 185 +
> .../vendor/arbitrary-int/.cargo-checksum.json | 1 +
> .../pl011/vendor/arbitrary-int/CHANGELOG.md | 47 +
> .../pl011/vendor/arbitrary-int/Cargo.toml | 54 +
> .../pl011/vendor/arbitrary-int/LICENSE.txt | 21 +
> .../char/pl011/vendor/arbitrary-int/README.md | 72 +
> .../pl011/vendor/arbitrary-int/meson.build | 14 +
> .../pl011/vendor/arbitrary-int/src/lib.rs | 1489 +++++
> .../pl011/vendor/arbitrary-int/tests/tests.rs | 1913 ++++++
> .../vendor/bilge-impl/.cargo-checksum.json | 1 +
> .../char/pl011/vendor/bilge-impl/Cargo.toml | 54 +
> .../hw/char/pl011/vendor/bilge-impl/README.md | 327 ++
> .../char/pl011/vendor/bilge-impl/meson.build | 24 +
> .../pl011/vendor/bilge-impl/src/bitsize.rs | 187 +
> .../vendor/bilge-impl/src/bitsize/split.rs | 185 +
> .../vendor/bilge-impl/src/bitsize_internal.rs | 235 +
> .../src/bitsize_internal/struct_gen.rs | 402 ++
> .../pl011/vendor/bilge-impl/src/debug_bits.rs | 55 +
> .../vendor/bilge-impl/src/default_bits.rs | 92 +
> .../pl011/vendor/bilge-impl/src/fmt_bits.rs | 112 +
> .../pl011/vendor/bilge-impl/src/from_bits.rs | 222 +
> .../char/pl011/vendor/bilge-impl/src/lib.rs | 79 +
> .../pl011/vendor/bilge-impl/src/shared.rs | 196 +
> .../src/shared/discriminant_assigner.rs | 56 +
> .../vendor/bilge-impl/src/shared/fallback.rs | 92 +
> .../vendor/bilge-impl/src/shared/util.rs | 91 +
> .../vendor/bilge-impl/src/try_from_bits.rs | 143 +
> .../pl011/vendor/bilge/.cargo-checksum.json | 1 +
> rust/hw/char/pl011/vendor/bilge/Cargo.toml | 69 +
> .../hw/char/pl011/vendor/bilge/LICENSE-APACHE | 176 +
> rust/hw/char/pl011/vendor/bilge/LICENSE-MIT | 17 +
> rust/hw/char/pl011/vendor/bilge/README.md | 327 ++
> rust/hw/char/pl011/vendor/bilge/meson.build | 17 +
> rust/hw/char/pl011/vendor/bilge/src/lib.rs | 80 +
> .../pl011/vendor/either/.cargo-checksum.json | 1 +
> rust/hw/char/pl011/vendor/either/Cargo.toml | 54 +
> .../char/pl011/vendor/either/LICENSE-APACHE | 201 +
> rust/hw/char/pl011/vendor/either/LICENSE-MIT | 25 +
> .../pl011/vendor/either/README-crates.io.md | 10 +
> rust/hw/char/pl011/vendor/either/meson.build | 16 +
> .../pl011/vendor/either/src/into_either.rs | 64 +
> .../char/pl011/vendor/either/src/iterator.rs | 315 +
> rust/hw/char/pl011/vendor/either/src/lib.rs | 1519 +++++
> .../pl011/vendor/either/src/serde_untagged.rs | 69 +
> .../either/src/serde_untagged_optional.rs | 74 +
> .../vendor/itertools/.cargo-checksum.json | 1 +
> .../char/pl011/vendor/itertools/CHANGELOG.md | 409 ++
> .../hw/char/pl011/vendor/itertools/Cargo.lock | 681 +++
> .../hw/char/pl011/vendor/itertools/Cargo.toml | 101 +
> .../pl011/vendor/itertools/LICENSE-APACHE | 201 +
> .../char/pl011/vendor/itertools/LICENSE-MIT | 25 +
> rust/hw/char/pl011/vendor/itertools/README.md | 44 +
> .../pl011/vendor/itertools/benches/bench1.rs | 877 +++
> .../vendor/itertools/benches/combinations.rs | 125 +
> .../benches/combinations_with_replacement.rs | 40 +
> .../vendor/itertools/benches/extra/mod.rs | 2 +
> .../itertools/benches/extra/zipslices.rs | 188 +
> .../itertools/benches/fold_specialization.rs | 73 +
> .../vendor/itertools/benches/powerset.rs | 44 +
> .../vendor/itertools/benches/tree_fold1.rs | 144 +
> .../itertools/benches/tuple_combinations.rs | 113 +
> .../pl011/vendor/itertools/benches/tuples.rs | 213 +
> .../pl011/vendor/itertools/examples/iris.data | 150 +
> .../pl011/vendor/itertools/examples/iris.rs | 137 +
> .../char/pl011/vendor/itertools/meson.build | 18 +
> .../vendor/itertools/src/adaptors/coalesce.rs | 235 +
> .../vendor/itertools/src/adaptors/map.rs | 124 +
> .../vendor/itertools/src/adaptors/mod.rs | 1151 ++++
> .../itertools/src/adaptors/multi_product.rs | 230 +
> .../vendor/itertools/src/combinations.rs | 128 +
> .../src/combinations_with_replacement.rs | 109 +
> .../pl011/vendor/itertools/src/concat_impl.rs | 23 +
> .../vendor/itertools/src/cons_tuples_impl.rs | 64 +
> .../char/pl011/vendor/itertools/src/diff.rs | 61 +
> .../vendor/itertools/src/duplicates_impl.rs | 216 +
> .../vendor/itertools/src/either_or_both.rs | 495 ++
> .../vendor/itertools/src/exactly_one_err.rs | 110 +
> .../pl011/vendor/itertools/src/extrema_set.rs | 48 +
> .../pl011/vendor/itertools/src/flatten_ok.rs | 165 +
> .../char/pl011/vendor/itertools/src/format.rs | 168 +
> .../char/pl011/vendor/itertools/src/free.rs | 286 +
> .../pl011/vendor/itertools/src/group_map.rs | 32 +
> .../pl011/vendor/itertools/src/groupbylazy.rs | 579 ++
> .../vendor/itertools/src/grouping_map.rs | 535 ++
> .../pl011/vendor/itertools/src/impl_macros.rs | 29 +
> .../pl011/vendor/itertools/src/intersperse.rs | 118 +
> .../pl011/vendor/itertools/src/k_smallest.rs | 20 +
> .../pl011/vendor/itertools/src/kmerge_impl.rs | 227 +
> .../pl011/vendor/itertools/src/lazy_buffer.rs | 63 +
> .../hw/char/pl011/vendor/itertools/src/lib.rs | 3967 +++++++++++++
> .../pl011/vendor/itertools/src/merge_join.rs | 220 +
> .../char/pl011/vendor/itertools/src/minmax.rs | 115 +
> .../vendor/itertools/src/multipeek_impl.rs | 101 +
> .../pl011/vendor/itertools/src/pad_tail.rs | 96 +
> .../pl011/vendor/itertools/src/peek_nth.rs | 102 +
> .../itertools/src/peeking_take_while.rs | 177 +
> .../vendor/itertools/src/permutations.rs | 277 +
> .../pl011/vendor/itertools/src/powerset.rs | 90 +
> .../itertools/src/process_results_impl.rs | 68 +
> .../vendor/itertools/src/put_back_n_impl.rs | 61 +
> .../pl011/vendor/itertools/src/rciter_impl.rs | 99 +
> .../pl011/vendor/itertools/src/repeatn.rs | 59 +
> .../pl011/vendor/itertools/src/size_hint.rs | 119 +
> .../pl011/vendor/itertools/src/sources.rs | 183 +
> .../itertools/src/take_while_inclusive.rs | 68 +
> .../hw/char/pl011/vendor/itertools/src/tee.rs | 78 +
> .../pl011/vendor/itertools/src/tuple_impl.rs | 331 ++
> .../pl011/vendor/itertools/src/unique_impl.rs | 179 +
> .../pl011/vendor/itertools/src/unziptuple.rs | 80 +
> .../vendor/itertools/src/with_position.rs | 88 +
> .../pl011/vendor/itertools/src/zip_eq_impl.rs | 60 +
> .../pl011/vendor/itertools/src/zip_longest.rs | 83 +
> .../pl011/vendor/itertools/src/ziptuple.rs | 138 +
> .../itertools/tests/adaptors_no_collect.rs | 46 +
> .../vendor/itertools/tests/flatten_ok.rs | 76 +
> .../vendor/itertools/tests/macros_hygiene.rs | 13 +
> .../vendor/itertools/tests/merge_join.rs | 108 +
> .../itertools/tests/peeking_take_while.rs | 69 +
> .../pl011/vendor/itertools/tests/quick.rs | 1849 ++++++
> .../vendor/itertools/tests/specializations.rs | 153 +
> .../pl011/vendor/itertools/tests/test_core.rs | 317 +
> .../pl011/vendor/itertools/tests/test_std.rs | 1184 ++++
> .../pl011/vendor/itertools/tests/tuples.rs | 86 +
> .../char/pl011/vendor/itertools/tests/zip.rs | 77 +
> rust/hw/char/pl011/vendor/meson.build | 18 +
> .../.cargo-checksum.json | 1 +
> .../vendor/proc-macro-error-attr/Cargo.toml | 33 +
> .../proc-macro-error-attr/LICENSE-APACHE | 201 +
> .../vendor/proc-macro-error-attr/LICENSE-MIT | 21 +
> .../vendor/proc-macro-error-attr/build.rs | 5 +
> .../vendor/proc-macro-error-attr/meson.build | 20 +
> .../vendor/proc-macro-error-attr/src/lib.rs | 121 +
> .../vendor/proc-macro-error-attr/src/parse.rs | 89 +
> .../proc-macro-error-attr/src/settings.rs | 72 +
> .../proc-macro-error/.cargo-checksum.json | 1 +
> .../vendor/proc-macro-error/CHANGELOG.md | 162 +
> .../pl011/vendor/proc-macro-error/Cargo.toml | 56 +
> .../vendor/proc-macro-error/LICENSE-APACHE | 201 +
> .../pl011/vendor/proc-macro-error/LICENSE-MIT | 21 +
> .../pl011/vendor/proc-macro-error/README.md | 258 +
> .../pl011/vendor/proc-macro-error/build.rs | 11 +
> .../pl011/vendor/proc-macro-error/meson.build | 22 +
> .../vendor/proc-macro-error/src/diagnostic.rs | 349 ++
> .../vendor/proc-macro-error/src/dummy.rs | 150 +
> .../proc-macro-error/src/imp/delegate.rs | 69 +
> .../proc-macro-error/src/imp/fallback.rs | 30 +
> .../pl011/vendor/proc-macro-error/src/lib.rs | 560 ++
> .../vendor/proc-macro-error/src/macros.rs | 288 +
> .../vendor/proc-macro-error/src/sealed.rs | 3 +
> .../proc-macro-error/tests/macro-errors.rs | 8 +
> .../pl011/vendor/proc-macro-error/tests/ok.rs | 10 +
> .../proc-macro-error/tests/runtime-errors.rs | 13 +
> .../vendor/proc-macro-error/tests/ui/abort.rs | 11 +
> .../proc-macro-error/tests/ui/abort.stderr | 48 +
> .../proc-macro-error/tests/ui/append_dummy.rs | 13 +
> .../tests/ui/append_dummy.stderr | 5 +
> .../tests/ui/children_messages.rs | 6 +
> .../tests/ui/children_messages.stderr | 23 +
> .../vendor/proc-macro-error/tests/ui/dummy.rs | 13 +
> .../proc-macro-error/tests/ui/dummy.stderr | 5 +
> .../vendor/proc-macro-error/tests/ui/emit.rs | 7 +
> .../proc-macro-error/tests/ui/emit.stderr | 48 +
> .../tests/ui/explicit_span_range.rs | 6 +
> .../tests/ui/explicit_span_range.stderr | 5 +
> .../proc-macro-error/tests/ui/misuse.rs | 11 +
> .../proc-macro-error/tests/ui/misuse.stderr | 13 +
> .../tests/ui/multiple_tokens.rs | 6 +
> .../tests/ui/multiple_tokens.stderr | 5 +
> .../tests/ui/not_proc_macro.rs | 4 +
> .../tests/ui/not_proc_macro.stderr | 10 +
> .../proc-macro-error/tests/ui/option_ext.rs | 6 +
> .../tests/ui/option_ext.stderr | 7 +
> .../tests/ui/proc_macro_hack.rs | 10 +
> .../tests/ui/proc_macro_hack.stderr | 26 +
> .../proc-macro-error/tests/ui/result_ext.rs | 7 +
> .../tests/ui/result_ext.stderr | 11 +
> .../tests/ui/to_tokens_span.rs | 6 +
> .../tests/ui/to_tokens_span.stderr | 11 +
> .../tests/ui/unknown_setting.rs | 4 +
> .../tests/ui/unknown_setting.stderr | 5 +
> .../tests/ui/unrelated_panic.rs | 6 +
> .../tests/ui/unrelated_panic.stderr | 7 +
> .../vendor/proc-macro2/.cargo-checksum.json | 1 +
> .../char/pl011/vendor/proc-macro2/Cargo.toml | 104 +
> .../pl011/vendor/proc-macro2/LICENSE-APACHE | 176 +
> .../char/pl011/vendor/proc-macro2/LICENSE-MIT | 23 +
> .../char/pl011/vendor/proc-macro2/README.md | 94 +
> .../hw/char/pl011/vendor/proc-macro2/build.rs | 227 +
> .../pl011/vendor/proc-macro2/build/probe.rs | 25 +
> .../char/pl011/vendor/proc-macro2/meson.build | 19 +
> .../vendor/proc-macro2/rust-toolchain.toml | 2 +
> .../pl011/vendor/proc-macro2/src/detection.rs | 75 +
> .../pl011/vendor/proc-macro2/src/extra.rs | 151 +
> .../pl011/vendor/proc-macro2/src/fallback.rs | 1226 ++++
> .../char/pl011/vendor/proc-macro2/src/lib.rs | 1369 +++++
> .../pl011/vendor/proc-macro2/src/location.rs | 29 +
> .../pl011/vendor/proc-macro2/src/marker.rs | 17 +
> .../pl011/vendor/proc-macro2/src/parse.rs | 996 ++++
> .../pl011/vendor/proc-macro2/src/rcvec.rs | 145 +
> .../pl011/vendor/proc-macro2/src/wrapper.rs | 993 ++++
> .../vendor/proc-macro2/tests/comments.rs | 105 +
> .../vendor/proc-macro2/tests/features.rs | 8 +
> .../pl011/vendor/proc-macro2/tests/marker.rs | 100 +
> .../pl011/vendor/proc-macro2/tests/test.rs | 905 +++
> .../vendor/proc-macro2/tests/test_fmt.rs | 28 +
> .../vendor/proc-macro2/tests/test_size.rs | 73 +
> .../pl011/vendor/quote/.cargo-checksum.json | 1 +
> rust/hw/char/pl011/vendor/quote/Cargo.toml | 50 +
> .../hw/char/pl011/vendor/quote/LICENSE-APACHE | 176 +
> rust/hw/char/pl011/vendor/quote/LICENSE-MIT | 23 +
> rust/hw/char/pl011/vendor/quote/README.md | 272 +
> rust/hw/char/pl011/vendor/quote/meson.build | 17 +
> .../pl011/vendor/quote/rust-toolchain.toml | 2 +
> rust/hw/char/pl011/vendor/quote/src/ext.rs | 110 +
> rust/hw/char/pl011/vendor/quote/src/format.rs | 168 +
> .../pl011/vendor/quote/src/ident_fragment.rs | 88 +
> rust/hw/char/pl011/vendor/quote/src/lib.rs | 1464 +++++
> .../hw/char/pl011/vendor/quote/src/runtime.rs | 530 ++
> .../hw/char/pl011/vendor/quote/src/spanned.rs | 50 +
> .../char/pl011/vendor/quote/src/to_tokens.rs | 209 +
> .../pl011/vendor/quote/tests/compiletest.rs | 7 +
> rust/hw/char/pl011/vendor/quote/tests/test.rs | 549 ++
> .../ui/does-not-have-iter-interpolated-dup.rs | 9 +
> ...does-not-have-iter-interpolated-dup.stderr | 11 +
> .../ui/does-not-have-iter-interpolated.rs | 9 +
> .../ui/does-not-have-iter-interpolated.stderr | 11 +
> .../tests/ui/does-not-have-iter-separated.rs | 5 +
> .../ui/does-not-have-iter-separated.stderr | 10 +
> .../quote/tests/ui/does-not-have-iter.rs | 5 +
> .../quote/tests/ui/does-not-have-iter.stderr | 10 +
> .../vendor/quote/tests/ui/not-quotable.rs | 7 +
> .../vendor/quote/tests/ui/not-quotable.stderr | 20 +
> .../vendor/quote/tests/ui/not-repeatable.rs | 8 +
> .../quote/tests/ui/not-repeatable.stderr | 34 +
> .../vendor/quote/tests/ui/wrong-type-span.rs | 7 +
> .../quote/tests/ui/wrong-type-span.stderr | 10 +
> .../pl011/vendor/syn/.cargo-checksum.json | 1 +
> rust/hw/char/pl011/vendor/syn/Cargo.toml | 260 +
> rust/hw/char/pl011/vendor/syn/LICENSE-APACHE | 176 +
> rust/hw/char/pl011/vendor/syn/LICENSE-MIT | 23 +
> rust/hw/char/pl011/vendor/syn/README.md | 284 +
> rust/hw/char/pl011/vendor/syn/benches/file.rs | 57 +
> rust/hw/char/pl011/vendor/syn/benches/rust.rs | 182 +
> rust/hw/char/pl011/vendor/syn/meson.build | 24 +
> rust/hw/char/pl011/vendor/syn/src/attr.rs | 793 +++
> rust/hw/char/pl011/vendor/syn/src/bigint.rs | 66 +
> rust/hw/char/pl011/vendor/syn/src/buffer.rs | 434 ++
> rust/hw/char/pl011/vendor/syn/src/classify.rs | 377 ++
> .../pl011/vendor/syn/src/custom_keyword.rs | 260 +
> .../vendor/syn/src/custom_punctuation.rs | 304 +
> rust/hw/char/pl011/vendor/syn/src/data.rs | 423 ++
> rust/hw/char/pl011/vendor/syn/src/derive.rs | 259 +
> .../char/pl011/vendor/syn/src/discouraged.rs | 225 +
> rust/hw/char/pl011/vendor/syn/src/drops.rs | 58 +
> rust/hw/char/pl011/vendor/syn/src/error.rs | 467 ++
> rust/hw/char/pl011/vendor/syn/src/export.rs | 73 +
> rust/hw/char/pl011/vendor/syn/src/expr.rs | 3960 +++++++++++++
> rust/hw/char/pl011/vendor/syn/src/ext.rs | 136 +
> rust/hw/char/pl011/vendor/syn/src/file.rs | 130 +
> rust/hw/char/pl011/vendor/syn/src/fixup.rs | 218 +
> .../hw/char/pl011/vendor/syn/src/gen/clone.rs | 2209 +++++++
> .../hw/char/pl011/vendor/syn/src/gen/debug.rs | 3160 ++++++++++
> rust/hw/char/pl011/vendor/syn/src/gen/eq.rs | 2242 +++++++
> rust/hw/char/pl011/vendor/syn/src/gen/fold.rs | 3779 ++++++++++++
> rust/hw/char/pl011/vendor/syn/src/gen/hash.rs | 2807 +++++++++
> .../hw/char/pl011/vendor/syn/src/gen/visit.rs | 3858 ++++++++++++
> .../pl011/vendor/syn/src/gen/visit_mut.rs | 3855 ++++++++++++
> rust/hw/char/pl011/vendor/syn/src/generics.rs | 1286 ++++
> rust/hw/char/pl011/vendor/syn/src/group.rs | 291 +
> rust/hw/char/pl011/vendor/syn/src/ident.rs | 108 +
> rust/hw/char/pl011/vendor/syn/src/item.rs | 3441 +++++++++++
> rust/hw/char/pl011/vendor/syn/src/lib.rs | 1019 ++++
> rust/hw/char/pl011/vendor/syn/src/lifetime.rs | 156 +
> rust/hw/char/pl011/vendor/syn/src/lit.rs | 1830 ++++++
> .../hw/char/pl011/vendor/syn/src/lookahead.rs | 169 +
> rust/hw/char/pl011/vendor/syn/src/mac.rs | 223 +
> rust/hw/char/pl011/vendor/syn/src/macros.rs | 166 +
> rust/hw/char/pl011/vendor/syn/src/meta.rs | 427 ++
> rust/hw/char/pl011/vendor/syn/src/op.rs | 219 +
> rust/hw/char/pl011/vendor/syn/src/parse.rs | 1397 +++++
> .../pl011/vendor/syn/src/parse_macro_input.rs | 128 +
> .../char/pl011/vendor/syn/src/parse_quote.rs | 210 +
> rust/hw/char/pl011/vendor/syn/src/pat.rs | 953 +++
> rust/hw/char/pl011/vendor/syn/src/path.rs | 886 +++
> .../char/pl011/vendor/syn/src/precedence.rs | 163 +
> rust/hw/char/pl011/vendor/syn/src/print.rs | 16 +
> .../char/pl011/vendor/syn/src/punctuated.rs | 1132 ++++
> .../char/pl011/vendor/syn/src/restriction.rs | 176 +
> rust/hw/char/pl011/vendor/syn/src/sealed.rs | 4 +
> rust/hw/char/pl011/vendor/syn/src/span.rs | 63 +
> rust/hw/char/pl011/vendor/syn/src/spanned.rs | 118 +
> rust/hw/char/pl011/vendor/syn/src/stmt.rs | 481 ++
> rust/hw/char/pl011/vendor/syn/src/thread.rs | 60 +
> rust/hw/char/pl011/vendor/syn/src/token.rs | 1138 ++++
> rust/hw/char/pl011/vendor/syn/src/tt.rs | 107 +
> rust/hw/char/pl011/vendor/syn/src/ty.rs | 1216 ++++
> rust/hw/char/pl011/vendor/syn/src/verbatim.rs | 33 +
> .../char/pl011/vendor/syn/src/whitespace.rs | 65 +
> .../char/pl011/vendor/syn/tests/common/eq.rs | 900 +++
> .../char/pl011/vendor/syn/tests/common/mod.rs | 28 +
> .../pl011/vendor/syn/tests/common/parse.rs | 49 +
> .../char/pl011/vendor/syn/tests/debug/gen.rs | 5163 +++++++++++++++++
> .../char/pl011/vendor/syn/tests/debug/mod.rs | 147 +
> .../char/pl011/vendor/syn/tests/macros/mod.rs | 93 +
> .../char/pl011/vendor/syn/tests/regression.rs | 5 +
> .../vendor/syn/tests/regression/issue1108.rs | 5 +
> .../vendor/syn/tests/regression/issue1235.rs | 32 +
> .../char/pl011/vendor/syn/tests/repo/mod.rs | 461 ++
> .../pl011/vendor/syn/tests/repo/progress.rs | 37 +
> .../pl011/vendor/syn/tests/test_asyncness.rs | 43 +
> .../pl011/vendor/syn/tests/test_attribute.rs | 225 +
> .../vendor/syn/tests/test_derive_input.rs | 781 +++
> .../char/pl011/vendor/syn/tests/test_expr.rs | 692 +++
> .../pl011/vendor/syn/tests/test_generics.rs | 282 +
> .../pl011/vendor/syn/tests/test_grouping.rs | 53 +
> .../char/pl011/vendor/syn/tests/test_ident.rs | 87 +
> .../char/pl011/vendor/syn/tests/test_item.rs | 332 ++
> .../pl011/vendor/syn/tests/test_iterators.rs | 70 +
> .../char/pl011/vendor/syn/tests/test_lit.rs | 331 ++
> .../char/pl011/vendor/syn/tests/test_meta.rs | 154 +
> .../vendor/syn/tests/test_parse_buffer.rs | 103 +
> .../vendor/syn/tests/test_parse_quote.rs | 166 +
> .../vendor/syn/tests/test_parse_stream.rs | 187 +
> .../char/pl011/vendor/syn/tests/test_pat.rs | 152 +
> .../char/pl011/vendor/syn/tests/test_path.rs | 130 +
> .../pl011/vendor/syn/tests/test_precedence.rs | 537 ++
> .../pl011/vendor/syn/tests/test_receiver.rs | 321 +
> .../pl011/vendor/syn/tests/test_round_trip.rs | 253 +
> .../pl011/vendor/syn/tests/test_shebang.rs | 67 +
> .../char/pl011/vendor/syn/tests/test_size.rs | 36 +
> .../char/pl011/vendor/syn/tests/test_stmt.rs | 322 +
> .../vendor/syn/tests/test_token_trees.rs | 32 +
> .../hw/char/pl011/vendor/syn/tests/test_ty.rs | 397 ++
> .../pl011/vendor/syn/tests/test_visibility.rs | 185 +
> .../char/pl011/vendor/syn/tests/zzz_stable.rs | 33 +
> .../vendor/unicode-ident/.cargo-checksum.json | 1 +
> .../pl011/vendor/unicode-ident/Cargo.toml | 63 +
> .../pl011/vendor/unicode-ident/LICENSE-APACHE | 176 +
> .../pl011/vendor/unicode-ident/LICENSE-MIT | 23 +
> .../vendor/unicode-ident/LICENSE-UNICODE | 46 +
> .../char/pl011/vendor/unicode-ident/README.md | 283 +
> .../pl011/vendor/unicode-ident/benches/xid.rs | 124 +
> .../pl011/vendor/unicode-ident/meson.build | 14 +
> .../pl011/vendor/unicode-ident/src/lib.rs | 269 +
> .../pl011/vendor/unicode-ident/src/tables.rs | 651 +++
> .../vendor/unicode-ident/tests/compare.rs | 67 +
> .../vendor/unicode-ident/tests/fst/mod.rs | 11 +
> .../unicode-ident/tests/fst/xid_continue.fst | Bin 0 -> 73249 bytes
> .../unicode-ident/tests/fst/xid_start.fst | Bin 0 -> 65487 bytes
> .../vendor/unicode-ident/tests/roaring/mod.rs | 21 +
> .../vendor/unicode-ident/tests/static_size.rs | 95 +
> .../vendor/unicode-ident/tests/tables/mod.rs | 7 +
> .../unicode-ident/tests/tables/tables.rs | 347 ++
> .../vendor/unicode-ident/tests/trie/mod.rs | 7 +
> .../vendor/unicode-ident/tests/trie/trie.rs | 445 ++
> .../vendor/version_check/.cargo-checksum.json | 1 +
> .../pl011/vendor/version_check/Cargo.toml | 24 +
> .../pl011/vendor/version_check/LICENSE-APACHE | 201 +
> .../pl011/vendor/version_check/LICENSE-MIT | 19 +
> .../char/pl011/vendor/version_check/README.md | 80 +
> .../pl011/vendor/version_check/meson.build | 14 +
> .../pl011/vendor/version_check/src/channel.rs | 193 +
> .../pl011/vendor/version_check/src/date.rs | 203 +
> .../pl011/vendor/version_check/src/lib.rs | 493 ++
> .../pl011/vendor/version_check/src/version.rs | 316 +
> 365 files changed, 108770 insertions(+)
> create mode 100644 rust/hw/char/pl011/vendor/either/README.rst
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/CHANGELOG.md
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/LICENSE.txt
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/README.md
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/tests/tests.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/README.md
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize/split.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal/struct_gen.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/debug_bits.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/default_bits.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/fmt_bits.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/from_bits.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared/discriminant_assigner.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared/fallback.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared/util.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/try_from_bits.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/bilge/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/bilge/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/bilge/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/bilge/README.md
> create mode 100644 rust/hw/char/pl011/vendor/bilge/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/bilge/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/either/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/either/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/either/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/either/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/either/README-crates.io.md
> create mode 100644 rust/hw/char/pl011/vendor/either/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/either/src/into_either.rs
> create mode 100644 rust/hw/char/pl011/vendor/either/src/iterator.rs
> create mode 100644 rust/hw/char/pl011/vendor/either/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/either/src/serde_untagged.rs
> create mode 100644 rust/hw/char/pl011/vendor/either/src/serde_untagged_optional.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/itertools/CHANGELOG.md
> create mode 100644 rust/hw/char/pl011/vendor/itertools/Cargo.lock
> create mode 100644 rust/hw/char/pl011/vendor/itertools/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/itertools/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/itertools/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/itertools/README.md
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/bench1.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/combinations.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/combinations_with_replacement.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/extra/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/extra/zipslices.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/fold_specialization.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/powerset.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/tree_fold1.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/tuple_combinations.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/tuples.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/examples/iris.data
> create mode 100644 rust/hw/char/pl011/vendor/itertools/examples/iris.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/coalesce.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/map.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/multi_product.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/combinations.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/combinations_with_replacement.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/concat_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/cons_tuples_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/diff.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/duplicates_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/either_or_both.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/exactly_one_err.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/extrema_set.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/flatten_ok.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/format.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/free.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/group_map.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/groupbylazy.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/grouping_map.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/impl_macros.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/intersperse.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/k_smallest.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/kmerge_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/lazy_buffer.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/merge_join.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/minmax.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/multipeek_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/pad_tail.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/peek_nth.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/peeking_take_while.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/permutations.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/powerset.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/process_results_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/put_back_n_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/rciter_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/repeatn.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/size_hint.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/sources.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/take_while_inclusive.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/tee.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/tuple_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/unique_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/unziptuple.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/with_position.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/zip_eq_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/zip_longest.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/ziptuple.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/adaptors_no_collect.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/flatten_ok.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/macros_hygiene.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/merge_join.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/peeking_take_while.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/quick.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/specializations.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/test_core.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/test_std.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/tuples.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/zip.rs
> create mode 100644 rust/hw/char/pl011/vendor/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/build.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/src/parse.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/src/settings.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/CHANGELOG.md
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/README.md
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/build.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/diagnostic.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/dummy.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/imp/delegate.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/imp/fallback.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/macros.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/sealed.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/macro-errors.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ok.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/runtime-errors.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/README.md
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/build.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/build/probe.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/rust-toolchain.toml
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/detection.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/extra.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/fallback.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/location.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/marker.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/parse.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/rcvec.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/wrapper.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/comments.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/features.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/marker.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/test.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/test_fmt.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/test_size.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/quote/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/quote/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/quote/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/quote/README.md
> create mode 100644 rust/hw/char/pl011/vendor/quote/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/quote/rust-toolchain.toml
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/ext.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/format.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/ident_fragment.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/runtime.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/spanned.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/to_tokens.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/compiletest.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/test.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.stderr
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.stderr
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.stderr
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.stderr
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.stderr
> create mode 100644 rust/hw/char/pl011/vendor/syn/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/syn/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/syn/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/syn/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/syn/README.md
> create mode 100644 rust/hw/char/pl011/vendor/syn/benches/file.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/benches/rust.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/attr.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/bigint.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/buffer.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/classify.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/custom_keyword.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/custom_punctuation.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/data.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/derive.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/discouraged.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/drops.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/error.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/export.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/expr.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/ext.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/file.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/fixup.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/clone.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/debug.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/eq.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/fold.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/hash.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/visit.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/visit_mut.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/generics.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/group.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/ident.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/item.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/lifetime.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/lit.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/lookahead.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/mac.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/macros.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/meta.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/op.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/parse.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/parse_macro_input.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/parse_quote.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/pat.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/path.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/precedence.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/print.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/punctuated.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/restriction.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/sealed.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/span.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/spanned.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/stmt.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/thread.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/token.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/tt.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/ty.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/verbatim.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/whitespace.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/common/eq.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/common/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/common/parse.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/debug/gen.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/debug/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/macros/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/regression.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/regression/issue1108.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/regression/issue1235.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/repo/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/repo/progress.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_asyncness.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_attribute.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_derive_input.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_expr.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_generics.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_grouping.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_ident.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_item.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_iterators.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_lit.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_meta.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_parse_buffer.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_parse_quote.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_parse_stream.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_pat.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_path.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_precedence.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_receiver.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_round_trip.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_shebang.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_size.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_stmt.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_token_trees.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_ty.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_visibility.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/zzz_stable.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/LICENSE-UNICODE
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/README.md
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/benches/xid.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/src/tables.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/compare.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/fst/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/fst/xid_continue.fst
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/fst/xid_start.fst
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/roaring/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/static_size.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/tables/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/tables/tables.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/trie/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/trie/trie.rs
> create mode 100644 rust/hw/char/pl011/vendor/version_check/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/version_check/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/version_check/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/version_check/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/version_check/README.md
> create mode 100644 rust/hw/char/pl011/vendor/version_check/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/version_check/src/channel.rs
> create mode 100644 rust/hw/char/pl011/vendor/version_check/src/date.rs
> create mode 100644 rust/hw/char/pl011/vendor/version_check/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/version_check/src/version.rs
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 5/8] .gitattributes: add Rust diff and merge attributes
2024-07-22 11:43 ` [RFC PATCH v5 5/8] .gitattributes: add Rust diff and merge attributes Manos Pitsidianakis
@ 2024-07-23 8:38 ` Zhao Liu
0 siblings, 0 replies; 35+ messages in thread
From: Zhao Liu @ 2024-07-23 8:38 UTC (permalink / raw)
To: Manos Pitsidianakis
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Bennée, Daniel P. Berrangé, Marc-André Lureau,
Thomas Huth, Markus Armbruster, Philippe Mathieu-Daudé,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson
On Mon, Jul 22, 2024 at 02:43:35PM +0300, Manos Pitsidianakis wrote:
> Date: Mon, 22 Jul 2024 14:43:35 +0300
> From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> Subject: [RFC PATCH v5 5/8] .gitattributes: add Rust diff and merge
> attributes
> X-Mailer: git-send-email 2.44.0
>
> Set rust source code to diff=rust (built-in with new git versions)
> and merge=binary for Cargo.lock files (they should not be merged but
> auto-generated by cargo)
>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
> .gitattributes | 3 +++
> 1 file changed, 3 insertions(+)
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 3/8] CI: Add build-system-rust-debian job
2024-07-22 11:43 ` [RFC PATCH v5 3/8] CI: Add build-system-rust-debian job Manos Pitsidianakis
2024-07-23 8:32 ` Richard Henderson
@ 2024-07-23 8:39 ` Daniel P. Berrangé
2024-07-23 10:06 ` Manos Pitsidianakis
1 sibling, 1 reply; 35+ messages in thread
From: Daniel P. Berrangé @ 2024-07-23 8:39 UTC (permalink / raw)
To: Manos Pitsidianakis
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Bennée, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé, Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson,
Wainer dos Santos Moschetta, Beraldo Leal
On Mon, Jul 22, 2024 at 02:43:33PM +0300, Manos Pitsidianakis wrote:
> Add job that builds with rust support enabled on debian.
>
> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
> .gitlab-ci.d/buildtest.yml | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
> index e3a0758bd9..e025e2cbf6 100644
> --- a/.gitlab-ci.d/buildtest.yml
> +++ b/.gitlab-ci.d/buildtest.yml
> @@ -107,6 +107,17 @@ crash-test-debian:
> - make NINJA=":" check-venv
> - pyvenv/bin/python3 scripts/device-crash-test -q --tcg-only ./qemu-system-i386
>
> +build-system-rust-debian:
> + extends:
> + - .native_build_job_template
> + - .native_build_artifact_template
> + needs:
> + job: amd64-debian-container
> + variables:
> + IMAGE: debian
> + CONFIGURE_ARGS: --enable-rust
> + TARGETS: aarch64-softmmu
> +
Do we actually want to do this ? With the updated lcitool containers,
any of the existing build-system-XXXX jobs ought to be able to detect
availability of rust and build with it. Re-using existing jobs means
we burn less CI time.
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 3/8] CI: Add build-system-rust-debian job
2024-07-23 8:39 ` Daniel P. Berrangé
@ 2024-07-23 10:06 ` Manos Pitsidianakis
2024-07-23 10:11 ` Daniel P. Berrangé
0 siblings, 1 reply; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-23 10:06 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé , Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson,
Wainer dos Santos Moschetta, Beraldo Leal
On Tue, 23 Jul 2024 11:39, "Daniel P. Berrangé" <berrange@redhat.com> wrote:
>On Mon, Jul 22, 2024 at 02:43:33PM +0300, Manos Pitsidianakis wrote:
>> Add job that builds with rust support enabled on debian.
>>
>> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
>> ---
>> .gitlab-ci.d/buildtest.yml | 11 +++++++++++
>> 1 file changed, 11 insertions(+)
>>
>> diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
>> index e3a0758bd9..e025e2cbf6 100644
>> --- a/.gitlab-ci.d/buildtest.yml
>> +++ b/.gitlab-ci.d/buildtest.yml
>> @@ -107,6 +107,17 @@ crash-test-debian:
>> - make NINJA=":" check-venv
>> - pyvenv/bin/python3 scripts/device-crash-test -q --tcg-only ./qemu-system-i386
>>
>> +build-system-rust-debian:
>> + extends:
>> + - .native_build_job_template
>> + - .native_build_artifact_template
>> + needs:
>> + job: amd64-debian-container
>> + variables:
>> + IMAGE: debian
>> + CONFIGURE_ARGS: --enable-rust
>> + TARGETS: aarch64-softmmu
>> +
>
>Do we actually want to do this ? With the updated lcitool containers,
>any of the existing build-system-XXXX jobs ought to be able to detect
>availability of rust and build with it. Re-using existing jobs means
>we burn less CI time.
>
>With regards,
>Daniel
Hello Daniel,
I think we do, as long as a rust toolchain is not required to build QEMU
by default. The other jobs could detect availability of Rust but we
don't have a way to check if it works and not fallback to compiling
without Rust.
Could we force enable Rust in one of the existing jobs?
Manos
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 3/8] CI: Add build-system-rust-debian job
2024-07-23 10:06 ` Manos Pitsidianakis
@ 2024-07-23 10:11 ` Daniel P. Berrangé
2024-07-23 10:24 ` Manos Pitsidianakis
0 siblings, 1 reply; 35+ messages in thread
From: Daniel P. Berrangé @ 2024-07-23 10:11 UTC (permalink / raw)
To: Manos Pitsidianakis
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé, Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson,
Wainer dos Santos Moschetta, Beraldo Leal
On Tue, Jul 23, 2024 at 01:06:20PM +0300, Manos Pitsidianakis wrote:
> On Tue, 23 Jul 2024 11:39, "Daniel P. Berrangé" <berrange@redhat.com> wrote:
> > On Mon, Jul 22, 2024 at 02:43:33PM +0300, Manos Pitsidianakis wrote:
> > > Add job that builds with rust support enabled on debian.
> > >
> > > Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> > > ---
> > > .gitlab-ci.d/buildtest.yml | 11 +++++++++++
> > > 1 file changed, 11 insertions(+)
> > >
> > > diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
> > > index e3a0758bd9..e025e2cbf6 100644
> > > --- a/.gitlab-ci.d/buildtest.yml
> > > +++ b/.gitlab-ci.d/buildtest.yml
> > > @@ -107,6 +107,17 @@ crash-test-debian:
> > > - make NINJA=":" check-venv
> > > - pyvenv/bin/python3 scripts/device-crash-test -q --tcg-only ./qemu-system-i386
> > > +build-system-rust-debian:
> > > + extends:
> > > + - .native_build_job_template
> > > + - .native_build_artifact_template
> > > + needs:
> > > + job: amd64-debian-container
> > > + variables:
> > > + IMAGE: debian
> > > + CONFIGURE_ARGS: --enable-rust
> > > + TARGETS: aarch64-softmmu
> > > +
> >
> > Do we actually want to do this ? With the updated lcitool containers,
> > any of the existing build-system-XXXX jobs ought to be able to detect
> > availability of rust and build with it. Re-using existing jobs means
> > we burn less CI time.
> >
> > With regards,
> > Daniel
>
> Hello Daniel,
>
> I think we do, as long as a rust toolchain is not required to build QEMU by
> default. The other jobs could detect availability of Rust but we don't have
> a way to check if it works and not fallback to compiling without Rust.
>
> Could we force enable Rust in one of the existing jobs?
Yes, pick any existing job where it works.
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 2/8] build deps: update lcitool to include rust bits
2024-07-23 8:31 ` Richard Henderson
@ 2024-07-23 10:11 ` Manos Pitsidianakis
0 siblings, 0 replies; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-23 10:11 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
Hello Richard,
On Tue, 23 Jul 2024 11:31, Richard Henderson <richard.henderson@linaro.org> wrote:
>On 7/22/24 21:43, Manos Pitsidianakis wrote:
>> From: Alex Bennée<alex.bennee@linaro.org>
>>
>> For rust development we need cargo, rustc and bindgen in our various
>> development environments. Update the libvirt-ci project to (!495) and
>> regenerate the containers and other dependency lists.
>
>The cover letter for v5 says use of cargo eliminated.
>Therefore no need to add to qemu.yml, correct?
>
>
>r~
Yes that is correct, thank you for pointing it out. If we end up using
only meson and not cargo, like it is done in this version, cargo can be
removed from this diff.
Manos
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 1/8] build-sys: Add rust feature option
2024-07-23 6:37 ` Zhao Liu
@ 2024-07-23 10:13 ` Manos Pitsidianakis
0 siblings, 0 replies; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-23 10:13 UTC (permalink / raw)
To: Zhao Liu
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Daniel P. Berrangé ,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé , Gustavo Romero, Pierrick Bouvier,
rowan.hart, Richard Henderson, Paolo Bonzini
On Tue, 23 Jul 2024 09:37, Zhao Liu <zhao1.liu@intel.com> wrote:
>Hi Manos,
>
>On Mon, Jul 22, 2024 at 02:43:31PM +0300, Manos Pitsidianakis wrote:
>> Date: Mon, 22 Jul 2024 14:43:31 +0300
>> From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
>> Subject: [RFC PATCH v5 1/8] build-sys: Add rust feature option
>> X-Mailer: git-send-email 2.44.0
>>
>> Add rust feature in meson.build, configure, to prepare for adding Rust
>> code in the followup commits.
>>
>> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
>> ---
>> MAINTAINERS | 5 +++++
>> configure | 12 ++++++++++++
>> meson.build | 17 ++++++++++++++++-
>> Kconfig | 1 +
>> Kconfig.host | 3 +++
>> meson_options.txt | 5 +++++
>> rust/Kconfig | 0
>> scripts/meson-buildoptions.sh | 3 +++
>> 8 files changed, 45 insertions(+), 1 deletion(-)
>> create mode 100644 rust/Kconfig
>>
>
>[snip]
>
>> diff --git a/meson.build b/meson.build
>> index a1e51277b0..a3f346ab3c 100644
>> --- a/meson.build
>> +++ b/meson.build
>> @@ -70,6 +70,14 @@ if host_os == 'darwin' and \
>> all_languages += ['objc']
>> objc = meson.get_compiler('objc')
>> endif
>> +if get_option('have_rust') and meson.version().version_compare('<1.0.0')
>> + error('Rust support requires Meson version >=1.0.0')
>> +endif
>> +have_rust = false
>> +if not get_option('disable_rust') and add_languages('rust', required: get_option('have_rust'), native: false)
>> + rustc = meson.get_compiler('rust')
>> + have_rust = true
>> +endif
>
>Only a nit, "disable_rust" seems redundant, and "have_rust" is enough.
>
>Others LGTM,
>
>Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
>
Hello Zhao, thank you for your review! Indeed it does seem redundant, I
added it to allow graceful fallback to not using Rust if the compiler is
not detected by meson.
Manos
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 8/8] rust/pl011: vendor dependencies
2024-07-23 8:37 ` Zhao Liu
@ 2024-07-23 10:19 ` Manos Pitsidianakis
0 siblings, 0 replies; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-23 10:19 UTC (permalink / raw)
To: Zhao Liu
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Daniel P. Berrangé ,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé , Gustavo Romero, Pierrick Bouvier,
rowan.hart, Richard Henderson
On Tue, 23 Jul 2024 11:37, Zhao Liu <zhao1.liu@intel.com> wrote:
>Hi Manos,
>
>(This patch contains too many codes so that mail list rejects to display
>it at https://lore.kernel.org/qemu-devel)
>
>Please correct me if I'm wrong...
>
>Is the reason for not using git submodules here because v5 abandoned
>compilation through Cargo, so it’s necessary to add meson.build to the
>code repository of each dependency, and consequently, all code must be
>loaded into QEMU?
>
>It looks like will be difficult to synchronize the dependency changes
>in the future.
Yes, ideally we want meson wrap files (git submodules were removed in
2019cabfee). Meson support for that is a bit buggy and might require
bleeding edge versions, so for the time being I vendored the
dependencies. Otherwise I'd keep getting delayed posting a new patch
series and I wanted to have feedback coming in the mean time :)
Manos
>
>Best Regards,
>Zhao
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 3/8] CI: Add build-system-rust-debian job
2024-07-23 10:11 ` Daniel P. Berrangé
@ 2024-07-23 10:24 ` Manos Pitsidianakis
0 siblings, 0 replies; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-23 10:24 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé , Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson,
Wainer dos Santos Moschetta, Beraldo Leal
On Tue, 23 Jul 2024 13:11, "Daniel P. Berrangé" <berrange@redhat.com> wrote:
>On Tue, Jul 23, 2024 at 01:06:20PM +0300, Manos Pitsidianakis wrote:
>> On Tue, 23 Jul 2024 11:39, "Daniel P. Berrangé" <berrange@redhat.com> wrote:
>> > On Mon, Jul 22, 2024 at 02:43:33PM +0300, Manos Pitsidianakis wrote:
>> > > Add job that builds with rust support enabled on debian.
>> > >
>> > > Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
>> > > ---
>> > > .gitlab-ci.d/buildtest.yml | 11 +++++++++++
>> > > 1 file changed, 11 insertions(+)
>> > >
>> > > diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
>> > > index e3a0758bd9..e025e2cbf6 100644
>> > > --- a/.gitlab-ci.d/buildtest.yml
>> > > +++ b/.gitlab-ci.d/buildtest.yml
>> > > @@ -107,6 +107,17 @@ crash-test-debian:
>> > > - make NINJA=":" check-venv
>> > > - pyvenv/bin/python3 scripts/device-crash-test -q --tcg-only ./qemu-system-i386
>> > > +build-system-rust-debian:
>> > > + extends:
>> > > + - .native_build_job_template
>> > > + - .native_build_artifact_template
>> > > + needs:
>> > > + job: amd64-debian-container
>> > > + variables:
>> > > + IMAGE: debian
>> > > + CONFIGURE_ARGS: --enable-rust
>> > > + TARGETS: aarch64-softmmu
>> > > +
>> >
>> > Do we actually want to do this ? With the updated lcitool containers,
>> > any of the existing build-system-XXXX jobs ought to be able to detect
>> > availability of rust and build with it. Re-using existing jobs means
>> > we burn less CI time.
>> >
>> > With regards,
>> > Daniel
>>
>> Hello Daniel,
>>
>> I think we do, as long as a rust toolchain is not required to build QEMU by
>> default. The other jobs could detect availability of Rust but we don't have
>> a way to check if it works and not fallback to compiling without Rust.
>>
>> Could we force enable Rust in one of the existing jobs?
>
>Yes, pick any existing job where it works.
>
>With regards,
>Daniel
OK sounds good, will make the change!
Manos
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-22 11:43 [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Manos Pitsidianakis
` (7 preceding siblings ...)
2024-07-22 11:43 ` [RFC PATCH v5 8/8] rust/pl011: vendor dependencies Manos Pitsidianakis
@ 2024-07-23 15:07 ` Paolo Bonzini
2024-07-24 9:14 ` Manos Pitsidianakis
8 siblings, 1 reply; 35+ messages in thread
From: Paolo Bonzini @ 2024-07-23 15:07 UTC (permalink / raw)
To: Manos Pitsidianakis, qemu-devel
Cc: Stefan Hajnoczi, Mads Ynddal, Peter Maydell, Alex Bennée,
Daniel P. Berrangé, Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé, Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson
On 7/22/24 13:43, Manos Pitsidianakis wrote:
> Changes from v4->v5:
> - Added CI patch from Alex Benee
> - Removed all cargo use, use meson rust support
> - Added Kconfig logic
The following requests from the v4 review have also been evaluated (good!):
✅ module structure should resemble the C part of the tree
✅ only generate bindings.rs.inc once
✅ a couple lints are too broad and should be enabled per-file. (though
there are still some issues with duplication of lints, I consider this
mostly done)
✅ please check if -Wl,--whole-archive can be replaced with link_whole
(as discussed on IRC, unfortunately it cannot)
The hot point here is how to handle dependencies. I appreciate that you
found a way to avoid repeated building of dependent crates, and to
integrate with Kconfig, but at the same time this is a huge change which
in my opinion is premature.
For example if we can (sooner or later) use the automatic Cargo
subprojects, we do not need any vendoring and we can use cargo in the
meanwhile (we can drop --cargo and CARGO at any point, just like we
dropped --meson and --sphinx-build in QEMU 8.1).
On the other hand, committing to using meson's "raw" (meson.build-level)
rust support and vendoring everything is premature in my opinion is very
different for people who are already comfortable with Cargo, so it makes
it harder to add new dependencies. In fact, because the huge patch 8
did not reach the mailing list, it's really hard to understand what's
going on, what had to be done by hand and what is done automatically by
meson.
In my opinion we should start with cargo workspaces as the
known-imperfect (but good enough) solution, so that it could be evolved
later. It is important that any change that deviates from common Rust
conventions is documented, and v4 provided a nice basis to build upon,
with documentation coming as things settle. This is why I explicitly
didn't include Kconfig in the TODO list in my review of v4.
> .../vendor/arbitrary-int/.cargo-checksum.json | 1 +
In any case, vendoring should not be done inside hw/char/pl011.
Also, of the code changes (as opposed to the build system changes) that
I had asked for in the review of v4, almost none of them have been
applied. I'm copying them here for future reference:
❌ TODO comments when the code is doing potential undefined behavior
❌ a trait to store the CStr corresponding to the structs
❌ a trait to generate all-zero structs without having to type "unsafe {
MaybeUninit::zeroed().assume_init() }"
❌ I'd like to use ctor instead of non-portable linker magic, and the
cstr crate instead of CStr statics or c""
If you have a tree that I can look at, to understand more of patch 8,
please send a pointer. However, honestly I am not comfortable with the
build system integration as done in this patch.
My suggestion is to do one of the following, or both:
- start from this version; try using Cargo subproject support in 1.5.0
and see if it works, so that vendoring can be dropped. We can require
Meson 1.5.0 to work on Rust support. In this case it's okay not to do
any further code changes (the four that were marked ❌ above).
- go back to the build system integration of v4, and do *only* the
changes that were requested during review (in this case, all of them
except link_whole, with you checked it does not work).
If you try using Cargo subproject support, please provide the running
time for configure and make, for both "v4" and "v5+subproject". When I
tried it, the processing of the subprojects was very slow.
Paolo
> .../pl011/vendor/arbitrary-int/CHANGELOG.md | 47 +
> .../pl011/vendor/arbitrary-int/Cargo.toml | 54 +
> .../pl011/vendor/arbitrary-int/LICENSE.txt | 21 +
> .../char/pl011/vendor/arbitrary-int/README.md | 72 +
> .../pl011/vendor/arbitrary-int/meson.build | 14 +
> .../pl011/vendor/arbitrary-int/src/lib.rs | 1489 +++++
> .../pl011/vendor/arbitrary-int/tests/tests.rs | 1913 ++++++
> .../vendor/bilge-impl/.cargo-checksum.json | 1 +
> .../char/pl011/vendor/bilge-impl/Cargo.toml | 54 +
> .../hw/char/pl011/vendor/bilge-impl/README.md | 327 ++
> .../char/pl011/vendor/bilge-impl/meson.build | 24 +
> .../pl011/vendor/bilge-impl/src/bitsize.rs | 187 +
> .../vendor/bilge-impl/src/bitsize/split.rs | 185 +
> .../vendor/bilge-impl/src/bitsize_internal.rs | 235 +
> .../src/bitsize_internal/struct_gen.rs | 402 ++
> .../pl011/vendor/bilge-impl/src/debug_bits.rs | 55 +
> .../vendor/bilge-impl/src/default_bits.rs | 92 +
> .../pl011/vendor/bilge-impl/src/fmt_bits.rs | 112 +
> .../pl011/vendor/bilge-impl/src/from_bits.rs | 222 +
> .../char/pl011/vendor/bilge-impl/src/lib.rs | 79 +
> .../pl011/vendor/bilge-impl/src/shared.rs | 196 +
> .../src/shared/discriminant_assigner.rs | 56 +
> .../vendor/bilge-impl/src/shared/fallback.rs | 92 +
> .../vendor/bilge-impl/src/shared/util.rs | 91 +
> .../vendor/bilge-impl/src/try_from_bits.rs | 143 +
> .../pl011/vendor/bilge/.cargo-checksum.json | 1 +
> rust/hw/char/pl011/vendor/bilge/Cargo.toml | 69 +
> .../hw/char/pl011/vendor/bilge/LICENSE-APACHE | 176 +
> rust/hw/char/pl011/vendor/bilge/LICENSE-MIT | 17 +
> rust/hw/char/pl011/vendor/bilge/README.md | 327 ++
> rust/hw/char/pl011/vendor/bilge/meson.build | 17 +
> rust/hw/char/pl011/vendor/bilge/src/lib.rs | 80 +
> .../pl011/vendor/either/.cargo-checksum.json | 1 +
> rust/hw/char/pl011/vendor/either/Cargo.toml | 54 +
> .../char/pl011/vendor/either/LICENSE-APACHE | 201 +
> rust/hw/char/pl011/vendor/either/LICENSE-MIT | 25 +
> .../pl011/vendor/either/README-crates.io.md | 10 +
> rust/hw/char/pl011/vendor/either/meson.build | 16 +
> .../pl011/vendor/either/src/into_either.rs | 64 +
> .../char/pl011/vendor/either/src/iterator.rs | 315 +
> rust/hw/char/pl011/vendor/either/src/lib.rs | 1519 +++++
> .../pl011/vendor/either/src/serde_untagged.rs | 69 +
> .../either/src/serde_untagged_optional.rs | 74 +
> .../vendor/itertools/.cargo-checksum.json | 1 +
> .../char/pl011/vendor/itertools/CHANGELOG.md | 409 ++
> .../hw/char/pl011/vendor/itertools/Cargo.lock | 681 +++
> .../hw/char/pl011/vendor/itertools/Cargo.toml | 101 +
> .../pl011/vendor/itertools/LICENSE-APACHE | 201 +
> .../char/pl011/vendor/itertools/LICENSE-MIT | 25 +
> rust/hw/char/pl011/vendor/itertools/README.md | 44 +
> .../pl011/vendor/itertools/benches/bench1.rs | 877 +++
> .../vendor/itertools/benches/combinations.rs | 125 +
> .../benches/combinations_with_replacement.rs | 40 +
> .../vendor/itertools/benches/extra/mod.rs | 2 +
> .../itertools/benches/extra/zipslices.rs | 188 +
> .../itertools/benches/fold_specialization.rs | 73 +
> .../vendor/itertools/benches/powerset.rs | 44 +
> .../vendor/itertools/benches/tree_fold1.rs | 144 +
> .../itertools/benches/tuple_combinations.rs | 113 +
> .../pl011/vendor/itertools/benches/tuples.rs | 213 +
> .../pl011/vendor/itertools/examples/iris.data | 150 +
> .../pl011/vendor/itertools/examples/iris.rs | 137 +
> .../char/pl011/vendor/itertools/meson.build | 18 +
> .../vendor/itertools/src/adaptors/coalesce.rs | 235 +
> .../vendor/itertools/src/adaptors/map.rs | 124 +
> .../vendor/itertools/src/adaptors/mod.rs | 1151 ++++
> .../itertools/src/adaptors/multi_product.rs | 230 +
> .../vendor/itertools/src/combinations.rs | 128 +
> .../src/combinations_with_replacement.rs | 109 +
> .../pl011/vendor/itertools/src/concat_impl.rs | 23 +
> .../vendor/itertools/src/cons_tuples_impl.rs | 64 +
> .../char/pl011/vendor/itertools/src/diff.rs | 61 +
> .../vendor/itertools/src/duplicates_impl.rs | 216 +
> .../vendor/itertools/src/either_or_both.rs | 495 ++
> .../vendor/itertools/src/exactly_one_err.rs | 110 +
> .../pl011/vendor/itertools/src/extrema_set.rs | 48 +
> .../pl011/vendor/itertools/src/flatten_ok.rs | 165 +
> .../char/pl011/vendor/itertools/src/format.rs | 168 +
> .../char/pl011/vendor/itertools/src/free.rs | 286 +
> .../pl011/vendor/itertools/src/group_map.rs | 32 +
> .../pl011/vendor/itertools/src/groupbylazy.rs | 579 ++
> .../vendor/itertools/src/grouping_map.rs | 535 ++
> .../pl011/vendor/itertools/src/impl_macros.rs | 29 +
> .../pl011/vendor/itertools/src/intersperse.rs | 118 +
> .../pl011/vendor/itertools/src/k_smallest.rs | 20 +
> .../pl011/vendor/itertools/src/kmerge_impl.rs | 227 +
> .../pl011/vendor/itertools/src/lazy_buffer.rs | 63 +
> .../hw/char/pl011/vendor/itertools/src/lib.rs | 3967 +++++++++++++
> .../pl011/vendor/itertools/src/merge_join.rs | 220 +
> .../char/pl011/vendor/itertools/src/minmax.rs | 115 +
> .../vendor/itertools/src/multipeek_impl.rs | 101 +
> .../pl011/vendor/itertools/src/pad_tail.rs | 96 +
> .../pl011/vendor/itertools/src/peek_nth.rs | 102 +
> .../itertools/src/peeking_take_while.rs | 177 +
> .../vendor/itertools/src/permutations.rs | 277 +
> .../pl011/vendor/itertools/src/powerset.rs | 90 +
> .../itertools/src/process_results_impl.rs | 68 +
> .../vendor/itertools/src/put_back_n_impl.rs | 61 +
> .../pl011/vendor/itertools/src/rciter_impl.rs | 99 +
> .../pl011/vendor/itertools/src/repeatn.rs | 59 +
> .../pl011/vendor/itertools/src/size_hint.rs | 119 +
> .../pl011/vendor/itertools/src/sources.rs | 183 +
> .../itertools/src/take_while_inclusive.rs | 68 +
> .../hw/char/pl011/vendor/itertools/src/tee.rs | 78 +
> .../pl011/vendor/itertools/src/tuple_impl.rs | 331 ++
> .../pl011/vendor/itertools/src/unique_impl.rs | 179 +
> .../pl011/vendor/itertools/src/unziptuple.rs | 80 +
> .../vendor/itertools/src/with_position.rs | 88 +
> .../pl011/vendor/itertools/src/zip_eq_impl.rs | 60 +
> .../pl011/vendor/itertools/src/zip_longest.rs | 83 +
> .../pl011/vendor/itertools/src/ziptuple.rs | 138 +
> .../itertools/tests/adaptors_no_collect.rs | 46 +
> .../vendor/itertools/tests/flatten_ok.rs | 76 +
> .../vendor/itertools/tests/macros_hygiene.rs | 13 +
> .../vendor/itertools/tests/merge_join.rs | 108 +
> .../itertools/tests/peeking_take_while.rs | 69 +
> .../pl011/vendor/itertools/tests/quick.rs | 1849 ++++++
> .../vendor/itertools/tests/specializations.rs | 153 +
> .../pl011/vendor/itertools/tests/test_core.rs | 317 +
> .../pl011/vendor/itertools/tests/test_std.rs | 1184 ++++
> .../pl011/vendor/itertools/tests/tuples.rs | 86 +
> .../char/pl011/vendor/itertools/tests/zip.rs | 77 +
> rust/hw/char/pl011/vendor/meson.build | 18 +
> .../.cargo-checksum.json | 1 +
> .../vendor/proc-macro-error-attr/Cargo.toml | 33 +
> .../proc-macro-error-attr/LICENSE-APACHE | 201 +
> .../vendor/proc-macro-error-attr/LICENSE-MIT | 21 +
> .../vendor/proc-macro-error-attr/build.rs | 5 +
> .../vendor/proc-macro-error-attr/meson.build | 20 +
> .../vendor/proc-macro-error-attr/src/lib.rs | 121 +
> .../vendor/proc-macro-error-attr/src/parse.rs | 89 +
> .../proc-macro-error-attr/src/settings.rs | 72 +
> .../proc-macro-error/.cargo-checksum.json | 1 +
> .../vendor/proc-macro-error/CHANGELOG.md | 162 +
> .../pl011/vendor/proc-macro-error/Cargo.toml | 56 +
> .../vendor/proc-macro-error/LICENSE-APACHE | 201 +
> .../pl011/vendor/proc-macro-error/LICENSE-MIT | 21 +
> .../pl011/vendor/proc-macro-error/README.md | 258 +
> .../pl011/vendor/proc-macro-error/build.rs | 11 +
> .../pl011/vendor/proc-macro-error/meson.build | 22 +
> .../vendor/proc-macro-error/src/diagnostic.rs | 349 ++
> .../vendor/proc-macro-error/src/dummy.rs | 150 +
> .../proc-macro-error/src/imp/delegate.rs | 69 +
> .../proc-macro-error/src/imp/fallback.rs | 30 +
> .../pl011/vendor/proc-macro-error/src/lib.rs | 560 ++
> .../vendor/proc-macro-error/src/macros.rs | 288 +
> .../vendor/proc-macro-error/src/sealed.rs | 3 +
> .../proc-macro-error/tests/macro-errors.rs | 8 +
> .../pl011/vendor/proc-macro-error/tests/ok.rs | 10 +
> .../proc-macro-error/tests/runtime-errors.rs | 13 +
> .../vendor/proc-macro-error/tests/ui/abort.rs | 11 +
> .../proc-macro-error/tests/ui/abort.stderr | 48 +
> .../proc-macro-error/tests/ui/append_dummy.rs | 13 +
> .../tests/ui/append_dummy.stderr | 5 +
> .../tests/ui/children_messages.rs | 6 +
> .../tests/ui/children_messages.stderr | 23 +
> .../vendor/proc-macro-error/tests/ui/dummy.rs | 13 +
> .../proc-macro-error/tests/ui/dummy.stderr | 5 +
> .../vendor/proc-macro-error/tests/ui/emit.rs | 7 +
> .../proc-macro-error/tests/ui/emit.stderr | 48 +
> .../tests/ui/explicit_span_range.rs | 6 +
> .../tests/ui/explicit_span_range.stderr | 5 +
> .../proc-macro-error/tests/ui/misuse.rs | 11 +
> .../proc-macro-error/tests/ui/misuse.stderr | 13 +
> .../tests/ui/multiple_tokens.rs | 6 +
> .../tests/ui/multiple_tokens.stderr | 5 +
> .../tests/ui/not_proc_macro.rs | 4 +
> .../tests/ui/not_proc_macro.stderr | 10 +
> .../proc-macro-error/tests/ui/option_ext.rs | 6 +
> .../tests/ui/option_ext.stderr | 7 +
> .../tests/ui/proc_macro_hack.rs | 10 +
> .../tests/ui/proc_macro_hack.stderr | 26 +
> .../proc-macro-error/tests/ui/result_ext.rs | 7 +
> .../tests/ui/result_ext.stderr | 11 +
> .../tests/ui/to_tokens_span.rs | 6 +
> .../tests/ui/to_tokens_span.stderr | 11 +
> .../tests/ui/unknown_setting.rs | 4 +
> .../tests/ui/unknown_setting.stderr | 5 +
> .../tests/ui/unrelated_panic.rs | 6 +
> .../tests/ui/unrelated_panic.stderr | 7 +
> .../vendor/proc-macro2/.cargo-checksum.json | 1 +
> .../char/pl011/vendor/proc-macro2/Cargo.toml | 104 +
> .../pl011/vendor/proc-macro2/LICENSE-APACHE | 176 +
> .../char/pl011/vendor/proc-macro2/LICENSE-MIT | 23 +
> .../char/pl011/vendor/proc-macro2/README.md | 94 +
> .../hw/char/pl011/vendor/proc-macro2/build.rs | 227 +
> .../pl011/vendor/proc-macro2/build/probe.rs | 25 +
> .../char/pl011/vendor/proc-macro2/meson.build | 19 +
> .../vendor/proc-macro2/rust-toolchain.toml | 2 +
> .../pl011/vendor/proc-macro2/src/detection.rs | 75 +
> .../pl011/vendor/proc-macro2/src/extra.rs | 151 +
> .../pl011/vendor/proc-macro2/src/fallback.rs | 1226 ++++
> .../char/pl011/vendor/proc-macro2/src/lib.rs | 1369 +++++
> .../pl011/vendor/proc-macro2/src/location.rs | 29 +
> .../pl011/vendor/proc-macro2/src/marker.rs | 17 +
> .../pl011/vendor/proc-macro2/src/parse.rs | 996 ++++
> .../pl011/vendor/proc-macro2/src/rcvec.rs | 145 +
> .../pl011/vendor/proc-macro2/src/wrapper.rs | 993 ++++
> .../vendor/proc-macro2/tests/comments.rs | 105 +
> .../vendor/proc-macro2/tests/features.rs | 8 +
> .../pl011/vendor/proc-macro2/tests/marker.rs | 100 +
> .../pl011/vendor/proc-macro2/tests/test.rs | 905 +++
> .../vendor/proc-macro2/tests/test_fmt.rs | 28 +
> .../vendor/proc-macro2/tests/test_size.rs | 73 +
> .../pl011/vendor/quote/.cargo-checksum.json | 1 +
> rust/hw/char/pl011/vendor/quote/Cargo.toml | 50 +
> .../hw/char/pl011/vendor/quote/LICENSE-APACHE | 176 +
> rust/hw/char/pl011/vendor/quote/LICENSE-MIT | 23 +
> rust/hw/char/pl011/vendor/quote/README.md | 272 +
> rust/hw/char/pl011/vendor/quote/meson.build | 17 +
> .../pl011/vendor/quote/rust-toolchain.toml | 2 +
> rust/hw/char/pl011/vendor/quote/src/ext.rs | 110 +
> rust/hw/char/pl011/vendor/quote/src/format.rs | 168 +
> .../pl011/vendor/quote/src/ident_fragment.rs | 88 +
> rust/hw/char/pl011/vendor/quote/src/lib.rs | 1464 +++++
> .../hw/char/pl011/vendor/quote/src/runtime.rs | 530 ++
> .../hw/char/pl011/vendor/quote/src/spanned.rs | 50 +
> .../char/pl011/vendor/quote/src/to_tokens.rs | 209 +
> .../pl011/vendor/quote/tests/compiletest.rs | 7 +
> rust/hw/char/pl011/vendor/quote/tests/test.rs | 549 ++
> .../ui/does-not-have-iter-interpolated-dup.rs | 9 +
> ...does-not-have-iter-interpolated-dup.stderr | 11 +
> .../ui/does-not-have-iter-interpolated.rs | 9 +
> .../ui/does-not-have-iter-interpolated.stderr | 11 +
> .../tests/ui/does-not-have-iter-separated.rs | 5 +
> .../ui/does-not-have-iter-separated.stderr | 10 +
> .../quote/tests/ui/does-not-have-iter.rs | 5 +
> .../quote/tests/ui/does-not-have-iter.stderr | 10 +
> .../vendor/quote/tests/ui/not-quotable.rs | 7 +
> .../vendor/quote/tests/ui/not-quotable.stderr | 20 +
> .../vendor/quote/tests/ui/not-repeatable.rs | 8 +
> .../quote/tests/ui/not-repeatable.stderr | 34 +
> .../vendor/quote/tests/ui/wrong-type-span.rs | 7 +
> .../quote/tests/ui/wrong-type-span.stderr | 10 +
> .../pl011/vendor/syn/.cargo-checksum.json | 1 +
> rust/hw/char/pl011/vendor/syn/Cargo.toml | 260 +
> rust/hw/char/pl011/vendor/syn/LICENSE-APACHE | 176 +
> rust/hw/char/pl011/vendor/syn/LICENSE-MIT | 23 +
> rust/hw/char/pl011/vendor/syn/README.md | 284 +
> rust/hw/char/pl011/vendor/syn/benches/file.rs | 57 +
> rust/hw/char/pl011/vendor/syn/benches/rust.rs | 182 +
> rust/hw/char/pl011/vendor/syn/meson.build | 24 +
> rust/hw/char/pl011/vendor/syn/src/attr.rs | 793 +++
> rust/hw/char/pl011/vendor/syn/src/bigint.rs | 66 +
> rust/hw/char/pl011/vendor/syn/src/buffer.rs | 434 ++
> rust/hw/char/pl011/vendor/syn/src/classify.rs | 377 ++
> .../pl011/vendor/syn/src/custom_keyword.rs | 260 +
> .../vendor/syn/src/custom_punctuation.rs | 304 +
> rust/hw/char/pl011/vendor/syn/src/data.rs | 423 ++
> rust/hw/char/pl011/vendor/syn/src/derive.rs | 259 +
> .../char/pl011/vendor/syn/src/discouraged.rs | 225 +
> rust/hw/char/pl011/vendor/syn/src/drops.rs | 58 +
> rust/hw/char/pl011/vendor/syn/src/error.rs | 467 ++
> rust/hw/char/pl011/vendor/syn/src/export.rs | 73 +
> rust/hw/char/pl011/vendor/syn/src/expr.rs | 3960 +++++++++++++
> rust/hw/char/pl011/vendor/syn/src/ext.rs | 136 +
> rust/hw/char/pl011/vendor/syn/src/file.rs | 130 +
> rust/hw/char/pl011/vendor/syn/src/fixup.rs | 218 +
> .../hw/char/pl011/vendor/syn/src/gen/clone.rs | 2209 +++++++
> .../hw/char/pl011/vendor/syn/src/gen/debug.rs | 3160 ++++++++++
> rust/hw/char/pl011/vendor/syn/src/gen/eq.rs | 2242 +++++++
> rust/hw/char/pl011/vendor/syn/src/gen/fold.rs | 3779 ++++++++++++
> rust/hw/char/pl011/vendor/syn/src/gen/hash.rs | 2807 +++++++++
> .../hw/char/pl011/vendor/syn/src/gen/visit.rs | 3858 ++++++++++++
> .../pl011/vendor/syn/src/gen/visit_mut.rs | 3855 ++++++++++++
> rust/hw/char/pl011/vendor/syn/src/generics.rs | 1286 ++++
> rust/hw/char/pl011/vendor/syn/src/group.rs | 291 +
> rust/hw/char/pl011/vendor/syn/src/ident.rs | 108 +
> rust/hw/char/pl011/vendor/syn/src/item.rs | 3441 +++++++++++
> rust/hw/char/pl011/vendor/syn/src/lib.rs | 1019 ++++
> rust/hw/char/pl011/vendor/syn/src/lifetime.rs | 156 +
> rust/hw/char/pl011/vendor/syn/src/lit.rs | 1830 ++++++
> .../hw/char/pl011/vendor/syn/src/lookahead.rs | 169 +
> rust/hw/char/pl011/vendor/syn/src/mac.rs | 223 +
> rust/hw/char/pl011/vendor/syn/src/macros.rs | 166 +
> rust/hw/char/pl011/vendor/syn/src/meta.rs | 427 ++
> rust/hw/char/pl011/vendor/syn/src/op.rs | 219 +
> rust/hw/char/pl011/vendor/syn/src/parse.rs | 1397 +++++
> .../pl011/vendor/syn/src/parse_macro_input.rs | 128 +
> .../char/pl011/vendor/syn/src/parse_quote.rs | 210 +
> rust/hw/char/pl011/vendor/syn/src/pat.rs | 953 +++
> rust/hw/char/pl011/vendor/syn/src/path.rs | 886 +++
> .../char/pl011/vendor/syn/src/precedence.rs | 163 +
> rust/hw/char/pl011/vendor/syn/src/print.rs | 16 +
> .../char/pl011/vendor/syn/src/punctuated.rs | 1132 ++++
> .../char/pl011/vendor/syn/src/restriction.rs | 176 +
> rust/hw/char/pl011/vendor/syn/src/sealed.rs | 4 +
> rust/hw/char/pl011/vendor/syn/src/span.rs | 63 +
> rust/hw/char/pl011/vendor/syn/src/spanned.rs | 118 +
> rust/hw/char/pl011/vendor/syn/src/stmt.rs | 481 ++
> rust/hw/char/pl011/vendor/syn/src/thread.rs | 60 +
> rust/hw/char/pl011/vendor/syn/src/token.rs | 1138 ++++
> rust/hw/char/pl011/vendor/syn/src/tt.rs | 107 +
> rust/hw/char/pl011/vendor/syn/src/ty.rs | 1216 ++++
> rust/hw/char/pl011/vendor/syn/src/verbatim.rs | 33 +
> .../char/pl011/vendor/syn/src/whitespace.rs | 65 +
> .../char/pl011/vendor/syn/tests/common/eq.rs | 900 +++
> .../char/pl011/vendor/syn/tests/common/mod.rs | 28 +
> .../pl011/vendor/syn/tests/common/parse.rs | 49 +
> .../char/pl011/vendor/syn/tests/debug/gen.rs | 5163 +++++++++++++++++
> .../char/pl011/vendor/syn/tests/debug/mod.rs | 147 +
> .../char/pl011/vendor/syn/tests/macros/mod.rs | 93 +
> .../char/pl011/vendor/syn/tests/regression.rs | 5 +
> .../vendor/syn/tests/regression/issue1108.rs | 5 +
> .../vendor/syn/tests/regression/issue1235.rs | 32 +
> .../char/pl011/vendor/syn/tests/repo/mod.rs | 461 ++
> .../pl011/vendor/syn/tests/repo/progress.rs | 37 +
> .../pl011/vendor/syn/tests/test_asyncness.rs | 43 +
> .../pl011/vendor/syn/tests/test_attribute.rs | 225 +
> .../vendor/syn/tests/test_derive_input.rs | 781 +++
> .../char/pl011/vendor/syn/tests/test_expr.rs | 692 +++
> .../pl011/vendor/syn/tests/test_generics.rs | 282 +
> .../pl011/vendor/syn/tests/test_grouping.rs | 53 +
> .../char/pl011/vendor/syn/tests/test_ident.rs | 87 +
> .../char/pl011/vendor/syn/tests/test_item.rs | 332 ++
> .../pl011/vendor/syn/tests/test_iterators.rs | 70 +
> .../char/pl011/vendor/syn/tests/test_lit.rs | 331 ++
> .../char/pl011/vendor/syn/tests/test_meta.rs | 154 +
> .../vendor/syn/tests/test_parse_buffer.rs | 103 +
> .../vendor/syn/tests/test_parse_quote.rs | 166 +
> .../vendor/syn/tests/test_parse_stream.rs | 187 +
> .../char/pl011/vendor/syn/tests/test_pat.rs | 152 +
> .../char/pl011/vendor/syn/tests/test_path.rs | 130 +
> .../pl011/vendor/syn/tests/test_precedence.rs | 537 ++
> .../pl011/vendor/syn/tests/test_receiver.rs | 321 +
> .../pl011/vendor/syn/tests/test_round_trip.rs | 253 +
> .../pl011/vendor/syn/tests/test_shebang.rs | 67 +
> .../char/pl011/vendor/syn/tests/test_size.rs | 36 +
> .../char/pl011/vendor/syn/tests/test_stmt.rs | 322 +
> .../vendor/syn/tests/test_token_trees.rs | 32 +
> .../hw/char/pl011/vendor/syn/tests/test_ty.rs | 397 ++
> .../pl011/vendor/syn/tests/test_visibility.rs | 185 +
> .../char/pl011/vendor/syn/tests/zzz_stable.rs | 33 +
> .../vendor/unicode-ident/.cargo-checksum.json | 1 +
> .../pl011/vendor/unicode-ident/Cargo.toml | 63 +
> .../pl011/vendor/unicode-ident/LICENSE-APACHE | 176 +
> .../pl011/vendor/unicode-ident/LICENSE-MIT | 23 +
> .../vendor/unicode-ident/LICENSE-UNICODE | 46 +
> .../char/pl011/vendor/unicode-ident/README.md | 283 +
> .../pl011/vendor/unicode-ident/benches/xid.rs | 124 +
> .../pl011/vendor/unicode-ident/meson.build | 14 +
> .../pl011/vendor/unicode-ident/src/lib.rs | 269 +
> .../pl011/vendor/unicode-ident/src/tables.rs | 651 +++
> .../vendor/unicode-ident/tests/compare.rs | 67 +
> .../vendor/unicode-ident/tests/fst/mod.rs | 11 +
> .../unicode-ident/tests/fst/xid_continue.fst | Bin 0 -> 73249 bytes
> .../unicode-ident/tests/fst/xid_start.fst | Bin 0 -> 65487 bytes
> .../vendor/unicode-ident/tests/roaring/mod.rs | 21 +
> .../vendor/unicode-ident/tests/static_size.rs | 95 +
> .../vendor/unicode-ident/tests/tables/mod.rs | 7 +
> .../unicode-ident/tests/tables/tables.rs | 347 ++
> .../vendor/unicode-ident/tests/trie/mod.rs | 7 +
> .../vendor/unicode-ident/tests/trie/trie.rs | 445 ++
> .../vendor/version_check/.cargo-checksum.json | 1 +
> .../pl011/vendor/version_check/Cargo.toml | 24 +
> .../pl011/vendor/version_check/LICENSE-APACHE | 201 +
> .../pl011/vendor/version_check/LICENSE-MIT | 19 +
> .../char/pl011/vendor/version_check/README.md | 80 +
> .../pl011/vendor/version_check/meson.build | 14 +
> .../pl011/vendor/version_check/src/channel.rs | 193 +
> .../pl011/vendor/version_check/src/date.rs | 203 +
> .../pl011/vendor/version_check/src/lib.rs | 493 ++
> .../pl011/vendor/version_check/src/version.rs | 316 +
> rust/hw/meson.build | 1 +
> rust/meson.build | 15 +
> rust/qemu-api/.gitignore | 2 +
> rust/qemu-api/Cargo.lock | 7 +
> rust/qemu-api/Cargo.toml | 23 +
> rust/qemu-api/README.md | 17 +
> rust/qemu-api/build.rs | 13 +
> rust/qemu-api/meson.build | 19 +
> rust/qemu-api/rustfmt.toml | 1 +
> rust/qemu-api/src/bindings.rs | 7 +
> rust/qemu-api/src/definitions.rs | 107 +
> rust/qemu-api/src/device_class.rs | 128 +
> rust/qemu-api/src/lib.rs | 100 +
> rust/qemu-api/src/tests.rs | 48 +
> rust/rustfmt.toml | 7 +
> .../ci/setup/ubuntu/ubuntu-2204-aarch64.yaml | 3 +
> .../ci/setup/ubuntu/ubuntu-2204-s390x.yaml | 3 +
> scripts/meson-buildoptions.sh | 3 +
> scripts/rustc_args.py | 84 +
> tests/docker/dockerfiles/alpine.docker | 3 +
> tests/docker/dockerfiles/centos9.docker | 3 +
> .../dockerfiles/debian-amd64-cross.docker | 4 +
> .../dockerfiles/debian-arm64-cross.docker | 4 +
> .../dockerfiles/debian-armel-cross.docker | 4 +
> .../dockerfiles/debian-armhf-cross.docker | 4 +
> .../dockerfiles/debian-i686-cross.docker | 4 +
> .../dockerfiles/debian-mips64el-cross.docker | 4 +
> .../dockerfiles/debian-mipsel-cross.docker | 4 +
> .../dockerfiles/debian-ppc64el-cross.docker | 4 +
> .../dockerfiles/debian-s390x-cross.docker | 4 +
> tests/docker/dockerfiles/debian.docker | 3 +
> .../dockerfiles/fedora-win64-cross.docker | 3 +
> tests/docker/dockerfiles/fedora.docker | 3 +
> tests/docker/dockerfiles/opensuse-leap.docker | 2 +
> tests/docker/dockerfiles/ubuntu2204.docker | 3 +
> tests/lcitool/libvirt-ci | 2 +-
> tests/lcitool/projects/qemu.yml | 3 +
> tests/vm/generated/freebsd.json | 2 +
> 432 files changed, 111104 insertions(+), 16 deletions(-)
> create mode 100644 rust/hw/char/pl011/vendor/either/README.rst
> create mode 100644 rust/wrapper.h
> create mode 100644 rust/.gitignore
> create mode 100644 rust/Kconfig
> create mode 100644 rust/hw/Kconfig
> create mode 100644 rust/hw/char/Kconfig
> create mode 100644 rust/hw/char/meson.build
> create mode 100644 rust/hw/char/pl011/.gitignore
> create mode 100644 rust/hw/char/pl011/Cargo.lock
> create mode 100644 rust/hw/char/pl011/Cargo.toml
> create mode 100644 rust/hw/char/pl011/README.md
> create mode 100644 rust/hw/char/pl011/meson.build
> create mode 120000 rust/hw/char/pl011/rustfmt.toml
> create mode 100644 rust/hw/char/pl011/src/definitions.rs
> create mode 100644 rust/hw/char/pl011/src/device.rs
> create mode 100644 rust/hw/char/pl011/src/device_class.rs
> create mode 100644 rust/hw/char/pl011/src/lib.rs
> create mode 100644 rust/hw/char/pl011/src/memory_ops.rs
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/CHANGELOG.md
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/LICENSE.txt
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/README.md
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/arbitrary-int/tests/tests.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/README.md
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize/split.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/bitsize_internal/struct_gen.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/debug_bits.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/default_bits.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/fmt_bits.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/from_bits.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared/discriminant_assigner.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared/fallback.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/shared/util.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge-impl/src/try_from_bits.rs
> create mode 100644 rust/hw/char/pl011/vendor/bilge/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/bilge/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/bilge/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/bilge/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/bilge/README.md
> create mode 100644 rust/hw/char/pl011/vendor/bilge/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/bilge/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/either/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/either/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/either/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/either/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/either/README-crates.io.md
> create mode 100644 rust/hw/char/pl011/vendor/either/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/either/src/into_either.rs
> create mode 100644 rust/hw/char/pl011/vendor/either/src/iterator.rs
> create mode 100644 rust/hw/char/pl011/vendor/either/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/either/src/serde_untagged.rs
> create mode 100644 rust/hw/char/pl011/vendor/either/src/serde_untagged_optional.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/itertools/CHANGELOG.md
> create mode 100644 rust/hw/char/pl011/vendor/itertools/Cargo.lock
> create mode 100644 rust/hw/char/pl011/vendor/itertools/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/itertools/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/itertools/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/itertools/README.md
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/bench1.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/combinations.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/combinations_with_replacement.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/extra/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/extra/zipslices.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/fold_specialization.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/powerset.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/tree_fold1.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/tuple_combinations.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/benches/tuples.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/examples/iris.data
> create mode 100644 rust/hw/char/pl011/vendor/itertools/examples/iris.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/coalesce.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/map.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/adaptors/multi_product.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/combinations.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/combinations_with_replacement.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/concat_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/cons_tuples_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/diff.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/duplicates_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/either_or_both.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/exactly_one_err.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/extrema_set.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/flatten_ok.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/format.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/free.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/group_map.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/groupbylazy.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/grouping_map.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/impl_macros.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/intersperse.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/k_smallest.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/kmerge_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/lazy_buffer.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/merge_join.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/minmax.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/multipeek_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/pad_tail.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/peek_nth.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/peeking_take_while.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/permutations.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/powerset.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/process_results_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/put_back_n_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/rciter_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/repeatn.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/size_hint.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/sources.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/take_while_inclusive.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/tee.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/tuple_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/unique_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/unziptuple.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/with_position.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/zip_eq_impl.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/zip_longest.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/src/ziptuple.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/adaptors_no_collect.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/flatten_ok.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/macros_hygiene.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/merge_join.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/peeking_take_while.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/quick.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/specializations.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/test_core.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/test_std.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/tuples.rs
> create mode 100644 rust/hw/char/pl011/vendor/itertools/tests/zip.rs
> create mode 100644 rust/hw/char/pl011/vendor/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/build.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/src/parse.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error-attr/src/settings.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/CHANGELOG.md
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/README.md
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/build.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/diagnostic.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/dummy.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/imp/delegate.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/imp/fallback.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/macros.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/src/sealed.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/macro-errors.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ok.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/runtime-errors.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/abort.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/append_dummy.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/children_messages.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/dummy.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/emit.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/explicit_span_range.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/misuse.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/multiple_tokens.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/not_proc_macro.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/option_ext.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/proc_macro_hack.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/result_ext.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/to_tokens_span.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unknown_setting.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro-error/tests/ui/unrelated_panic.stderr
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/README.md
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/build.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/build/probe.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/rust-toolchain.toml
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/detection.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/extra.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/fallback.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/location.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/marker.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/parse.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/rcvec.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/src/wrapper.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/comments.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/features.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/marker.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/test.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/test_fmt.rs
> create mode 100644 rust/hw/char/pl011/vendor/proc-macro2/tests/test_size.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/quote/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/quote/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/quote/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/quote/README.md
> create mode 100644 rust/hw/char/pl011/vendor/quote/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/quote/rust-toolchain.toml
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/ext.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/format.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/ident_fragment.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/runtime.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/spanned.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/src/to_tokens.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/compiletest.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/test.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter-separated.stderr
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/does-not-have-iter.stderr
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-quotable.stderr
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/not-repeatable.stderr
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.rs
> create mode 100644 rust/hw/char/pl011/vendor/quote/tests/ui/wrong-type-span.stderr
> create mode 100644 rust/hw/char/pl011/vendor/syn/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/syn/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/syn/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/syn/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/syn/README.md
> create mode 100644 rust/hw/char/pl011/vendor/syn/benches/file.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/benches/rust.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/attr.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/bigint.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/buffer.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/classify.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/custom_keyword.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/custom_punctuation.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/data.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/derive.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/discouraged.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/drops.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/error.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/export.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/expr.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/ext.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/file.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/fixup.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/clone.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/debug.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/eq.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/fold.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/hash.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/visit.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/gen/visit_mut.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/generics.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/group.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/ident.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/item.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/lifetime.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/lit.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/lookahead.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/mac.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/macros.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/meta.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/op.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/parse.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/parse_macro_input.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/parse_quote.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/pat.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/path.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/precedence.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/print.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/punctuated.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/restriction.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/sealed.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/span.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/spanned.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/stmt.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/thread.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/token.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/tt.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/ty.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/verbatim.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/src/whitespace.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/common/eq.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/common/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/common/parse.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/debug/gen.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/debug/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/macros/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/regression.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/regression/issue1108.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/regression/issue1235.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/repo/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/repo/progress.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_asyncness.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_attribute.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_derive_input.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_expr.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_generics.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_grouping.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_ident.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_item.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_iterators.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_lit.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_meta.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_parse_buffer.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_parse_quote.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_parse_stream.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_pat.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_path.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_precedence.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_receiver.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_round_trip.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_shebang.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_size.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_stmt.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_token_trees.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_ty.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/test_visibility.rs
> create mode 100644 rust/hw/char/pl011/vendor/syn/tests/zzz_stable.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/LICENSE-UNICODE
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/README.md
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/benches/xid.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/src/tables.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/compare.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/fst/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/fst/xid_continue.fst
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/fst/xid_start.fst
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/roaring/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/static_size.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/tables/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/tables/tables.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/trie/mod.rs
> create mode 100644 rust/hw/char/pl011/vendor/unicode-ident/tests/trie/trie.rs
> create mode 100644 rust/hw/char/pl011/vendor/version_check/.cargo-checksum.json
> create mode 100644 rust/hw/char/pl011/vendor/version_check/Cargo.toml
> create mode 100644 rust/hw/char/pl011/vendor/version_check/LICENSE-APACHE
> create mode 100644 rust/hw/char/pl011/vendor/version_check/LICENSE-MIT
> create mode 100644 rust/hw/char/pl011/vendor/version_check/README.md
> create mode 100644 rust/hw/char/pl011/vendor/version_check/meson.build
> create mode 100644 rust/hw/char/pl011/vendor/version_check/src/channel.rs
> create mode 100644 rust/hw/char/pl011/vendor/version_check/src/date.rs
> create mode 100644 rust/hw/char/pl011/vendor/version_check/src/lib.rs
> create mode 100644 rust/hw/char/pl011/vendor/version_check/src/version.rs
> create mode 100644 rust/hw/meson.build
> create mode 100644 rust/meson.build
> create mode 100644 rust/qemu-api/.gitignore
> create mode 100644 rust/qemu-api/Cargo.lock
> create mode 100644 rust/qemu-api/Cargo.toml
> create mode 100644 rust/qemu-api/README.md
> create mode 100644 rust/qemu-api/build.rs
> create mode 100644 rust/qemu-api/meson.build
> create mode 120000 rust/qemu-api/rustfmt.toml
> create mode 100644 rust/qemu-api/src/bindings.rs
> create mode 100644 rust/qemu-api/src/definitions.rs
> create mode 100644 rust/qemu-api/src/device_class.rs
> create mode 100644 rust/qemu-api/src/lib.rs
> create mode 100644 rust/qemu-api/src/tests.rs
> create mode 100644 rust/rustfmt.toml
> create mode 100644 scripts/rustc_args.py
>
>
> base-commit: a7ddb48bd1363c8bcdf42776d320289c42191f01
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-23 15:07 ` [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Paolo Bonzini
@ 2024-07-24 9:14 ` Manos Pitsidianakis
2024-07-24 10:34 ` Paolo Bonzini
0 siblings, 1 reply; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-24 9:14 UTC (permalink / raw)
To: Paolo Bonzini, qemu-devel
Cc: Stefan Hajnoczi, Mads Ynddal, Peter Maydell, Alex Benné e,
Daniel P. Berrangé , Marc-André Lureau, Thomas Huth,
Markus Armbruster, Philippe Mathieu-Daudé , Zhao Liu,
Gustavo Romero, Pierrick Bouvier, rowan.hart, Richard Henderson
Hello Paolo, thank you for the thorough response,
On Tue, 23 Jul 2024 18:07, Paolo Bonzini <pbonzini@redhat.com> wrote:
>On 7/22/24 13:43, Manos Pitsidianakis wrote:
>> Changes from v4->v5:
>> - Added CI patch from Alex Benee
>> - Removed all cargo use, use meson rust support
>> - Added Kconfig logic
>
>The following requests from the v4 review have also been evaluated (good!):
>
>✅ module structure should resemble the C part of the tree
To expand on this, I tried really hard to make the rust code live along
the c files, but given that the bindings depend on various headers that
are only gathered in the common source set in meson by the time all the
subdirs are evaluated, it results in the Rust device being dependendant
on a meson target (bindings_rs) that cannot be declared yet.
It's kind of a code smell, ideally we should not use bindgen for QEMU
internal headers but update bindings along with the C headers (with
extra tests to ensure definitions and layout match). Not for this
patchset, but something to keep in mind.
>
>✅ only generate bindings.rs.inc once
>
>✅ a couple lints are too broad and should be enabled per-file. (though
>there are still some issues with duplication of lints, I consider this
>mostly done)
>
>✅ please check if -Wl,--whole-archive can be replaced with link_whole
>(as discussed on IRC, unfortunately it cannot)
>
>
>The hot point here is how to handle dependencies. I appreciate that you
>found a way to avoid repeated building of dependent crates, and to
>integrate with Kconfig, but at the same time this is a huge change which
>in my opinion is premature.
>
>For example if we can (sooner or later) use the automatic Cargo
>subprojects, we do not need any vendoring and we can use cargo in the
>meanwhile (we can drop --cargo and CARGO at any point, just like we
>dropped --meson and --sphinx-build in QEMU 8.1).
>
>On the other hand, committing to using meson's "raw" (meson.build-level)
>rust support and vendoring everything is premature in my opinion is very
>different for people who are already comfortable with Cargo, so it makes
>it harder to add new dependencies. In fact, because the huge patch 8
>did not reach the mailing list, it's really hard to understand what's
>going on, what had to be done by hand and what is done automatically by
>meson.
I agree. I personally prefer using meson wraps and fetch the
dependencies via network to be honest. While also providing Cargo.toml
and Cargo.lock manifests for developers.
>
>In my opinion we should start with cargo workspaces as the
>known-imperfect (but good enough) solution, so that it could be evolved
>later. It is important that any change that deviates from common Rust
>conventions is documented, and v4 provided a nice basis to build upon,
>with documentation coming as things settle. This is why I explicitly
>didn't include Kconfig in the TODO list in my review of v4.
After working with the latest meson releases, it seems we will soon have
a good enough way of handling all this with meson. It makes me sceptical
of adding cargo wrappers and using a build system out of meson when we
might be able to drop all that soonish. We might as well bite the bullet
now to avoid working on something we know we will remove. It's not that
of a clear-cut decision, so I'd like feedback on this. What do you
think?
>
>> .../vendor/arbitrary-int/.cargo-checksum.json | 1 +
>
>In any case, vendoring should not be done inside hw/char/pl011.
>
>Also, of the code changes (as opposed to the build system changes) that
>I had asked for in the review of v4, almost none of them have been
>applied. I'm copying them here for future reference:
Thanks, this helps a lot.
>
>❌ TODO comments when the code is doing potential undefined behavior
Do you mean like Rust's safety comments?
https://std-dev-guide.rust-lang.org/policy/safety-comments.html
These can be required by lints which is really helpful. At this point
the UART library has safety comments (which needs to be reviewed for
validity). I plan on adding some at the macros in qemu-api as well.
>
>❌ a trait to store the CStr corresponding to the structs
I don't know yet if that is helpful in our usecase, because the strings
must be visible from C, thus be (rust, not c) statics, unmangled and
marked as #[used] for the linker. It makes sense from the Rust POV but
must also be FFI-accessible.
>
>❌ a trait to generate all-zero structs without having to type "unsafe {
>MaybeUninit::zeroed().assume_init() }"
Traits cannot have const fns at the moment (traits cannot have
type-level effects like const or async but it's WIP to get them into
rustc), so this cannot be used for statics and consts.
>
>❌ I'd like to use ctor instead of non-portable linker magic,
The linker sections are pretty much standard and in fact ctor uses the
same linker attributes. Would writing our own constructor macro be a
solution for you? My reasoning is that 1) we support our own specific
platforms and it's better for portability to reflect that in our source
tree and 2) it avoids the external dependency, linker sections do not
change so any ctor update would be in the API or adding more platform
support, not fixes in what we target.
>and the cstr crate instead of CStr statics or c""
Oh yes, the c"" literals must be replaced. The cstr! macro is the same,
semantically, can you explain what you mean by "CStr statics"?
>
>If you have a tree that I can look at, to understand more of patch 8,
>please send a pointer. However, honestly I am not comfortable with the
>build system integration as done in this patch.
Ah forgot to mention it in the cover letter, everything is under the
rust-pl011-rfc-v5 tag here:
https://gitlab.com/epilys/rust-for-qemu/-/tree/rust-pl011-rfc-v5?ref_type=tags
>
>My suggestion is to do one of the following, or both:
>
>- start from this version; try using Cargo subproject support in 1.5.0
>and see if it works, so that vendoring can be dropped. We can require
>Meson 1.5.0 to work on Rust support. In this case it's okay not to do
>any further code changes (the four that were marked ❌ above).
This is my preference as stated above, if everyone also agrees.
>
>- go back to the build system integration of v4, and do *only* the
>changes that were requested during review (in this case, all of them
>except link_whole, with you checked it does not work).
>
>If you try using Cargo subproject support, please provide the running
>time for configure and make, for both "v4" and "v5+subproject". When I
>tried it, the processing of the subprojects was very slow.
Hmmm thanks for mentioning that, I did not notice any slow times
locally. Will check.
Thanks!
Manos
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-24 9:14 ` Manos Pitsidianakis
@ 2024-07-24 10:34 ` Paolo Bonzini
2024-07-25 5:47 ` Manos Pitsidianakis
0 siblings, 1 reply; 35+ messages in thread
From: Paolo Bonzini @ 2024-07-24 10:34 UTC (permalink / raw)
To: Manos Pitsidianakis
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Daniel P. Berrangé,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé, Zhao Liu, Gustavo Romero,
Pierrick Bouvier, rowan.hart, Richard Henderson
On Wed, Jul 24, 2024 at 11:58 AM Manos Pitsidianakis
<manos.pitsidianakis@linaro.org> wrote:
>
> Hello Paolo, thank you for the thorough response,
>
> On Tue, 23 Jul 2024 18:07, Paolo Bonzini <pbonzini@redhat.com> wrote:
> >On 7/22/24 13:43, Manos Pitsidianakis wrote:
> >> Changes from v4->v5:
> >> - Added CI patch from Alex Benee
> >> - Removed all cargo use, use meson rust support
> >> - Added Kconfig logic
> >
> >The following requests from the v4 review have also been evaluated (good!):
> >
> >✅ module structure should resemble the C part of the tree
>
> To expand on this, I tried really hard to make the rust code live along
> the c files
Yes, I don't think it's a requirement that they live along the C
files. Using rust/hw/... as you did is fine.
> I agree. I personally prefer using meson wraps and fetch the
> dependencies via network to be honest. While also providing Cargo.toml
> and Cargo.lock manifests for developers.
Ok, it's good that you agree because that's what I was worried about. :)
> >
> >In my opinion we should start with cargo workspaces as the
> >known-imperfect (but good enough) solution, so that it could be evolved
> >later. It is important that any change that deviates from common Rust
> >conventions is documented, and v4 provided a nice basis to build upon,
> >with documentation coming as things settle. This is why I explicitly
> >didn't include Kconfig in the TODO list in my review of v4.
>
> After working with the latest meson releases, it seems we will soon have
> a good enough way of handling all this with meson. It makes me sceptical
> of adding cargo wrappers and using a build system out of meson when we
> might be able to drop all that soonish. We might as well bite the bullet
> now to avoid working on something we know we will remove.
Ehh, as you say below it's complicated. Sometimes worse is better.
Personally I wouldn't have minded keeping the v4 approach as a "known
evil"; but if you can make the Cargo subprojects work, that would be
fine for me. What I don't like is the vendoring and handwritten (I
think?) meson.build, I think that's worse than the v4.
> >Also, of the code changes (as opposed to the build system changes) that
> >I had asked for in the review of v4, almost none of them have been
> >applied. I'm copying them here for future reference:
>
> Thanks, this helps a lot.
>
> >❌ TODO comments when the code is doing potential undefined behavior
>
> Do you mean like Rust's safety comments?
No I meant comments where we have known instances of undefined
behavior. The two I had in my emails are
(in pl011_init):
// TODO: this assumes that "all zeroes" is a valid state for all fields of
// PL011State. This is not necessarily true of any #[repr(Rust)] structs,
// including bilge-generated types. It should instead use MaybeUninit.
(before the call to qemu_chr_fe_accept_input):
// TODO: this causes a callback that creates another "&mut self".
// This is forbidden by Rust aliasing rules and has to be fixed
// using interior mutability.
> https://std-dev-guide.rust-lang.org/policy/safety-comments.html
>
> These can be required by lints which is really helpful. At this point
> the UART library has safety comments (which needs to be reviewed for
> validity). I plan on adding some at the macros in qemu-api as well.
>
> >
> >❌ a trait to store the CStr corresponding to the structs
>
> I don't know yet if that is helpful in our usecase, because the strings
> must be visible from C, thus be (rust, not c) statics, unmangled and
> marked as #[used] for the linker. It makes sense from the Rust POV but
> must also be FFI-accessible.
Why do they have to be #[used]? You have
+ #[used]
+ static TYPE_NAME: &::core::ffi::CStr = $tname;
+ $tname.as_ptr()
but since the cstr crate (and c"" literal) promise to return a
&'static CStr, I thought it could be just
$tname.as_ptr()
About traits, I meant something like
pub unsafe trait ObjectType: Sized {
const TYPE_NAME: &'static CStr;
}
So that you can put the trait declaration in the pl011 crate and the
type_info! macro can do
<$t as ObjectType>::TYPE_NAME.as_ptr()
(also for the parent).
> >❌ a trait to generate all-zero structs without having to type "unsafe {
> >MaybeUninit::zeroed().assume_init() }"
>
> Traits cannot have const fns at the moment (traits cannot have
> type-level effects like const or async but it's WIP to get them into
> rustc), so this cannot be used for statics and consts.
Ah, I see. Anyhow, I've been looking at the Linux kernel's pinned-init
crate (https://rust-for-linux.com/pinned-init) and it provides a
Zeroable macro including #[derive] support. So that has gone lower in
my priority.
> >❌ I'd like to use ctor instead of non-portable linker magic,
>
> The linker sections are pretty much standard and in fact ctor uses the
> same linker attributes. Would writing our own constructor macro be a
> solution for you? My reasoning is that 1) we support our own specific
> platforms and it's better for portability to reflect that in our source
> tree and 2) it avoids the external dependency, linker sections do not
> change so any ctor update would be in the API or adding more platform
> support, not fixes in what we target.
I'd still like to give someone else the burden. :) Writing our own
constructor macro would be more work for little gain.
> >and the cstr crate instead of CStr statics or c""
>
> Oh yes, the c"" literals must be replaced. The cstr! macro is the same,
> semantically, can you explain what you mean by "CStr statics"?
Ah, I meant that it applies to both direct use:
pub static CLK_NAME: &CStr = c"clk";
and arguments to macros (for example type_info).
> >My suggestion is to do one of the following, or both:
> >
> >- start from this version; try using Cargo subproject support in 1.5.0
> >and see if it works, so that vendoring can be dropped. We can require
> >Meson 1.5.0 to work on Rust support. In this case it's okay not to do
> >any further code changes (the four that were marked ❌ above).
>
> This is my preference as stated above, if everyone also agrees.
I think it's worth trying it anyway.
> >- go back to the build system integration of v4, and do *only* the
> >changes that were requested during review (in this case, all of them
> >except link_whole, with you checked it does not work).
> >
> >If you try using Cargo subproject support, please provide the running
> >time for configure and make, for both "v4" and "v5+subproject". When I
> >tried it, the processing of the subprojects was very slow.
>
> Hmmm thanks for mentioning that, I did not notice any slow times
> locally. Will check.
Ok, thanks!
Paolo
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-24 10:34 ` Paolo Bonzini
@ 2024-07-25 5:47 ` Manos Pitsidianakis
2024-07-25 9:50 ` Paolo Bonzini
0 siblings, 1 reply; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-25 5:47 UTC (permalink / raw)
To: qeemu-devel, Paolo Bonzini
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Daniel P. Berrangé ,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé , Zhao Liu, Gustavo Romero,
Pierrick Bouvier, rowan.hart, Richard Henderson
On Wed, 24 Jul 2024 13:34, Paolo Bonzini <pbonzini@redhat.com> wrote:
>On Wed, Jul 24, 2024 at 11:58 AM Manos Pitsidianakis
><manos.pitsidianakis@linaro.org> wrote:
>> >In my opinion we should start with cargo workspaces as the
>> >known-imperfect (but good enough) solution, so that it could be evolved
>> >later. It is important that any change that deviates from common Rust
>> >conventions is documented, and v4 provided a nice basis to build upon,
>> >with documentation coming as things settle. This is why I explicitly
>> >didn't include Kconfig in the TODO list in my review of v4.
>>
>> After working with the latest meson releases, it seems we will soon have
>> a good enough way of handling all this with meson. It makes me sceptical
>> of adding cargo wrappers and using a build system out of meson when we
>> might be able to drop all that soonish. We might as well bite the bullet
>> now to avoid working on something we know we will remove.
>
>Ehh, as you say below it's complicated. Sometimes worse is better.
>Personally I wouldn't have minded keeping the v4 approach as a "known
>evil"; but if you can make the Cargo subprojects work, that would be
>fine for me. What I don't like is the vendoring and handwritten (I
>think?) meson.build, I think that's worse than the v4.
>
>> >Also, of the code changes (as opposed to the build system changes) that
>> >I had asked for in the review of v4, almost none of them have been
>> >applied. I'm copying them here for future reference:
>>
>> Thanks, this helps a lot.
>>
>> >❌ TODO comments when the code is doing potential undefined behavior
>>
>> Do you mean like Rust's safety comments?
>
>No I meant comments where we have known instances of undefined
>behavior. The two I had in my emails are
>
>(in pl011_init):
>// TODO: this assumes that "all zeroes" is a valid state for all fields of
>// PL011State. This is not necessarily true of any #[repr(Rust)] structs,
>// including bilge-generated types. It should instead use MaybeUninit.
>
>(before the call to qemu_chr_fe_accept_input):
>// TODO: this causes a callback that creates another "&mut self".
>// This is forbidden by Rust aliasing rules and has to be fixed
>// using interior mutability.
You mean that we can have a call stack that looks something like...
<qemu code>
|_ pl011_read
|_ PL011State::read()
|_ qemu_chr_fe_accept_input()
|_ pl011_read
|_ PL011State::read()
If I understand correctly, this does not create another "&mut self",
because a mutable reference of self is passed to
qemu_chr_fe_accept_input(), and only exists until it returns.
In any case, I agree that these subtleties must be examined thoroughly
in general. In this case though PL011State has only Copy fields and no
side effects when dropped. This means that adding interior mutability
e.g. with Cell would have exactly the same behavior.
But your bringing it up makes me wonder whether we can detect any bad
behaviors with miri... It does not play well with FFI boundaries but
it's possible to mock them in some cases. I will look into the two TODOs
you mention and also if it's possible to verify the correct behavior
whenever possible!
>
>> https://std-dev-guide.rust-lang.org/policy/safety-comments.html
>>
>> These can be required by lints which is really helpful. At this point
>> the UART library has safety comments (which needs to be reviewed for
>> validity). I plan on adding some at the macros in qemu-api as well.
>>
>> >
>> >❌ a trait to store the CStr corresponding to the structs
>>
>> I don't know yet if that is helpful in our usecase, because the strings
>> must be visible from C, thus be (rust, not c) statics, unmangled and
>> marked as #[used] for the linker. It makes sense from the Rust POV but
>> must also be FFI-accessible.
>
>Why do they have to be #[used]? You have
>
>+ #[used]
>+ static TYPE_NAME: &::core::ffi::CStr = $tname;
>+ $tname.as_ptr()
>
>but since the cstr crate (and c"" literal) promise to return a
>&'static CStr, I thought it could be just
>
> $tname.as_ptr()
>
>About traits, I meant something like
>
>pub unsafe trait ObjectType: Sized {
> const TYPE_NAME: &'static CStr;
>}
>
>So that you can put the trait declaration in the pl011 crate and the
>type_info! macro can do
>
><$t as ObjectType>::TYPE_NAME.as_ptr()
>
>(also for the parent).
That was my approach at the beginning but I was having issues with the
linker stripping the <some const value>.as_ptr() and it would point to
invalid memory; I checked it again and I think using #[used] just for
the TypeInfo struct declaration might be enough so these can be removed.
>
>> >❌ a trait to generate all-zero structs without having to type "unsafe {
>> >MaybeUninit::zeroed().assume_init() }"
>>
>> Traits cannot have const fns at the moment (traits cannot have
>> type-level effects like const or async but it's WIP to get them into
>> rustc), so this cannot be used for statics and consts.
>
>Ah, I see. Anyhow, I've been looking at the Linux kernel's pinned-init
>crate (https://rust-for-linux.com/pinned-init) and it provides a
>Zeroable macro including #[derive] support. So that has gone lower in
>my priority.
>
>> >❌ I'd like to use ctor instead of non-portable linker magic,
>>
>> The linker sections are pretty much standard and in fact ctor uses the
>> same linker attributes. Would writing our own constructor macro be a
>> solution for you? My reasoning is that 1) we support our own specific
>> platforms and it's better for portability to reflect that in our source
>> tree and 2) it avoids the external dependency, linker sections do not
>> change so any ctor update would be in the API or adding more platform
>> support, not fixes in what we target.
>
>I'd still like to give someone else the burden. :) Writing our own
>constructor macro would be more work for little gain.
Well, it's just that I personally don't view adding __attribute__
manually in only two places is a burden but I've no strong preference
over it.
I'm looking at the ctor dependencies and they are a few:
https://github.com/mmastrac/rust-ctor/blob/cc3ab9160ed9dc3bdf20d735352b519abc2913e9/Cargo.lock
Do you perhaps agree with adding a FIXME comment to replace the linker
attributes with ctor when we get the cargo dependency story in meson
sorted out?
Manos
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-25 5:47 ` Manos Pitsidianakis
@ 2024-07-25 9:50 ` Paolo Bonzini
2024-07-25 10:02 ` Manos Pitsidianakis
0 siblings, 1 reply; 35+ messages in thread
From: Paolo Bonzini @ 2024-07-25 9:50 UTC (permalink / raw)
To: Manos Pitsidianakis
Cc: qeemu-devel, qemu-devel, Stefan Hajnoczi, Mads Ynddal,
Peter Maydell, Alex Benné e, Daniel P. Berrangé,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé, Zhao Liu, Gustavo Romero,
Pierrick Bouvier, rowan.hart, Richard Henderson
[-- Attachment #1: Type: text/plain, Size: 3642 bytes --]
Il gio 25 lug 2024, 08:19 Manos Pitsidianakis <
manos.pitsidianakis@linaro.org> ha scritto:
> >(before the call to qemu_chr_fe_accept_input):
> >// TODO: this causes a callback that creates another "&mut self".
> >// This is forbidden by Rust aliasing rules and has to be fixed
> >// using interior mutability.
>
> You mean that we can have a call stack that looks something like...
>
> <qemu code>
> |_ pl011_read
> |_ PL011State::read()
> |_ qemu_chr_fe_accept_input()
> |_ pl011_read
> |_ PL011State::read()
>
> If I understand correctly, this does not create another "&mut self",
> because a mutable reference of self is passed to
> qemu_chr_fe_accept_input(), and only exists until it returns.
>
Unfortunately that's a *mut, not a &mut. A &mut must be unique, so the cast
in pl011_read() is undefined behavior.
In any case, I agree that these subtleties must be examined thoroughly
> in general. In this case though PL011State has only Copy fields and no
> side effects when dropped. This means that adding interior mutability
> e.g. with Cell would have exactly the same behavior.
>
If you add interior mutability you can operate on a &self; and then
creating the &mut (via either Cell or RefCell) from the callback is legal.
But your bringing it up makes me wonder whether we can detect any bad
> behaviors with miri... It does not play well with FFI boundaries but
> it's possible to mock them in some cases. I will look into the two TODOs
> you mention and also if it's possible to verify the correct behavior
> whenever possible!
>
The most robust way is to write proper bindings to QEMU APIs that enforce
use of shared references. That will take time; but we'll get there, for now
it's important just to point out the problem.
> >> >❌ a trait to generate all-zero structs without having to type "unsafe {
> >> >MaybeUninit::zeroed().assume_init() }"
> >>
> >> Traits cannot have const fns at the moment (traits cannot have
> >> type-level effects like const or async but it's WIP to get them into
> >> rustc), so this cannot be used for statics and consts.
> >
> >Ah, I see. Anyhow, I've been looking at the Linux kernel's pinned-init
> >crate (https://rust-for-linux.com/pinned-init) and it provides a
> >Zeroable macro including #[derive] support. So that has gone lower in
> >my priority.
> >
> >> >❌ I'd like to use ctor instead of non-portable linker magic,
> >>
> >> The linker sections are pretty much standard and in fact ctor uses the
> >> same linker attributes. Would writing our own constructor macro be a
> >> solution for you? My reasoning is that 1) we support our own specific
> >> platforms and it's better for portability to reflect that in our source
> >> tree and 2) it avoids the external dependency, linker sections do not
> >> change so any ctor update would be in the API or adding more platform
> >> support, not fixes in what we target.
> >
> >I'd still like to give someone else the burden. :) Writing our own
> >constructor macro would be more work for little gain.
>
> Well, it's just that I personally don't view adding __attribute__
> manually in only two places is a burden but I've no strong preference
> over it.
>
> I'm looking at the ctor dependencies and they are a few:
>
> https://github.com/mmastrac/rust-ctor/blob/cc3ab9160ed9dc3bdf20d735352b519abc2913e9/Cargo.lock
>
> Do you perhaps agree with adding a FIXME comment to replace the linker
> attributes with ctor when we get the cargo dependency story in meson
> sorted out?
>
Yes, that's fine.
Paolo
Manos
>
>
[-- Attachment #2: Type: text/html, Size: 5664 bytes --]
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-25 9:50 ` Paolo Bonzini
@ 2024-07-25 10:02 ` Manos Pitsidianakis
2024-07-25 11:19 ` Paolo Bonzini
0 siblings, 1 reply; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-25 10:02 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qeemu-devel, qemu-devel, Stefan Hajnoczi, Mads Ynddal,
Peter Maydell, Alex Benné e, Daniel P. Berrangé ,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé , Zhao Liu, Gustavo Romero,
Pierrick Bouvier, rowan.hart, Richard Henderson
On Thu, 25 Jul 2024 12:50, Paolo Bonzini <pbonzini@redhat.com> wrote:
>Il gio 25 lug 2024, 08:19 Manos Pitsidianakis <
>manos.pitsidianakis@linaro.org> ha scritto:
>
>> >(before the call to qemu_chr_fe_accept_input):
>> >// TODO: this causes a callback that creates another "&mut self".
>> >// This is forbidden by Rust aliasing rules and has to be fixed
>> >// using interior mutability.
>>
>> You mean that we can have a call stack that looks something like...
>>
>> <qemu code>
>> |_ pl011_read
>> |_ PL011State::read()
>> |_ qemu_chr_fe_accept_input()
>> |_ pl011_read
>> |_ PL011State::read()
>>
>> If I understand correctly, this does not create another "&mut self",
>> because a mutable reference of self is passed to
>> qemu_chr_fe_accept_input(), and only exists until it returns.
>>
>
>Unfortunately that's a *mut, not a &mut. A &mut must be unique, so the cast
>in pl011_read() is undefined behavior.
Actually it's:
unsafe { qemu_chr_fe_accept_input(&mut self.char_backend) };
And you can ensure there's no disjoint borrowing by making a wrapper
function that mutably borrows self, e.g.
fn accept_input(&mut self) {
unsafe { qemu_chr_fe_accept_input(&mut self.char_backend) };
}
This is not undefined behavior, since the cast in pl011_read creates a
mutable reference that does not outlive the same call to pl011_read.
>
>In any case, I agree that these subtleties must be examined thoroughly
>> in general. In this case though PL011State has only Copy fields and no
>> side effects when dropped. This means that adding interior mutability
>> e.g. with Cell would have exactly the same behavior.
>>
>
>If you add interior mutability you can operate on a &self; and then
>creating the &mut (via either Cell or RefCell) from the callback is legal.
>
>But your bringing it up makes me wonder whether we can detect any bad
>> behaviors with miri... It does not play well with FFI boundaries but
>> it's possible to mock them in some cases. I will look into the two TODOs
>> you mention and also if it's possible to verify the correct behavior
>> whenever possible!
>>
>
>The most robust way is to write proper bindings to QEMU APIs that enforce
>use of shared references. That will take time; but we'll get there, for now
>it's important just to point out the problem.
Please demonstrate a scenario where said problem shows up, otherwise
it's just hand-waving on a undefined (pun intended ;) ) hypothetical.
>
>
>> >> >❌ a trait to generate all-zero structs without having to type "unsafe {
>> >> >MaybeUninit::zeroed().assume_init() }"
>> >>
>> >> Traits cannot have const fns at the moment (traits cannot have
>> >> type-level effects like const or async but it's WIP to get them into
>> >> rustc), so this cannot be used for statics and consts.
>> >
>> >Ah, I see. Anyhow, I've been looking at the Linux kernel's pinned-init
>> >crate (https://rust-for-linux.com/pinned-init) and it provides a
>> >Zeroable macro including #[derive] support. So that has gone lower in
>> >my priority.
>> >
>> >> >❌ I'd like to use ctor instead of non-portable linker magic,
>> >>
>> >> The linker sections are pretty much standard and in fact ctor uses the
>> >> same linker attributes. Would writing our own constructor macro be a
>> >> solution for you? My reasoning is that 1) we support our own specific
>> >> platforms and it's better for portability to reflect that in our source
>> >> tree and 2) it avoids the external dependency, linker sections do not
>> >> change so any ctor update would be in the API or adding more platform
>> >> support, not fixes in what we target.
>> >
>> >I'd still like to give someone else the burden. :) Writing our own
>> >constructor macro would be more work for little gain.
>>
>> Well, it's just that I personally don't view adding __attribute__
>> manually in only two places is a burden but I've no strong preference
>> over it.
>>
>> I'm looking at the ctor dependencies and they are a few:
>>
>> https://github.com/mmastrac/rust-ctor/blob/cc3ab9160ed9dc3bdf20d735352b519abc2913e9/Cargo.lock
>>
>> Do you perhaps agree with adding a FIXME comment to replace the linker
>> attributes with ctor when we get the cargo dependency story in meson
>> sorted out?
>>
>
>Yes, that's fine.
Thanks! We also have to keep in mind we would like Debian to be able to
package this, so we should be very conservative on what dependencies we
use.
>
>Paolo
>
>Manos
>>
>>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-25 10:02 ` Manos Pitsidianakis
@ 2024-07-25 11:19 ` Paolo Bonzini
2024-07-25 14:48 ` Manos Pitsidianakis
0 siblings, 1 reply; 35+ messages in thread
From: Paolo Bonzini @ 2024-07-25 11:19 UTC (permalink / raw)
To: Manos Pitsidianakis
Cc: qeemu-devel, qemu-devel, Stefan Hajnoczi, Mads Ynddal,
Peter Maydell, Alex Benné e, Daniel P. Berrangé,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé, Zhao Liu, Gustavo Romero,
Pierrick Bouvier, rowan.hart, Richard Henderson
On Thu, Jul 25, 2024 at 12:14 PM Manos Pitsidianakis
<manos.pitsidianakis@linaro.org> wrote:
> >Unfortunately that's a *mut, not a &mut. A &mut must be unique, so the cast
> >in pl011_read() is undefined behavior.
>
> Actually it's:
>
> unsafe { qemu_chr_fe_accept_input(&mut self.char_backend) };
>
> And you can ensure there's no disjoint borrowing by making a wrapper
> function that mutably borrows self, e.g.
>
> fn accept_input(&mut self) {
> unsafe { qemu_chr_fe_accept_input(&mut self.char_backend) };
> }
>
> This is not undefined behavior, since the cast in pl011_read creates a
> mutable reference that does not outlive the same call to pl011_read.
pl011_receive (called by qemu_chr_fe_accept_input) creates a mutable
reference that *overlaps* the lifetime of the outer reference created
by pl011_read. This is undefined behavior. You're effectively writing:
fn main() {
let mut foo = String::from("foo");
let x = &mut foo;
let y = &mut foo;
print!("{}", y);
print!("{}", x); // does not compile
}
And even if you're hiding it like this:
fn main() {
let mut foo = String::from("foo");
let x = &mut foo;
let x_ptr: *mut String = x as *mut _;
let y = &mut foo;
print!("{}", y);
print!("{}", unsafe { &mut *x_ptr });
}
It's still wrong. Quoting the docs:
https://doc.rust-lang.org/nightly/nomicon/references.html
-> "A mutable reference cannot be aliased"
https://doc.rust-lang.org/nightly/nomicon/aliasing.html
-> "variables and pointers alias if they refer to overlapping regions
of memory."
https://doc.rust-lang.org/reference/behavior-considered-undefined.html
-> "Rust programs must never cause undefined behavior. It is the
programmer's responsibility when writing unsafe code to ensure that
any safe code interacting with the unsafe code cannot trigger these
behaviors."
The QEMU code has even more layers hiding the problem but it's the
same thing: there are two &mut that are alive at the same time, and
refer to the same region of memory.
> Please demonstrate a scenario where said problem shows up, otherwise
> it's just hand-waving on a undefined (pun intended ;) ) hypothetical.
Again: there's no "scenario where the problem shows up", you just
can't do that; the code is wrong.
I'm not saying you should fix it now, because it's complicated to fix
it and in particular to fix it the right way. But I think it is a
requirement for merging Rust code that the community understands the
extra complexity introduced by writing Rust code that interacts with C
APIs, and does not hand wave it away as not a problem.
> >> Do you perhaps agree with adding a FIXME comment to replace the linker
> >> attributes with ctor when we get the cargo dependency story in meson
> >> sorted out?
> >
> >Yes, that's fine.
>
> Thanks! We also have to keep in mind we would like Debian to be able to
> package this, so we should be very conservative on what dependencies we
> use.
If we add Rust dependencies, Debian will have to figure out how to
package them in order to build QEMU. But I agree that it's a good idea
to add them slowly.
Paolo
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-25 11:19 ` Paolo Bonzini
@ 2024-07-25 14:48 ` Manos Pitsidianakis
2024-07-25 15:15 ` Paolo Bonzini
0 siblings, 1 reply; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-25 14:48 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Daniel P. Berrangé,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé, Zhao Liu, Gustavo Romero,
Pierrick Bouvier, rowan.hart, Richard Henderson
On Thu, 25 Jul 2024 at 14:19, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On Thu, Jul 25, 2024 at 12:14 PM Manos Pitsidianakis
> <manos.pitsidianakis@linaro.org> wrote:
> > >Unfortunately that's a *mut, not a &mut. A &mut must be unique, so the cast
> > >in pl011_read() is undefined behavior.
> >
> > Actually it's:
> >
> > unsafe { qemu_chr_fe_accept_input(&mut self.char_backend) };
> >
> > And you can ensure there's no disjoint borrowing by making a wrapper
> > function that mutably borrows self, e.g.
> >
> > fn accept_input(&mut self) {
> > unsafe { qemu_chr_fe_accept_input(&mut self.char_backend) };
> > }
> >
> > This is not undefined behavior, since the cast in pl011_read creates a
> > mutable reference that does not outlive the same call to pl011_read.
>
> pl011_receive (called by qemu_chr_fe_accept_input) creates a mutable
> reference that *overlaps* the lifetime of the outer reference created
> by pl011_read. This is undefined behavior. You're effectively writing:
There is no overlap there, sorry. Once qemu_chr_fe_accept_input
returns, any references it created do not exist anymore.
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-25 14:48 ` Manos Pitsidianakis
@ 2024-07-25 15:15 ` Paolo Bonzini
2024-07-26 7:12 ` Manos Pitsidianakis
0 siblings, 1 reply; 35+ messages in thread
From: Paolo Bonzini @ 2024-07-25 15:15 UTC (permalink / raw)
To: Manos Pitsidianakis
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Daniel P. Berrangé,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé, Zhao Liu, Gustavo Romero,
Pierrick Bouvier, rowan.hart, Richard Henderson
On Thu, Jul 25, 2024 at 4:48 PM Manos Pitsidianakis
<manos.pitsidianakis@linaro.org> wrote:
> > pl011_receive (called by qemu_chr_fe_accept_input) creates a mutable
> > reference that *overlaps* the lifetime of the outer reference created
> > by pl011_read. This is undefined behavior. You're effectively writing:
>
> There is no overlap there, sorry. Once qemu_chr_fe_accept_input
> returns, any references it created do not exist anymore.
read |-------------|
receive |-----|
That's the overlap. Maybe you're thinking that the outer &mut "goes to
sleep" and is reborn when qemu_chr_fe_accept_input() returns, but
there's no such thing in the language.
You can do it within a function:
fn main() {
let mut x = 42u32;
let a = &mut x;
let b = &mut *a;
*b = 0;
*a = 43;
// *b = 42;
}
But that's because the compiler _knows_ the provenance of b. So it
says "ok, 'b' is basically the same as 'a' and 'a' won't be accessed
while 'b' is live". This doesn't happen in any other case. In fact
miri points out that, the moment you create a &mut in pl011_read, the
chardev's opaque becomes effectively unusable[1]. In other words,
you're not even allowed to turn it from a *mut into a &mut!
Again: it's exactly the same as the example above
fn main() {
let mut foo = String::from("foo");
let x = &mut foo; // pl011_read has a reference
let x_ptr: *mut String = x as *mut _; // pl011_receive starts
let y = &mut foo; // pl011_receive creates
a reference
// at this point, x becomes invalid
print!("{}", y);
// pl011_receive returns
// this is undefined behavior (shown by miri)
print!("{}", unsafe { &mut *x_ptr });
}
Honestly I don't see how I can provide a proof or explanation that is
more definitive than miri. If some specific documentation or
discussions gives you the perception that there is no undefined
behavior, I'm happy to check them out and provide an explanation in
that context. But otherwise, I don't think it's useful to keep
debating *whether* it is undefined behavior.
Paolo
[1] this is the other example I gave a few hours ago, which I'll copy
here for reference:
// MIRIFLAGS=-Zmiri-ignore-leaks cargo +nightly miri run
use std::mem::MaybeUninit;
struct S {
me: *mut S,
them: *mut S
}
impl S {
pub fn chardev_receive(&mut self) {
println!("in chardev_receive with &mut");
}
pub fn memory_write_good(&mut self) {
println!("in memory_write_good, calling qemu_chr_fe_accept_input()");
qemu_chr_fe_accept_input_good(self);
}
pub fn memory_write_bad(&mut self) {
println!("in memory_write_bad, calling qemu_chr_fe_accept_input()");
qemu_chr_fe_accept_input_bad(self);
}
}
fn qemu_chr_fe_accept_input_good(c: &S) {
// you can still go from *mut to &mut in _another_ instance of struct S
(unsafe { &mut *c.them }).chardev_receive();
}
fn qemu_chr_fe_accept_input_bad(c: &S) {
// you cannot go from *mut to &mut when it points to _this_ instance;
// creating the &mut that is passed to memory_write_bad() has
// effectively made that *mut unusable!
(unsafe { &mut *c.me }).chardev_receive();
}
fn main() {
let p: &mut MaybeUninit<S> = Box::leak(Box::new(MaybeUninit::uninit()));
let q: &mut MaybeUninit<S> = Box::leak(Box::new(MaybeUninit::uninit()));
unsafe {
let p_mut_ptr = p.as_mut_ptr();
let q_mut_ptr = q.as_mut_ptr();
*(&mut *p_mut_ptr) = S { me: p_mut_ptr, them: q_mut_ptr };
(&mut *p_mut_ptr).memory_write_bad();
(&mut *p_mut_ptr).memory_write_good();
}
}
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-25 15:15 ` Paolo Bonzini
@ 2024-07-26 7:12 ` Manos Pitsidianakis
2024-07-26 8:19 ` Paolo Bonzini
0 siblings, 1 reply; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-26 7:12 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Daniel P. Berrangé ,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé , Zhao Liu, Gustavo Romero,
Pierrick Bouvier, rowan.hart, Richard Henderson
On Thu, 25 Jul 2024 18:15, Paolo Bonzini <pbonzini@redhat.com> wrote:
>On Thu, Jul 25, 2024 at 4:48 PM Manos Pitsidianakis
><manos.pitsidianakis@linaro.org> wrote:
>> > pl011_receive (called by qemu_chr_fe_accept_input) creates a mutable
>> > reference that *overlaps* the lifetime of the outer reference created
>> > by pl011_read. This is undefined behavior. You're effectively writing:
>>
>> There is no overlap there, sorry. Once qemu_chr_fe_accept_input
>> returns, any references it created do not exist anymore.
>
>read |-------------|
>receive |-----|
>
>That's the overlap. Maybe you're thinking that the outer &mut "goes to
>sleep" and is reborn when qemu_chr_fe_accept_input() returns, but
>there's no such thing in the language.
There's no overlap, because the read scope is not live while receive is
active. References are linear types, when you give `&mut sth` as an
argument to a function call, you can model it in your mind as "giving
the mutual reference to the function call" and "receiving it back" when
it returns.
There'd be an overlap if qemu_chr_fe_accept_input got two mutual
references of the same memory location, such as calling foo(&mut self,
&mut self) with foo being `fn foo(a: &mut T, b: &mut T)`.
>
>You can do it within a function:
>
These examples you provide are not really equivalent.
>Honestly I don't see how I can provide a proof or explanation that is
>more definitive than miri. If some specific documentation or
>discussions gives you the perception that there is no undefined
>behavior, I'm happy to check them out and provide an explanation in
>that context. But otherwise, I don't think it's useful to keep
>debating *whether* it is undefined behavior.
Agreed! but thank you for taking the time to discuss this :)
Manos
PS: I will explain why your good/bad example behaves like it does:
>// MIRIFLAGS=-Zmiri-ignore-leaks cargo +nightly miri run
>use std::mem::MaybeUninit;
>
>struct S {
> me: *mut S,
> them: *mut S
>}
>
>impl S {
> pub fn chardev_receive(&mut self) {
> println!("in chardev_receive with &mut");
> }
>
> pub fn memory_write_good(&mut self) {
> println!("in memory_write_good, calling qemu_chr_fe_accept_input()");
> qemu_chr_fe_accept_input_good(self);
> }
>
> pub fn memory_write_bad(&mut self) {
> println!("in memory_write_bad, calling qemu_chr_fe_accept_input()");
> qemu_chr_fe_accept_input_bad(self);
> }
>}
>
>fn qemu_chr_fe_accept_input_good(c: &S) {
> // you can still go from *mut to &mut in _another_ instance of struct S
> (unsafe { &mut *c.them }).chardev_receive();
`them` is an uninitialized value, so you are dereferencing it and
passing a mutable reference to it, while
>}
>
>fn qemu_chr_fe_accept_input_bad(c: &S) {
> // you cannot go from *mut to &mut when it points to _this_ instance;
> // creating the &mut that is passed to memory_write_bad() has
> // effectively made that *mut unusable!
> (unsafe { &mut *c.me }).chardev_receive();
>}
`me` is the same memory location as `c`, which is passed as read only
(&S) here.
>
>fn main() {
> let p: &mut MaybeUninit<S> = Box::leak(Box::new(MaybeUninit::uninit()));
> let q: &mut MaybeUninit<S> = Box::leak(Box::new(MaybeUninit::uninit()));
>
> unsafe {
> let p_mut_ptr = p.as_mut_ptr();
> let q_mut_ptr = q.as_mut_ptr();
> *(&mut *p_mut_ptr) = S { me: p_mut_ptr, them: q_mut_ptr };
> (&mut *p_mut_ptr).memory_write_bad();
> (&mut *p_mut_ptr).memory_write_good();
> }
>}
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-26 7:12 ` Manos Pitsidianakis
@ 2024-07-26 8:19 ` Paolo Bonzini
2024-07-26 9:26 ` Manos Pitsidianakis
0 siblings, 1 reply; 35+ messages in thread
From: Paolo Bonzini @ 2024-07-26 8:19 UTC (permalink / raw)
To: Manos Pitsidianakis
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Daniel P. Berrangé,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé, Zhao Liu, Gustavo Romero,
Pierrick Bouvier, rowan.hart, Richard Henderson
On Fri, Jul 26, 2024 at 9:26 AM Manos Pitsidianakis
<manos.pitsidianakis@linaro.org> wrote:
>
> On Thu, 25 Jul 2024 18:15, Paolo Bonzini <pbonzini@redhat.com> wrote:
> >On Thu, Jul 25, 2024 at 4:48 PM Manos Pitsidianakis
> ><manos.pitsidianakis@linaro.org> wrote:
> >> > pl011_receive (called by qemu_chr_fe_accept_input) creates a mutable
> >> > reference that *overlaps* the lifetime of the outer reference created
> >> > by pl011_read. This is undefined behavior. You're effectively writing:
> >>
> >> There is no overlap there, sorry. Once qemu_chr_fe_accept_input
> >> returns, any references it created do not exist anymore.
> >
> >read |-------------|
> >receive |-----|
> >
> >That's the overlap. Maybe you're thinking that the outer &mut "goes to
> >sleep" and is reborn when qemu_chr_fe_accept_input() returns, but
> >there's no such thing in the language.
>
> There's no overlap, because the read scope is not live while receive is
> active. References are linear types, when you give `&mut sth` as an
> argument to a function call, you can model it in your mind as "giving
> the mutual reference to the function call" and "receiving it back" when
> it returns.
There is no such thing as "being active", the only exception being
when you create an &mut from *the same* &mut.
To clarify further: in principle, if you have code like this in pl011_read():
self.a = 42;
qemu_chr_accept_input(self.chardev);
return self.a
The compiler can optimize the second "self.a" to 42. The optimization
is incorrect if pl011_receive() overwrites "self.a". But that's not a
problem with the optimization, it's a problem with what
pl011_receive() does.
In other words, the *mere existence* of a &mut in an outer scope makes
it invalid to create *another* &mut pointing to the same memory in an
inner scope.
As I said, I don't see the point in discussing this more, and I'm not
going to unless you provide a clear pointer to documentation that
states the opposite.
Paolo
> There'd be an overlap if qemu_chr_fe_accept_input got two mutual
> references of the same memory location, such as calling foo(&mut self,
> &mut self) with foo being `fn foo(a: &mut T, b: &mut T)`.
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-26 8:19 ` Paolo Bonzini
@ 2024-07-26 9:26 ` Manos Pitsidianakis
2024-07-31 9:41 ` Manos Pitsidianakis
0 siblings, 1 reply; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-26 9:26 UTC (permalink / raw)
To: Paolo Bonzini
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Daniel P. Berrangé,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé, Zhao Liu, Gustavo Romero,
Pierrick Bouvier, rowan.hart, Richard Henderson
On Fri, 26 Jul 2024 at 11:19, Paolo Bonzini <pbonzini@redhat.com> wrote:
> As I said, I don't see the point in discussing this more, and I'm not
> going to unless you provide a clear pointer to documentation that
> states the opposite.
Same here.
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-26 9:26 ` Manos Pitsidianakis
@ 2024-07-31 9:41 ` Manos Pitsidianakis
2024-07-31 10:35 ` Paolo Bonzini
0 siblings, 1 reply; 35+ messages in thread
From: Manos Pitsidianakis @ 2024-07-31 9:41 UTC (permalink / raw)
To: Paolo Bonzini, qemu-devel
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Daniel P. Berrangé ,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé , Zhao Liu, Gustavo Romero,
Pierrick Bouvier, rowan.hart, Richard Henderson
On Fri, 26 Jul 2024 12:26, Manos Pitsidianakis <manos.pitsidianakis@linaro.org> wrote:
>On Fri, 26 Jul 2024 at 11:19, Paolo Bonzini <pbonzini@redhat.com> wrote:
>> As I said, I don't see the point in discussing this more, and I'm not
>> going to unless you provide a clear pointer to documentation that
>> states the opposite.
>
>Same here.
Next patch series version is taking more time than I expected because of
unrelated issues, plus I'm on PTO these days, so I am posting the
resolution (which I hope satisfies everyone) here early:
It's possible to refactor this code (and any other similar cases) to
prevent recursive mutable calls:
diff --git a/rust/hw/char/pl011/src/device.rs
b/rust/hw/char/pl011/src/device.rs
index 3643b7bdee..449930e34e 100644
--- a/rust/hw/char/pl011/src/device.rs
+++ b/rust/hw/char/pl011/src/device.rs
@@ -104,10 +127,14 @@ pub fn init(&mut self) {
}
}
- pub fn read(&mut self, offset: hwaddr, _size: core::ffi::c_uint) -> u64 {
+ pub fn read(
+ &mut self,
+ offset: hwaddr,
+ _size: core::ffi::c_uint,
+ ) -> std::ops::ControlFlow<u64, u64> {
use RegisterOffset::*;
- match RegisterOffset::try_from(offset) {
+ std::ops::ControlFlow::Break(match RegisterOffset::try_from(offset) {
Err(v) if (0x3f8..0x400).contains(&v) => {
u64::from(PL011_ID_ARM[((offset - 0xfe0) >> 2) as usize])
}
@@ -134,10 +161,8 @@ pub fn read(&mut self, offset: hwaddr, _size: core::ffi::c_uint) -> u64 {
// Update error bits.
self.receive_status_error_clear = c.to_be_bytes()[3].into();
self.update();
- // SAFETY: self.char_backend is a valid CharBackend instance after it's been
- // initialized in realize().
- unsafe { qemu_chr_fe_accept_input(&mut self.char_backend) };
- c.into()
+ // Must call qemu_chr_fe_accept_input, so return Continue:
+ return std::ops::ControlFlow::Continue(c.into());
}
Ok(RSR) => u8::from(self.receive_status_error_clear).into(),
Ok(FR) => u16::from(self.flags).into(),
@@ -159,7 +184,7 @@ pub fn read(&mut self, offset: hwaddr, _size: core::ffi::c_uint) -> u64 {
0
}
Ok(DMACR) => self.dmacr.into(),
- }
+ })
}
pub fn write(&mut self, offset: hwaddr, value: u64) {
diff --git a/rust/hw/char/pl011/src/memory_ops.rs b/rust/hw/char/pl011/src/memory_ops.rs
index 6144d28586..5e185b7cd7 100644
--- a/rust/hw/char/pl011/src/memory_ops.rs
+++ b/rust/hw/char/pl011/src/memory_ops.rs
@@ -29,7 +29,18 @@
) -> u64 {
assert!(!opaque.is_null());
let mut state = NonNull::new_unchecked(opaque.cast::<PL011State>());
- state.as_mut().read(addr, size)
+ let val = state.as_mut().read(addr, size);
+ match val {
+ std::ops::ControlFlow::Break(val) => val,
+ std::ops::ControlFlow::Continue(val) => {
+ // SAFETY: self.char_backend is a valid CharBackend instance after it's been
+ // initialized in realize().
+ let cb_ptr = core::ptr::addr_of_mut!(state.as_mut().char_backend);
+ unsafe { qemu_chr_fe_accept_input(cb_ptr) };
+
+ val
+ }
+ }
}
When we iterate the APIs further we will find better idiomatic solutions
that do not rely on devices themselves to do this kind of stuff, but
offer interfaces from the `qemu_api` library crate.
Manos
^ permalink raw reply related [flat|nested] 35+ messages in thread
* Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
2024-07-31 9:41 ` Manos Pitsidianakis
@ 2024-07-31 10:35 ` Paolo Bonzini
0 siblings, 0 replies; 35+ messages in thread
From: Paolo Bonzini @ 2024-07-31 10:35 UTC (permalink / raw)
To: Manos Pitsidianakis
Cc: qemu-devel, Stefan Hajnoczi, Mads Ynddal, Peter Maydell,
Alex Benné e, Daniel P. Berrangé,
Marc-André Lureau, Thomas Huth, Markus Armbruster,
Philippe Mathieu-Daudé, Zhao Liu, Gustavo Romero,
Pierrick Bouvier, rowan.hart, Richard Henderson
On Wed, Jul 31, 2024 at 11:50 AM Manos Pitsidianakis
<manos.pitsidianakis@linaro.org> wrote:
>
> On Fri, 26 Jul 2024 12:26, Manos Pitsidianakis <manos.pitsidianakis@linaro.org> wrote:
> >On Fri, 26 Jul 2024 at 11:19, Paolo Bonzini <pbonzini@redhat.com> wrote:
> >> As I said, I don't see the point in discussing this more, and I'm not
> >> going to unless you provide a clear pointer to documentation that
> >> states the opposite.
> >
> >Same here.
>
> Next patch series version is taking more time than I expected because of
> unrelated issues, plus I'm on PTO these days, so I am posting the
> resolution (which I hope satisfies everyone) here early:
I would be okay with just a TODO comment (I think we all agree that
the issue is theoretical), but this one's okay too if you prefer.
Paolo
^ permalink raw reply [flat|nested] 35+ messages in thread
end of thread, other threads:[~2024-07-31 10:35 UTC | newest]
Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-22 11:43 [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 1/8] build-sys: Add rust feature option Manos Pitsidianakis
2024-07-23 6:37 ` Zhao Liu
2024-07-23 10:13 ` Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 2/8] build deps: update lcitool to include rust bits Manos Pitsidianakis
2024-07-23 8:31 ` Richard Henderson
2024-07-23 10:11 ` Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 3/8] CI: Add build-system-rust-debian job Manos Pitsidianakis
2024-07-23 8:32 ` Richard Henderson
2024-07-23 8:39 ` Daniel P. Berrangé
2024-07-23 10:06 ` Manos Pitsidianakis
2024-07-23 10:11 ` Daniel P. Berrangé
2024-07-23 10:24 ` Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 4/8] rust: add bindgen step as a meson dependency Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 5/8] .gitattributes: add Rust diff and merge attributes Manos Pitsidianakis
2024-07-23 8:38 ` Zhao Liu
2024-07-22 11:43 ` [RFC PATCH v5 6/8] rust: add crate to expose bindings and interfaces Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 7/8] rust: add PL011 device model Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 8/8] rust/pl011: vendor dependencies Manos Pitsidianakis
2024-07-23 8:37 ` Zhao Liu
2024-07-23 10:19 ` Manos Pitsidianakis
2024-07-23 15:07 ` [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Paolo Bonzini
2024-07-24 9:14 ` Manos Pitsidianakis
2024-07-24 10:34 ` Paolo Bonzini
2024-07-25 5:47 ` Manos Pitsidianakis
2024-07-25 9:50 ` Paolo Bonzini
2024-07-25 10:02 ` Manos Pitsidianakis
2024-07-25 11:19 ` Paolo Bonzini
2024-07-25 14:48 ` Manos Pitsidianakis
2024-07-25 15:15 ` Paolo Bonzini
2024-07-26 7:12 ` Manos Pitsidianakis
2024-07-26 8:19 ` Paolo Bonzini
2024-07-26 9:26 ` Manos Pitsidianakis
2024-07-31 9:41 ` Manos Pitsidianakis
2024-07-31 10:35 ` Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).