[
  {
    "path": ".bazelignore",
    "content": "buck-out/\ntarget/\ntools/buck/buck2/\n"
  },
  {
    "path": ".bazelrc",
    "content": "###############################################################################\n## Bazel Configuration Flags\n##\n## `.bazelrc` is a Bazel configuration file.\n## https://bazel.build/docs/best-practices#bazelrc-file\n###############################################################################\n\nbuild --enable_platform_specific_config\nbuild:linux --@rules_rust//:extra_rustc_flags=-Clink-arg=-fuse-ld=lld\nbuild:linux --cxxopt=-std=c++17\nbuild:macos --cxxopt=-std=c++17\n\n###############################################################################\n## Custom user flags\n##\n## This should always be the last thing in the `.bazelrc` file to ensure\n## consistent behavior when setting flags in that file as `.bazelrc` files are\n## evaluated top to bottom.\n###############################################################################\n\ntry-import %workspace%/user.bazelrc\n"
  },
  {
    "path": ".bcr/README.md",
    "content": "# Bazel Central Registry\n\nWhen the ruleset is released, we want it to be published to the\nBazel Central Registry automatically:\n<https://registry.bazel.build>\n\nThis folder contains configuration files to automate the publish step.\nSee <https://github.com/bazel-contrib/publish-to-bcr/blob/main/templates/README.md>\nfor authoritative documentation about these files.\n"
  },
  {
    "path": ".bcr/config.yml",
    "content": "fixedReleaser:\n  login: dtolnay\n  email: dtolnay@gmail.com\n"
  },
  {
    "path": ".bcr/metadata.template.json",
    "content": "{\n  \"homepage\": \"https://cxx.rs\",\n  \"maintainers\": [\n    {\n      \"github\": \"dtolnay\",\n      \"github_user_id\": 1940490,\n      \"email\": \"dtolnay@gmail.com\",\n      \"name\": \"David Tolnay\"\n    }\n  ],\n  \"repository\": [\n    \"github:dtolnay/cxx\"\n  ],\n  \"versions\": [],\n  \"yanked_versions\": {}\n}\n"
  },
  {
    "path": ".bcr/presubmit.yml",
    "content": "matrix:\n  platform:\n    - macos_arm64\n    - ubuntu2404\n    - windows\n  bazel: [8.x, 9.x]\ntasks:\n  verify_targets:\n    name: Verify build targets\n    platform: ${{ platform }}\n    bazel: ${{ bazel }}\n    build_targets:\n      - '@cxx.rs//...'\n    test_targets:\n      - '@cxx.rs//...'\n"
  },
  {
    "path": ".bcr/source.template.json",
    "content": "{\n  \"integrity\": \"\",\n  \"strip_prefix\": \"{REPO}-{VERSION}\",\n  \"url\": \"https://github.com/{OWNER}/{REPO}/releases/download/{TAG}/{REPO}-{VERSION}.tar.gz\"\n}\n"
  },
  {
    "path": ".buckconfig",
    "content": "[cells]\nroot = .\nprelude = tools/buck/prelude\ntoolchains = tools/buck/toolchains\nnone = none\n\n[external_cells]\nprelude = bundled\n\n[cell_aliases]\nconfig = prelude\nfbcode = none\nfbsource = none\n\n[project]\n# Hide BUCK files under target/package/ from `buck build ...`. Otherwise:\n#   $ buck build ...\n#   //target/package/cxx-0.3.0/tests:ffi references non-existing file or directory 'target/package/cxx-0.3.0/tests/ffi/lib.rs'\n#\n# Also hide some Bazel-managed directories that contain symlinks to the repo root.\nignore = \\\n    .git, \\\n    bazel-bin, \\\n    bazel-cxx, \\\n    bazel-out, \\\n    bazel-testlogs, \\\n    target\n\n[parser]\ntarget_platform_detector_spec = target:root//...->prelude//platforms:default\n"
  },
  {
    "path": ".buckroot",
    "content": ""
  },
  {
    "path": ".clang-format",
    "content": "AlwaysBreakTemplateDeclarations: true\nMaxEmptyLinesToKeep: 3\nReflowComments: false\n"
  },
  {
    "path": ".clang-tidy",
    "content": "Checks:\n  clang-analyzer-*,\n  clang-diagnostic-*,\n  cppcoreguidelines-*,\n  modernize-*,\n  -cppcoreguidelines-avoid-const-or-ref-data-members,\n  -cppcoreguidelines-macro-usage,\n  -cppcoreguidelines-owning-memory,\n  -cppcoreguidelines-pro-bounds-pointer-arithmetic,\n  -cppcoreguidelines-pro-type-const-cast,\n  -cppcoreguidelines-pro-type-member-init,\n  -cppcoreguidelines-pro-type-reinterpret-cast,\n  -cppcoreguidelines-special-member-functions,\n  -modernize-concat-nested-namespaces,\n  -modernize-return-braced-init-list,\n  -modernize-type-traits,\n  -modernize-use-constraints,\n  -modernize-use-nodiscard,\n  -modernize-use-ranges,\n  -modernize-use-trailing-return-type,\nHeaderFilterRegex: cxx\\.h\n"
  },
  {
    "path": ".devcontainer/Dockerfile",
    "content": "FROM dtolnay/devcontainer:latest\n"
  },
  {
    "path": ".devcontainer/README.md",
    "content": "This directory contains the container setup used when developing CXX inside of\nGitHub [Codespaces].\n\n[Codespaces]: https://github.com/features/codespaces\n"
  },
  {
    "path": ".devcontainer/build.Dockerfile",
    "content": "FROM mcr.microsoft.com/devcontainers/rust:bookworm\n\nRUN apt-get update \\\n    && export DEBIAN_FRONTEND=noninteractive \\\n    && apt-get -y install --no-install-recommends clang lld zstd \\\n    && apt-get clean \\\n    && rm -rf /var/lib/apt/lists/* \\\n    && wget -q -O /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64 \\\n    && wget -q -O /tmp/buck.zst https://github.com/facebook/buck2/releases/download/latest/buck2-x86_64-unknown-linux-gnu.zst \\\n    && wget -q -O /usr/local/bin/buildifier https://github.com/bazelbuild/buildtools/releases/latest/download/buildifier-linux-amd64 \\\n    && unzstd /tmp/buck.zst -o /usr/local/bin/buck \\\n    && chmod +x /usr/local/bin/bazel /usr/local/bin/buck /usr/local/bin/buildifier \\\n    && rm /tmp/buck.zst \\\n    && rustup component add rust-analyzer rust-src\n"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "content": "{\n    \"name\": \"Rust\",\n    \"build\": {\n        \"dockerfile\": \"Dockerfile\"\n    },\n    \"runArgs\": [\"--cap-add=SYS_PTRACE\", \"--security-opt\", \"seccomp=unconfined\"],\n    \"settings\": {\n        \"terminal.integrated.shell.linux\": \"/bin/bash\",\n        \"lldb.executable\": \"/usr/bin/lldb\",\n        \"files.watcherExclude\": {\n            \"**/target/**\": true\n        }\n    },\n    \"extensions\": [\n        \"BazelBuild.vscode-bazel\",\n        \"ms-vscode.cpptools\",\n        \"rust-lang.rust-analyzer\",\n        \"vadimcn.vscode-lldb\"\n    ]\n}\n"
  },
  {
    "path": ".gitattributes",
    "content": "/MODULE.bazel.lock linguist-generated\n/third-party/BUCK linguist-generated\n/third-party/bazel/** linguist-generated\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: dtolnay\n"
  },
  {
    "path": ".github/workflows/buck2.yml",
    "content": "name: Buck2\n\non:\n  push:\n  workflow_dispatch:\n  schedule: [cron: \"40 1,13 * * *\"]\n\npermissions:\n  contents: read\n\njobs:\n  buck2:\n    name: Buck2 on ${{matrix.os == 'ubuntu' && 'Linux' || matrix.os == 'macos' && 'macOS' || matrix.os == 'windows' && 'Windows' || '???'}}\n    runs-on: ${{matrix.os}}-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        os: [ubuntu, macos, windows]\n    timeout-minutes: 45\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          components: rust-src\n      - uses: dtolnay/install-buck2@latest\n      - run: buck2 run demo\n      - run: buck2 build ...\n      - run: buck2 test ...\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  push:\n  pull_request:\n  workflow_dispatch:\n  schedule: [cron: \"40 1 * * *\"]\n\npermissions:\n  contents: read\n\njobs:\n  pre_ci:\n    uses: dtolnay/.github/.github/workflows/pre_ci.yml@master\n\n  test:\n    name: ${{matrix.name || format('Rust {0}', matrix.rust)}}\n    needs: pre_ci\n    if: needs.pre_ci.outputs.continue\n    runs-on: ${{matrix.runs-on || format('{0}-latest', matrix.os)}}\n    strategy:\n      fail-fast: false\n      matrix:\n        rust: [nightly, beta, stable, 1.85.0]\n        os: [ubuntu]\n        cc: [g++]\n        flags: ['']\n        include:\n          - name: Cargo on macOS\n            rust: nightly\n            os: macos\n          - name: Cargo on Windows (msvc)\n            rust: nightly-x86_64-pc-windows-msvc\n            os: windows\n          - name: Clang\n            rust: nightly\n            os: ubuntu\n            cc: clang++\n            flags: -std=c++20\n          - name: Clang (no exceptions)\n            rust: nightly\n            os: ubuntu\n            cc: clang++\n            flags: -std=c++20 -fno-exceptions\n          - name: C++14 on Linux\n            rust: nightly\n            os: ubuntu\n            cc: g++\n            flags: -std=c++14\n          - name: C++14 on macOS\n            rust: nightly\n            os: macos\n            flags: -std=c++14\n          - name: C++14 on Windows\n            rust: nightly-x86_64-pc-windows-msvc\n            os: windows\n            flags: /std:c++14\n          - name: C++17 on Linux\n            rust: nightly\n            os: ubuntu\n            cc: g++\n            flags: -std=c++17\n          - name: C++17 on macOS\n            rust: nightly\n            os: macos\n            flags: -std=c++17\n          - name: C++17 on Windows\n            rust: nightly-x86_64-pc-windows-msvc\n            os: windows\n            flags: /std:c++17\n          - name: C++20 on Linux\n            rust: nightly\n            os: ubuntu\n            cc: g++\n            flags: -std=c++20\n          - name: C++20 on macOS\n            rust: nightly\n            os: macos\n            flags: -std=c++20\n            runs-on: macos-15\n          - name: C++20 on Windows\n            rust: nightly-x86_64-pc-windows-msvc\n            os: windows\n            flags: /std:c++20\n          - name: Pedantic\n            rust: nightly\n            os: ubuntu\n            cc: clang++\n            flags:\n              -Weverything\n              -Wno-c++98-compat\n              -Wno-c++98-compat-pedantic\n              -Wno-c++20-compat\n              -Wno-implicit-int-conversion\n              -Wno-missing-prototypes\n              -Wno-padded\n              -Wno-sign-conversion\n              -Wno-undefined-func-template\n              -Wno-unsafe-buffer-usage\n              -Wno-unused-macros\n    env:\n      CXX: ${{matrix.cc}}\n      CXXFLAGS: ${{matrix.flags}} ${{matrix.os == 'windows' && '/EHsc /WX' || '-Werror -Wall -Wpedantic'}}\n      RUSTFLAGS: --cfg deny_warnings -Dwarnings\n    timeout-minutes: 45\n    steps:\n      - name: Enable symlinks (windows)\n        if: matrix.os == 'windows'\n        run: git config --global core.symlinks true\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@master\n        with:\n          toolchain: ${{matrix.rust}}\n          components: rust-src\n      - name: Determine test suite subset\n        # Our Windows and macOS jobs are the longest running, so exclude the\n        # relatively slow compiletest from them to speed up end-to-end CI time,\n        # except during cron builds when no human is presumably waiting on the\n        # build. The extra coverage is not particularly valuable and we can\n        # still ensure the test is kept passing on the basis of the scheduled\n        # builds.\n        run: |\n          echo RUSTFLAGS=$RUSTFLAGS >> $GITHUB_ENV\n          echo exclude=--exclude cxx-test-suite >> $GITHUB_OUTPUT\n        env:\n          RUSTFLAGS: ${{env.RUSTFLAGS}} ${{matrix.os != 'ubuntu' && github.event_name != 'schedule' && '--cfg skip_ui_tests' || ''}}\n        id: testsuite\n        shell: bash\n      - name: Ignore macOS linker warning\n        run: echo RUSTFLAGS=${RUSTFLAGS}\\ -Alinker_messages >> $GITHUB_ENV\n        if: matrix.os == 'macos'\n      - run: cargo run --manifest-path demo/Cargo.toml\n      - run: cargo test --workspace ${{steps.testsuite.outputs.exclude}}\n        if: contains(matrix.flags, '-fno-exceptions') == false\n      - run: cargo check --no-default-features --features alloc\n        env:\n          RUSTFLAGS: --cfg compile_error_if_std ${{env.RUSTFLAGS}}\n      - run: cargo check --no-default-features\n        env:\n          RUSTFLAGS: --cfg compile_error_if_alloc --cfg cxx_experimental_no_alloc ${{env.RUSTFLAGS}}\n      - uses: actions/upload-artifact@v6\n        if: matrix.os == 'ubuntu' && matrix.rust == 'nightly' && matrix.cc == '' && matrix.flags == '' && always()\n        with:\n          name: Cargo.lock\n          path: Cargo.lock\n        continue-on-error: true\n\n  wasi:\n    name: WebAssembly\n    runs-on: ubuntu-latest\n    timeout-minutes: 45\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@nightly\n        with:\n          targets: wasm32-wasip1\n          components: rust-src\n      - uses: dtolnay/install@wasmtime-cli\n      - run: curl https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-27/wasi-sdk-27.0-x86_64-linux.tar.gz --location --silent --show-error --fail --retry 2 --output ${{runner.temp}}/wasi-sdk-27.0-x86_64-linux.tar.gz\n      - run: tar xf ${{runner.temp}}/wasi-sdk-27.0-x86_64-linux.tar.gz -C ${{runner.temp}}\n      - run: cargo build --target=wasm32-wasip1 --manifest-path=demo/Cargo.toml --release\n          --config='target.wasm32-wasip1.linker=\"${{runner.temp}}/wasi-sdk-27.0-x86_64-linux/bin/lld\"'\n          --config='target.wasm32-wasip1.rustflags=[\"-Clink-args=-L${{runner.temp}}/wasi-sdk-27.0-x86_64-linux/share/wasi-sysroot/lib/wasm32-wasip1\", \"-Clink-args=-lc++abi\"]'\n        env:\n          CXX: ${{runner.temp}}/wasi-sdk-27.0-x86_64-linux/bin/clang++\n          CXXFLAGS: --sysroot=${{runner.temp}}/wasi-sdk-27.0-x86_64-linux/share/wasi-sysroot\n      - run: wasmtime target/wasm32-wasip1/release/demo.wasm\n\n  emscripten:\n    name: Emscripten\n    needs: pre_ci\n    if: needs.pre_ci.outputs.continue\n    runs-on: ubuntu-latest\n    timeout-minutes: 45\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@nightly\n        with:\n          targets: wasm32-unknown-emscripten\n          components: rust-src\n      - name: Disable initramfs update\n        run: sudo sed -i 's/^update_initramfs=yes$/update_initramfs=no/' /etc/initramfs-tools/update-initramfs.conf\n      - name: Disable man-db update\n        run: sudo rm -f /var/lib/man-db/auto-update\n      - name: Install emscripten\n        run: sudo apt-get install emscripten\n      - run: cargo build --target=wasm32-unknown-emscripten --manifest-path=demo/Cargo.toml --release -Zbuild-std\n        env:\n          RUSTFLAGS: -Clink-arg=--emrun ${{env.RUSTFLAGS}}\n      - name: Create demo.html for demo.js\n        run: echo '<!DOCTYPE html><script src=\"demo.js\"></script>' > target/wasm32-unknown-emscripten/release/demo.html\n      - name: Install firefox\n        run: sudo snap install firefox\n      - run: emrun target/wasm32-unknown-emscripten/release/demo.html\n          --browser=/snap/firefox/current/usr/lib/firefox/firefox\n          --browser_args=-headless\n          --safe_firefox_profile\n          --log_stdout=${{runner.temp}}/demo.log\n          --timeout=60\n          --kill_exit\n      - run: cat ${{runner.temp}}/demo.log\n      - run: grep --silent blobid ${{runner.temp}}/demo.log\n\n  reindeer:\n    name: Reindeer\n    runs-on: ubuntu-latest\n    if: github.event_name != 'pull_request'\n    timeout-minutes: 45\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          components: rust-src\n      - uses: dtolnay/install@reindeer\n      - run: reindeer buckify\n        working-directory: third-party\n      - name: Check reindeer-generated BUCK file up to date\n        run: git diff --exit-code\n\n  bazel:\n    name: Bazel on ${{matrix.os == 'ubuntu' && 'Linux' || matrix.os == 'macos' && 'macOS' || matrix.os == 'windows' && 'Windows' || '???'}}\n    runs-on: ${{matrix.os}}-latest\n    if: github.event_name != 'pull_request'\n    strategy:\n      fail-fast: false\n      matrix:\n        os: [ubuntu, macos, windows]\n    timeout-minutes: 45\n    steps:\n      - uses: actions/checkout@v6\n      - name: Disable initramfs update\n        run: sudo sed -i 's/^update_initramfs=yes$/update_initramfs=no/' /etc/initramfs-tools/update-initramfs.conf\n        if: matrix.os == 'ubuntu'\n      - name: Disable man-db update\n        run: sudo rm -f /var/lib/man-db/auto-update\n        if: matrix.os == 'ubuntu'\n      - name: Install lld\n        run: sudo apt-get install lld\n        if: matrix.os == 'ubuntu'\n      - name: Set bazelrc for Windows\n        run: echo \"startup --output_user_root=D:/bzl\" > user.bazelrc\n        if: matrix.os == 'windows'\n      - run: bazel --version\n      - run: bazel run demo --verbose_failures --noshow_progress ${{matrix.os == 'macos' && '--xcode_version_config=tools/bazel:github_actions_xcodes' || ''}}\n      - run: bazel test ... --verbose_failures --noshow_progress ${{matrix.os == 'macos' && '--xcode_version_config=tools/bazel:github_actions_xcodes' || ''}}\n      - name: Check MODULE.bazel.lock up to date\n        run: git diff --exit-code\n      - run: bazel run //third-party:vendor\n        if: matrix.os == 'ubuntu' || matrix.os == 'macos'\n      - name: Check third-party/bazel up to date\n        run: git diff --exit-code\n        if: matrix.os == 'ubuntu' || matrix.os == 'macos'\n\n  minimal:\n    name: Minimal versions\n    needs: pre_ci\n    if: needs.pre_ci.outputs.continue\n    runs-on: ubuntu-latest\n    timeout-minutes: 45\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@nightly\n      - run: cargo generate-lockfile -Z minimal-versions\n      - run: cargo check --locked --workspace\n\n  doc:\n    name: Documentation\n    needs: pre_ci\n    if: needs.pre_ci.outputs.continue\n    runs-on: ubuntu-latest\n    timeout-minutes: 45\n    env:\n      RUSTDOCFLAGS: -Dwarnings\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@nightly\n        with:\n          components: rust-src\n      - uses: dtolnay/install@cargo-docs-rs\n      - run: cargo docs-rs\n      - run: cargo docs-rs -p cxx-build\n      - run: cargo docs-rs -p cxx-gen\n      - run: cargo docs-rs -p cxxbridge-flags\n      - run: cargo docs-rs -p cxxbridge-macro\n\n  clippy:\n    name: Clippy\n    runs-on: ubuntu-latest\n    if: github.event_name != 'pull_request'\n    timeout-minutes: 45\n    env:\n      RUSTFLAGS: -Dwarnings\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@nightly\n        with:\n          components: clippy, rust-src\n      - run: cargo clippy --workspace --tests --exclude demo -- -Dclippy::all -Dclippy::pedantic\n      - run: cargo clippy --manifest-path demo/Cargo.toml -- -Dclippy::all\n\n  clang-tidy:\n    name: Clang Tidy\n    runs-on: ubuntu-latest\n    if: github.event_name != 'pull_request'\n    timeout-minutes: 45\n    steps:\n      - uses: actions/checkout@v6\n      - name: Disable initramfs update\n        run: sudo sed -i 's/^update_initramfs=yes$/update_initramfs=no/' /etc/initramfs-tools/update-initramfs.conf\n      - name: Disable man-db update\n        run: sudo rm -f /var/lib/man-db/auto-update\n      - name: Install clang-tidy\n        run: sudo apt-get update && sudo apt-get install clang-tidy-20\n      - name: Run clang-tidy\n        run: clang-tidy-20 src/cxx.cc --warnings-as-errors=*\n\n  eslint:\n    name: ESLint\n    runs-on: ubuntu-latest\n    if: github.event_name != 'pull_request'\n    timeout-minutes: 45\n    steps:\n      - uses: actions/checkout@v6\n      - run: npm install\n        working-directory: book\n      - run: npx eslint\n        working-directory: book\n\n  outdated:\n    name: Outdated\n    runs-on: ubuntu-latest\n    if: github.event_name != 'pull_request'\n    timeout-minutes: 45\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/rust-toolchain@stable\n      - uses: dtolnay/install@cargo-outdated\n      - run: cargo outdated --workspace --exit-code 1\n"
  },
  {
    "path": ".github/workflows/install.yml",
    "content": "name: Install\n\non:\n  workflow_dispatch:\n  schedule: [cron: \"40 1 * * *\"]\n  push: {tags: ['*']}\n\npermissions: {}\n\nenv:\n  RUSTFLAGS: -Dwarnings\n\njobs:\n  install:\n    name: Install\n    uses: dtolnay/.github/.github/workflows/check_install.yml@master\n    with:\n      crate: cxxbridge-cmd\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\non:\n  release:\n    types: [released]\n\npermissions:\n  attestations: write\n  contents: write\n  id-token: write\n\njobs:\n  upload:\n    uses: dtolnay/.github/.github/workflows/release_tgz.yml@master\n\n  publish-to-bcr:\n    needs: upload\n    uses: bazel-contrib/publish-to-bcr/.github/workflows/publish.yaml@92ae43f10e552721931f98b61fe5506bbdf32ce6\n    with:\n      tag_name: ${{github.event.release.tag_name}}\n      registry_fork: dtolnay-contrib/bazel-central-registry\n      attest: false\n    secrets:\n      publish_token: ${{secrets.PUBLISH_TOKEN}}\n"
  },
  {
    "path": ".github/workflows/site.yml",
    "content": "name: Deploy\n\non:\n  push:\n    branches:\n      - master\n    paths:\n      - book/**\n      - .github/workflows/site.yml\n  workflow_dispatch:\n\njobs:\n  deploy:\n    name: Deploy\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n    timeout-minutes: 30\n    steps:\n      - uses: actions/checkout@v6\n      - uses: dtolnay/install@mdbook\n      - run: mdbook --version\n\n      - name: Build\n        run: book/build.sh\n\n      - name: Push to gh-pages\n        working-directory: book/build\n        run: |\n          REV=$(git rev-parse --short HEAD)\n          git init\n          git remote add upstream https://x-access-token:${{secrets.GITHUB_TOKEN}}@github.com/dtolnay/cxx\n          git config user.name \"CXX\"\n          git config user.email \"dtolnay+cxx@gmail.com\"\n          git add -A .\n          git commit -qm \"Website @ ${{github.repository}}@${REV}\"\n          git push -q upstream HEAD:refs/heads/gh-pages --force\n"
  },
  {
    "path": ".gitignore",
    "content": "/.buckconfig.d/\n/.buckconfig.local\n/.buckd\n/bazel-bin\n/bazel-cxx\n/bazel-out\n/bazel-testlogs\n/user.bazelrc\n/buck-out\n/expand.cc\n/expand.rs\n/target/\n/Cargo.lock\n"
  },
  {
    "path": ".vscode/README.md",
    "content": "VS Code actions and configuration. Applicable when developing CXX inside of\nGitHub [Codespaces].\n\n[Codespaces]: https://github.com/features/codespaces\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"Run cxx demo\",\n            \"type\": \"lldb\",\n            \"request\": \"launch\",\n            \"cargo\": {\n                \"args\": [\"build\", \"--manifest-path\", \"demo/Cargo.toml\"],\n                \"filter\": {\n                    \"name\": \"demo\",\n                    \"kind\": \"bin\"\n                }\n            }\n        },\n        {\n            \"name\": \"Debug cargo tests\",\n            \"type\": \"lldb\",\n            \"request\": \"launch\",\n            \"cargo\": {\n                \"args\": [\"test\", \"--no-run\"],\n                \"filter\": {\n                    \"name\": \"test\",\n                    \"kind\": \"test\"\n                }\n            }\n        }\n    ]\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n    \"search.exclude\": {\n        \"**/target\": true\n    }\n}\n"
  },
  {
    "path": ".vscode/tasks.json",
    "content": "{\n    \"version\": \"2.0.0\",\n    \"tasks\": [\n        {\n            \"label\": \"Cargo test\",\n            \"type\": \"shell\",\n            \"command\": \"cargo test\",\n            \"group\": \"test\"\n        },\n        {\n            \"label\": \"Bazel test\",\n            \"type\": \"shell\",\n            \"command\": \"bazel test ...\",\n            \"group\": \"test\",\n            \"dependsOn\": [\"Vendor\"]\n        },\n        {\n            \"label\": \"Buck test\",\n            \"type\": \"shell\",\n            \"command\": \"buck test ...\",\n            \"group\": \"test\",\n            \"dependsOn\": [\"Vendor\"]\n        },\n        {\n            \"label\": \"Vendor\",\n            \"type\": \"shell\",\n            \"command\": \"cp third-party/Cargo.lock . && cargo vendor --versioned-dirs --locked third-party/vendor\"\n        }\n    ]\n}\n"
  },
  {
    "path": ".watchmanconfig",
    "content": "{\n  \"ignore_dirs\": [\"buck-out\"]\n}\n"
  },
  {
    "path": "BUCK",
    "content": "load(\":Cargo.toml\", cargo_toml = \"value\")\n\nCARGO_PKG_VERSION_PATCH = cargo_toml[\"package\"][\"version\"].split(\".\")[2]\n\nrust_library(\n    name = \"cxx\",\n    srcs = glob([\"src/**/*.rs\"]),\n    doc_deps = [\n        \":cxx-build\",\n    ],\n    edition = \"2021\",\n    features = [\n        \"alloc\",\n        \"std\",\n    ],\n    visibility = [\"PUBLIC\"],\n    deps = [\n        \":core\",\n        \":cxxbridge-macro\",\n        \"//third-party:foldhash\",\n    ],\n)\n\nalias(\n    name = \"codegen\",\n    actual = \":cxxbridge\",\n    visibility = [\"PUBLIC\"],\n)\n\nrust_binary(\n    name = \"cxxbridge\",\n    srcs = glob([\n        \"gen/cmd/src/**/*.rs\",\n        \"gen/src/builtin/*.h\",\n    ]) + [\n        \"gen/cmd/src/gen\",\n        \"gen/cmd/src/syntax\",\n    ],\n    edition = \"2021\",\n    env = {\n        \"CARGO_PKG_VERSION_PATCH\": CARGO_PKG_VERSION_PATCH,\n    },\n    deps = [\n        \"//third-party:clap\",\n        \"//third-party:codespan-reporting\",\n        \"//third-party:indexmap\",\n        \"//third-party:proc-macro2\",\n        \"//third-party:quote\",\n        \"//third-party:syn\",\n    ],\n)\n\ncxx_library(\n    name = \"core\",\n    srcs = [\"src/cxx.cc\"],\n    exported_headers = {\n        \"cxx.h\": \"include/cxx.h\",\n    },\n    header_namespace = \"rust\",\n    preferred_linkage = \"static\",\n    visibility = [\"PUBLIC\"],\n)\n\nrust_library(\n    name = \"cxxbridge-macro\",\n    srcs = glob([\"macro/src/**/*.rs\"]) + [\"macro/src/syntax\"],\n    doctests = False,\n    edition = \"2021\",\n    env = {\n        \"CARGO_PKG_VERSION_PATCH\": CARGO_PKG_VERSION_PATCH,\n    },\n    proc_macro = True,\n    deps = [\n        \"//third-party:indexmap\",\n        \"//third-party:proc-macro2\",\n        \"//third-party:quote\",\n        \"//third-party:rustversion\",\n        \"//third-party:syn\",\n    ],\n)\n\nrust_library(\n    name = \"cxx-build\",\n    srcs = glob([\n        \"gen/build/src/**/*.rs\",\n        \"gen/src/builtin/*.h\",\n    ]) + [\n        \"gen/build/src/gen\",\n        \"gen/build/src/syntax\",\n    ],\n    doctests = False,\n    edition = \"2021\",\n    env = {\n        \"CARGO_PKG_VERSION_PATCH\": CARGO_PKG_VERSION_PATCH,\n    },\n    deps = [\n        \"//third-party:cc\",\n        \"//third-party:codespan-reporting\",\n        \"//third-party:indexmap\",\n        \"//third-party:proc-macro2\",\n        \"//third-party:quote\",\n        \"//third-party:scratch\",\n        \"//third-party:syn\",\n    ],\n)\n\nrust_library(\n    name = \"cxx-gen\",\n    srcs = glob([\n        \"gen/lib/src/**/*.rs\",\n        \"gen/src/builtin/*.h\",\n    ]) + [\n        \"gen/lib/src/gen\",\n        \"gen/lib/src/syntax\",\n    ],\n    edition = \"2021\",\n    env = {\n        \"CARGO_PKG_VERSION_PATCH\": CARGO_PKG_VERSION_PATCH,\n    },\n    visibility = [\"PUBLIC\"],\n    deps = [\n        \"//third-party:cc\",\n        \"//third-party:codespan-reporting\",\n        \"//third-party:indexmap\",\n        \"//third-party:proc-macro2\",\n        \"//third-party:quote\",\n        \"//third-party:syn\",\n    ],\n)\n"
  },
  {
    "path": "BUILD.bazel",
    "content": "load(\"@rules_cc//cc:defs.bzl\", \"cc_library\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_binary\", \"rust_library\", \"rust_proc_macro\")\n\nrust_library(\n    name = \"cxx\",\n    srcs = glob([\"src/**/*.rs\"]),\n    crate_features = [\n        \"alloc\",\n        \"std\",\n    ],\n    edition = \"2021\",\n    proc_macro_deps = [\n        \":cxxbridge-macro\",\n    ],\n    version = module_version(),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \":core-lib\",\n        \"@crates.io//:foldhash\",\n    ],\n)\n\nalias(\n    name = \"codegen\",\n    actual = \":cxxbridge\",\n    visibility = [\"//visibility:public\"],\n)\n\nrust_binary(\n    name = \"cxxbridge\",\n    srcs = glob([\"gen/cmd/src/**/*.rs\"]),\n    compile_data = glob([\"gen/cmd/src/gen/**/*.h\"]),\n    edition = \"2021\",\n    version = module_version(),\n    deps = [\n        \"@crates.io//:clap\",\n        \"@crates.io//:codespan-reporting\",\n        \"@crates.io//:indexmap\",\n        \"@crates.io//:proc-macro2\",\n        \"@crates.io//:quote\",\n        \"@crates.io//:syn\",\n    ],\n)\n\ncc_library(\n    name = \"core\",\n    hdrs = [\"include/cxx.h\"],\n    include_prefix = \"rust\",\n    strip_include_prefix = \"include\",\n    visibility = [\"//visibility:public\"],\n)\n\ncc_library(\n    name = \"core-lib\",\n    srcs = [\"src/cxx.cc\"],\n    hdrs = [\"include/cxx.h\"],\n    linkstatic = True,\n)\n\nrust_proc_macro(\n    name = \"cxxbridge-macro\",\n    srcs = glob([\"macro/src/**/*.rs\"]),\n    edition = \"2021\",\n    proc_macro_deps = [\n        \"@crates.io//:rustversion\",\n    ],\n    version = module_version(),\n    deps = [\n        \"@crates.io//:indexmap\",\n        \"@crates.io//:proc-macro2\",\n        \"@crates.io//:quote\",\n        \"@crates.io//:syn\",\n    ],\n)\n\nrust_library(\n    name = \"cxx-build\",\n    srcs = glob([\"gen/build/src/**/*.rs\"]),\n    compile_data = glob([\"gen/build/src/gen/**/*.h\"]),\n    edition = \"2021\",\n    version = module_version(),\n    deps = [\n        \"@crates.io//:cc\",\n        \"@crates.io//:codespan-reporting\",\n        \"@crates.io//:indexmap\",\n        \"@crates.io//:proc-macro2\",\n        \"@crates.io//:quote\",\n        \"@crates.io//:scratch\",\n        \"@crates.io//:syn\",\n    ],\n)\n\nrust_library(\n    name = \"cxx-gen\",\n    srcs = glob([\"gen/lib/src/**/*.rs\"]),\n    compile_data = glob([\"gen/lib/src/gen/**/*.h\"]),\n    edition = \"2021\",\n    version = module_version(),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"@crates.io//:cc\",\n        \"@crates.io//:codespan-reporting\",\n        \"@crates.io//:indexmap\",\n        \"@crates.io//:proc-macro2\",\n        \"@crates.io//:quote\",\n        \"@crates.io//:syn\",\n    ],\n)\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[package]\nname = \"cxx\"\nversion = \"1.0.194\"\nauthors = [\"David Tolnay <dtolnay@gmail.com>\"]\ncategories = [\"development-tools::ffi\", \"api-bindings\", \"no-std\"]\ndescription = \"Safe interop between Rust and C++\"\ndocumentation = \"https://docs.rs/cxx\"\nedition = \"2021\"\nexclude = [\"/demo\", \"/gen\", \"/syntax\", \"/third-party\", \"/tools/buck/prelude\"]\nhomepage = \"https://cxx.rs\"\nkeywords = [\"ffi\", \"c++\"]\nlicense = \"MIT OR Apache-2.0\"\nlinks = \"cxxbridge1\"\nrepository = \"https://github.com/dtolnay/cxx\"\nrust-version = \"1.85\"\n\n[features]\ndefault = [\"std\", \"cxxbridge-flags/default\"] # c++11\n\"c++14\" = [\"cxxbridge-flags/c++14\"]\n\"c++17\" = [\"cxxbridge-flags/c++17\"]\n\"c++20\" = [\"cxxbridge-flags/c++20\"]\nalloc = []\nstd = [\"alloc\", \"foldhash/std\"]\n\n[dependencies]\ncxxbridge-macro = { version = \"=1.0.194\", path = \"macro\" }\nfoldhash = { version = \"0.2\", default-features = false }\nlink-cplusplus = \"1.0.11\"\n\n[build-dependencies]\ncc = \"1.0.101\"\ncxxbridge-flags = { version = \"=1.0.194\", path = \"flags\", default-features = false }\n\n[dev-dependencies]\ncc = \"1.0.101\"\ncxx-build = { version = \"1\", path = \"gen/build\" }\ncxx-gen = { version = \"=0.7.194\", path = \"gen/lib\" }\ncxx-test-suite = { version = \"0\", path = \"tests/ffi\" }\nindoc = \"2\"\nproc-macro2 = \"1.0.95\"\nquote = \"1.0.40\"\nrustversion = \"1.0.13\"\nscratch = \"1\"\ntarget-triple = \"1\"\ntempfile = \"3.8\"\ntrybuild = { version = \"1.0.108\", features = [\"diff\"] }\n\n# Disallow incompatible version appearing in the same lockfile.\n[target.'cfg(any())'.build-dependencies]\ncxx-build = { version = \"=1.0.194\", path = \"gen/build\" }\ncxxbridge-cmd = { version = \"=1.0.194\", path = \"gen/cmd\" }\n\n[workspace]\nmembers = [\"demo\", \"flags\", \"gen/build\", \"gen/cmd\", \"gen/lib\", \"macro\", \"tests/ffi\"]\n\n[package.metadata.docs.rs]\ntargets = [\"x86_64-unknown-linux-gnu\"]\nrustdoc-args = [\n    \"--generate-link-to-definition\",\n    \"--generate-macro-expansion\",\n    \"--extern-html-root-url=core=https://doc.rust-lang.org\",\n    \"--extern-html-root-url=alloc=https://doc.rust-lang.org\",\n    \"--extern-html-root-url=std=https://doc.rust-lang.org\",\n]\n\n[package.metadata.bazel]\nadditive_build_file_content = \"\"\"\nload(\"@rules_cc//cc:defs.bzl\", \"cc_library\")\ncc_library(\n    name = \"cxx_cc\",\n    srcs = [\"src/cxx.cc\"],\n    hdrs = [\"include/cxx.h\"],\n    include_prefix = \"rust\",\n    includes = [\"include\"],\n    linkstatic = True,\n    strip_include_prefix = \"include\",\n    visibility = [\"//visibility:public\"],\n)\n\"\"\"\ndeps = [\":cxx_cc\"]\nextra_aliased_targets = { cxx_cc = \"cxx_cc\" }\ngen_build_script = false\n\n[patch.crates-io]\ncxx = { path = \".\" }\ncxx-build = { path = \"gen/build\" }\n"
  },
  {
    "path": "LICENSE-APACHE",
    "content": "                              Apache License\n                        Version 2.0, January 2004\n                     http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n   \"License\" shall mean the terms and conditions for use, reproduction,\n   and distribution as defined by Sections 1 through 9 of this document.\n\n   \"Licensor\" shall mean the copyright owner or entity authorized by\n   the copyright owner that is granting the License.\n\n   \"Legal Entity\" shall mean the union of the acting entity and all\n   other entities that control, are controlled by, or are under common\n   control with that entity. For the purposes of this definition,\n   \"control\" means (i) the power, direct or indirect, to cause the\n   direction or management of such entity, whether by contract or\n   otherwise, or (ii) ownership of fifty percent (50%) or more of the\n   outstanding shares, or (iii) beneficial ownership of such entity.\n\n   \"You\" (or \"Your\") shall mean an individual or Legal Entity\n   exercising permissions granted by this License.\n\n   \"Source\" form shall mean the preferred form for making modifications,\n   including but not limited to software source code, documentation\n   source, and configuration files.\n\n   \"Object\" form shall mean any form resulting from mechanical\n   transformation or translation of a Source form, including but\n   not limited to compiled object code, generated documentation,\n   and conversions to other media types.\n\n   \"Work\" shall mean the work of authorship, whether in Source or\n   Object form, made available under the License, as indicated by a\n   copyright notice that is included in or attached to the work\n   (an example is provided in the Appendix below).\n\n   \"Derivative Works\" shall mean any work, whether in Source or Object\n   form, that is based on (or derived from) the Work and for which the\n   editorial revisions, annotations, elaborations, or other modifications\n   represent, as a whole, an original work of authorship. For the purposes\n   of this License, Derivative Works shall not include works that remain\n   separable from, or merely link (or bind by name) to the interfaces of,\n   the Work and Derivative Works thereof.\n\n   \"Contribution\" shall mean any work of authorship, including\n   the original version of the Work and any modifications or additions\n   to that Work or Derivative Works thereof, that is intentionally\n   submitted to Licensor for inclusion in the Work by the copyright owner\n   or by an individual or Legal Entity authorized to submit on behalf of\n   the copyright owner. For the purposes of this definition, \"submitted\"\n   means any form of electronic, verbal, or written communication sent\n   to the Licensor or its representatives, including but not limited to\n   communication on electronic mailing lists, source code control systems,\n   and issue tracking systems that are managed by, or on behalf of, the\n   Licensor for the purpose of discussing and improving the Work, but\n   excluding communication that is conspicuously marked or otherwise\n   designated in writing by the copyright owner as \"Not a Contribution.\"\n\n   \"Contributor\" shall mean Licensor and any individual or Legal Entity\n   on behalf of whom a Contribution has been received by Licensor and\n   subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   copyright license to reproduce, prepare Derivative Works of,\n   publicly display, publicly perform, sublicense, and distribute the\n   Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   (except as stated in this section) patent license to make, have made,\n   use, offer to sell, sell, import, and otherwise transfer the Work,\n   where such license applies only to those patent claims licensable\n   by such Contributor that are necessarily infringed by their\n   Contribution(s) alone or by combination of their Contribution(s)\n   with the Work to which such Contribution(s) was submitted. If You\n   institute patent litigation against any entity (including a\n   cross-claim or counterclaim in a lawsuit) alleging that the Work\n   or a Contribution incorporated within the Work constitutes direct\n   or contributory patent infringement, then any patent licenses\n   granted to You under this License for that Work shall terminate\n   as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n   Work or Derivative Works thereof in any medium, with or without\n   modifications, and in Source or Object form, provided that You\n   meet the following conditions:\n\n   (a) You must give any other recipients of the Work or\n       Derivative Works a copy of this License; and\n\n   (b) You must cause any modified files to carry prominent notices\n       stating that You changed the files; and\n\n   (c) You must retain, in the Source form of any Derivative Works\n       that You distribute, all copyright, patent, trademark, and\n       attribution notices from the Source form of the Work,\n       excluding those notices that do not pertain to any part of\n       the Derivative Works; and\n\n   (d) If the Work includes a \"NOTICE\" text file as part of its\n       distribution, then any Derivative Works that You distribute must\n       include a readable copy of the attribution notices contained\n       within such NOTICE file, excluding those notices that do not\n       pertain to any part of the Derivative Works, in at least one\n       of the following places: within a NOTICE text file distributed\n       as part of the Derivative Works; within the Source form or\n       documentation, if provided along with the Derivative Works; or,\n       within a display generated by the Derivative Works, if and\n       wherever such third-party notices normally appear. The contents\n       of the NOTICE file are for informational purposes only and\n       do not modify the License. You may add Your own attribution\n       notices within Derivative Works that You distribute, alongside\n       or as an addendum to the NOTICE text from the Work, provided\n       that such additional attribution notices cannot be construed\n       as modifying the License.\n\n   You may add Your own copyright statement to Your modifications and\n   may provide additional or different license terms and conditions\n   for use, reproduction, or distribution of Your modifications, or\n   for any such Derivative Works as a whole, provided Your use,\n   reproduction, and distribution of the Work otherwise complies with\n   the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n   any Contribution intentionally submitted for inclusion in the Work\n   by You to the Licensor shall be under the terms and conditions of\n   this License, without any additional terms or conditions.\n   Notwithstanding the above, nothing herein shall supersede or modify\n   the terms of any separate license agreement you may have executed\n   with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n   names, trademarks, service marks, or product names of the Licensor,\n   except as required for reasonable and customary use in describing the\n   origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n   agreed to in writing, Licensor provides the Work (and each\n   Contributor provides its Contributions) on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n   implied, including, without limitation, any warranties or conditions\n   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n   PARTICULAR PURPOSE. You are solely responsible for determining the\n   appropriateness of using or redistributing the Work and assume any\n   risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n   whether in tort (including negligence), contract, or otherwise,\n   unless required by applicable law (such as deliberate and grossly\n   negligent acts) or agreed to in writing, shall any Contributor be\n   liable to You for damages, including any direct, indirect, special,\n   incidental, or consequential damages of any character arising as a\n   result of this License or out of the use or inability to use the\n   Work (including but not limited to damages for loss of goodwill,\n   work stoppage, computer failure or malfunction, or any and all\n   other commercial damages or losses), even if such Contributor\n   has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n   the Work or Derivative Works thereof, You may choose to offer,\n   and charge a fee for, acceptance of support, warranty, indemnity,\n   or other liability obligations and/or rights consistent with this\n   License. However, in accepting such obligations, You may act only\n   on Your own behalf and on Your sole responsibility, not on behalf\n   of any other Contributor, and only if You agree to indemnify,\n   defend, and hold each Contributor harmless for any liability\n   incurred by, or claims asserted against, such Contributor by reason\n   of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n"
  },
  {
    "path": "LICENSE-MIT",
    "content": "Permission is hereby granted, free of charge, to any\nperson obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the\nSoftware without restriction, including without\nlimitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software\nis furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice\nshall be included in all copies or substantial portions\nof the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF\nANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\nTO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\nSHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR\nIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "MODULE.bazel",
    "content": "module(\n    name = \"cxx.rs\",\n    version = \"0.0.0\",\n    bazel_compatibility = [\">=8.0.0\"],\n    compatibility_level = 1,\n)\n\nbazel_dep(name = \"apple_support\", version = \"2.1.0\")\nbazel_dep(name = \"bazel_features\", version = \"1.33.0\")\nbazel_dep(name = \"bazel_skylib\", version = \"1.8.2\")\nbazel_dep(name = \"platforms\", version = \"1.0.0\")\nbazel_dep(name = \"rules_cc\", version = \"0.2.14\")\nbazel_dep(name = \"rules_rust\", version = \"0.69.0\")\n\nrust = use_extension(\"@rules_rust//rust:extensions.bzl\", \"rust\")\nrust.toolchain(versions = [\"1.94.0\"])\nuse_repo(rust, \"rust_toolchains\")\n\nregister_toolchains(\"@rust_toolchains//:all\")\n\ncrate_repositories = use_extension(\"//tools/bazel:extension.bzl\", \"crate_repositories\")\nuse_repo(crate_repositories, \"crates.io\", \"vendor\")\n"
  },
  {
    "path": "README.md",
    "content": "CXX &mdash; safe FFI between Rust and C++\n=========================================\n\n[<img alt=\"github\" src=\"https://img.shields.io/badge/github-dtolnay/cxx-8da0cb?style=for-the-badge&labelColor=555555&logo=github\" height=\"20\">](https://github.com/dtolnay/cxx)\n[<img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/cxx.svg?style=for-the-badge&color=fc8d62&logo=rust\" height=\"20\">](https://crates.io/crates/cxx)\n[<img alt=\"docs.rs\" src=\"https://img.shields.io/badge/docs.rs-cxx-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\" height=\"20\">](https://docs.rs/cxx)\n[<img alt=\"build status\" src=\"https://img.shields.io/github/actions/workflow/status/dtolnay/cxx/ci.yml?branch=master&style=for-the-badge\" height=\"20\">](https://github.com/dtolnay/cxx/actions?query=branch%3Amaster)\n\nThis library provides a **safe** mechanism for calling C++ code from Rust and\nRust code from C++, not subject to the many ways that things can go wrong when\nusing bindgen or cbindgen to generate unsafe C-style bindings.\n\nThis doesn't change the fact that 100% of C++ code is unsafe. When auditing a\nproject, you would be on the hook for auditing all the unsafe Rust code and\n*all* the C++ code. The core safety claim under this new model is that auditing\njust the C++ side would be sufficient to catch all problems, i.e. the Rust side\ncan be 100% safe.\n\n```toml\n[dependencies]\ncxx = \"1.0\"\n\n[build-dependencies]\ncxx-build = \"1.0\"\n```\n\n*Compiler support: requires rustc 1.85+ and c++11 or newer*<br>\n*[Release notes](https://github.com/dtolnay/cxx/releases)*\n\n<br>\n\n## Guide\n\nPlease see **<https://cxx.rs>** for a tutorial, reference material, and example\ncode.\n\n<br>\n\n## Overview\n\nThe idea is that we define the signatures of both sides of our FFI boundary\nembedded together in one Rust module (the next section shows an example). From\nthis, CXX receives a complete picture of the boundary to perform static analyses\nagainst the types and function signatures to uphold both Rust's and C++'s\ninvariants and requirements.\n\nIf everything checks out statically, then CXX uses a pair of code generators to\nemit the relevant `extern \"C\"` signatures on both sides together with any\nnecessary static assertions for later in the build process to verify\ncorrectness. On the Rust side this code generator is simply an attribute\nprocedural macro. On the C++ side it can be a small Cargo build script if your\nbuild is managed by Cargo, or for other build systems like Bazel or Buck we\nprovide a command line tool which generates the header and source file and\nshould be easy to integrate.\n\nThe resulting FFI bridge operates at zero or negligible overhead, i.e. no\ncopying, no serialization, no memory allocation, no runtime checks needed.\n\nThe FFI signatures are able to use native types from whichever side they please,\nsuch as Rust's `String` or C++'s `std::string`, Rust's `Box` or C++'s\n`std::unique_ptr`, Rust's `Vec` or C++'s `std::vector`, etc in any combination.\nCXX guarantees an ABI-compatible signature that both sides understand, based on\nbuiltin bindings for key standard library types to expose an idiomatic API on\nthose types to the other language. For example when manipulating a C++ string\nfrom Rust, its `len()` method becomes a call of the `size()` member function\ndefined by C++; when manipulating a Rust string from C++, its `size()` member\nfunction calls Rust's `len()`.\n\n<br>\n\n## Example\n\nIn this example we are writing a Rust application that wishes to take advantage\nof an existing C++ client for a large-file blobstore service. The blobstore\nsupports a `put` operation for a discontiguous buffer upload. For example we\nmight be uploading snapshots of a circular buffer which would tend to consist of\n2 chunks, or fragments of a file spread across memory for some other reason.\n\nA runnable version of this example is provided under the *demo* directory of\nthis repo. To try it out, run `cargo run` from that directory.\n\n```rust\n#[cxx::bridge]\nmod ffi {\n    // Any shared structs, whose fields will be visible to both languages.\n    struct BlobMetadata {\n        size: usize,\n        tags: Vec<String>,\n    }\n\n    extern \"Rust\" {\n        // Zero or more opaque types which both languages can pass around but\n        // only Rust can see the fields.\n        type MultiBuf;\n\n        // Functions implemented in Rust.\n        fn next_chunk(buf: &mut MultiBuf) -> &[u8];\n    }\n\n    unsafe extern \"C++\" {\n        // One or more headers with the matching C++ declarations. Our code\n        // generators don't read it but it gets #include'd and used in static\n        // assertions to ensure our picture of the FFI boundary is accurate.\n        include!(\"demo/include/blobstore.h\");\n\n        // Zero or more opaque types which both languages can pass around but\n        // only C++ can see the fields.\n        type BlobstoreClient;\n\n        // Functions implemented in C++.\n        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;\n        fn put(&self, parts: &mut MultiBuf) -> u64;\n        fn tag(&self, blobid: u64, tag: &str);\n        fn metadata(&self, blobid: u64) -> BlobMetadata;\n    }\n}\n```\n\nNow we simply provide Rust definitions of all the things in the `extern \"Rust\"`\nblock and C++ definitions of all the things in the `extern \"C++\"` block, and get\nto call back and forth safely.\n\nHere are links to the complete set of source files involved in the demo:\n\n- [demo/src/main.rs](demo/src/main.rs)\n- [demo/build.rs](demo/build.rs)\n- [demo/include/blobstore.h](demo/include/blobstore.h)\n- [demo/src/blobstore.cc](demo/src/blobstore.cc)\n\nTo look at the code generated in both languages for the example by the CXX code\ngenerators:\n\n```console\n   # run Rust code generator and print to stdout\n   # (requires https://github.com/dtolnay/cargo-expand)\n$ cargo expand --manifest-path demo/Cargo.toml\n\n   # run C++ code generator and print to stdout\n$ cargo run --manifest-path gen/cmd/Cargo.toml -- demo/src/main.rs\n```\n\n<br>\n\n## Details\n\nAs seen in the example, the language of the FFI boundary involves 3 kinds of\nitems:\n\n- **Shared structs** &mdash; their fields are made visible to both languages.\n  The definition written within cxx::bridge is the single source of truth.\n\n- **Opaque types** &mdash; their fields are secret from the other language.\n  These cannot be passed across the FFI by value but only behind an indirection,\n  such as a reference `&`, a Rust `Box`, or a `UniquePtr`. Can be a type alias\n  for an arbitrarily complicated generic language-specific type depending on\n  your use case.\n\n- **Functions** &mdash; implemented in either language, callable from the other\n  language.\n\nWithin the `extern \"Rust\"` part of the CXX bridge we list the types and\nfunctions for which Rust is the source of truth. These all implicitly refer to\nthe `super` module, the parent module of the CXX bridge. You can think of the\ntwo items listed in the example above as being like `use super::MultiBuf` and\n`use super::next_chunk` except re-exported to C++. The parent module will either\ncontain the definitions directly for simple things, or contain the relevant\n`use` statements to bring them into scope from elsewhere.\n\nWithin the `extern \"C++\"` part, we list types and functions for which C++ is the\nsource of truth, as well as the header(s) that declare those APIs. In the future\nit's possible that this section could be generated bindgen-style from the\nheaders but for now we need the signatures written out; static assertions will\nverify that they are accurate.\n\nYour function implementations themselves, whether in C++ or Rust, *do not* need\nto be defined as `extern \"C\"` ABI or no\\_mangle. CXX will put in the right shims\nwhere necessary to make it all work.\n\n<br>\n\n## Comparison vs bindgen and cbindgen\n\nNotice that with CXX there is repetition of all the function signatures: they\nare typed out once where the implementation is defined (in C++ or Rust) and\nagain inside the cxx::bridge module, though compile-time assertions guarantee\nthese are kept in sync. This is different from [bindgen] and [cbindgen] where\nfunction signatures are typed by a human once and the tool consumes them in one\nlanguage and emits them in the other language.\n\n[bindgen]: https://github.com/rust-lang/rust-bindgen\n[cbindgen]: https://github.com/eqrion/cbindgen/\n\nThis is because CXX fills a somewhat different role. It is a lower level tool\nthan bindgen or cbindgen in a sense; you can think of it as being a replacement\nfor the concept of `extern \"C\"` signatures as we know them, rather than a\nreplacement for a bindgen. It would be reasonable to build a higher level\nbindgen-like tool on top of CXX which consumes a C++ header and/or Rust module\n(and/or IDL like Thrift) as source of truth and generates the cxx::bridge,\neliminating the repetition while leveraging the static analysis safety\nguarantees of CXX.\n\nBut note in other ways CXX is higher level than the bindgens, with rich support\nfor common standard library types. Frequently with bindgen when we are dealing\nwith an idiomatic C++ API we would end up manually wrapping that API in C-style\nraw pointer functions, applying bindgen to get unsafe raw pointer Rust\nfunctions, and replicating the API again to expose those idiomatically in Rust.\nThat's a much worse form of repetition because it is unsafe all the way through.\n\nBy using a CXX bridge as the shared understanding between the languages, rather\nthan `extern \"C\"` C-style signatures as the shared understanding, common FFI use\ncases become expressible using 100% safe code.\n\nIt would also be reasonable to mix and match, using CXX bridge for the 95% of\nyour FFI that is straightforward and doing the remaining few oddball signatures\nthe old fashioned way with bindgen and cbindgen, if for some reason CXX's static\nrestrictions get in the way. Please file an issue if you end up taking this\napproach so that we know what ways it would be worthwhile to make the tool more\nexpressive.\n\n<br>\n\n## Cargo-based setup\n\nFor builds that are orchestrated by Cargo, you will use a build script that runs\nCXX's C++ code generator and compiles the resulting C++ code along with any\nother C++ code for your crate.\n\nThe canonical build script is as follows. The indicated line returns a\n[`cc::Build`] instance (from the usual widely used `cc` crate) on which you can\nset up any additional source files and compiler flags as normal.\n\n[`cc::Build`]: https://docs.rs/cc/1.0/cc/struct.Build.html\n\n```toml\n# Cargo.toml\n\n[build-dependencies]\ncxx-build = \"1.0\"\n```\n\n```rust\n// build.rs\n\nfn main() {\n    cxx_build::bridge(\"src/main.rs\")  // returns a cc::Build\n        .file(\"src/demo.cc\")\n        .std(\"c++11\")\n        .compile(\"cxxbridge-demo\");\n\n    println!(\"cargo:rerun-if-changed=src/demo.cc\");\n    println!(\"cargo:rerun-if-changed=include/demo.h\");\n}\n```\n\n<br>\n\n## Non-Cargo setup\n\nFor use in non-Cargo builds like Bazel or Buck, CXX provides an alternate way of\ninvoking the C++ code generator as a standalone command line tool. The tool is\npackaged as the `cxxbridge-cmd` crate on crates.io or can be built from the\n*gen/cmd* directory of this repo.\n\n```bash\n$ cargo install cxxbridge-cmd\n\n$ cxxbridge src/main.rs --header > path/to/mybridge.h\n$ cxxbridge src/main.rs > path/to/mybridge.cc\n```\n\n<br>\n\n## Safety\n\nBe aware that the design of this library is intentionally restrictive and\nopinionated! It isn't a goal to be powerful enough to handle arbitrary\nsignatures in either language. Instead this project is about carving out a\nreasonably expressive set of functionality about which we can make useful safety\nguarantees today and maybe extend over time. You may find that it takes some\npractice to use CXX bridge effectively as it won't work in all the ways that you\nare used to.\n\nSome of the considerations that go into ensuring safety are:\n\n- By design, our paired code generators work together to control both sides of\n  the FFI boundary. Ordinarily in Rust writing your own `extern \"C\"` blocks is\n  unsafe because the Rust compiler has no way to know whether the signatures\n  you've written actually match the signatures implemented in the other\n  language. With CXX we achieve that visibility and know what's on the other\n  side.\n\n- Our static analysis detects and prevents passing types by value that shouldn't\n  be passed by value from C++ to Rust, for example because they may contain\n  internal pointers that would be screwed up by Rust's move behavior.\n\n- To many people's surprise, it is possible to have a struct in Rust and a\n  struct in C++ with exactly the same layout / fields / alignment / everything,\n  and still not the same ABI when passed by value. This is a longstanding\n  bindgen bug that leads to segfaults in absolutely correct-looking code\n  ([rust-lang/rust-bindgen#778]). CXX knows about this and can insert the\n  necessary zero-cost workaround transparently where needed, so go ahead and\n  pass your structs by value without worries. This is made possible by owning\n  both sides of the boundary rather than just one.\n\n- Template instantiations: for example in order to expose a UniquePtr\\<T\\> type\n  in Rust backed by a real C++ unique\\_ptr, we have a way of using a Rust trait\n  to connect the behavior back to the template instantiations performed by the\n  other language.\n\n[rust-lang/rust-bindgen#778]: https://github.com/rust-lang/rust-bindgen/issues/778\n\n<br>\n\n## Builtin types\n\nIn addition to all the primitive types (i32 &lt;=&gt; int32_t), the following\ncommon types may be used in the fields of shared structs and the arguments and\nreturns of functions.\n\n<table>\n<tr><th>name in Rust</th><th>name in C++</th><th>restrictions</th></tr>\n<tr><td>String</td><td>rust::String</td><td></td></tr>\n<tr><td>&amp;str</td><td>rust::Str</td><td></td></tr>\n<tr><td>&amp;[T]</td><td>rust::Slice&lt;const T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n<tr><td>&amp;mut [T]</td><td>rust::Slice&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n<tr><td><a href=\"https://docs.rs/cxx/1.0/cxx/struct.CxxString.html\">CxxString</a></td><td>std::string</td><td><sup><i>cannot be passed by value</i></sup></td></tr>\n<tr><td>Box&lt;T&gt;</td><td>rust::Box&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n<tr><td><a href=\"https://docs.rs/cxx/1.0/cxx/struct.UniquePtr.html\">UniquePtr&lt;T&gt;</a></td><td>std::unique_ptr&lt;T&gt;</td><td><sup><i>cannot hold opaque Rust type</i></sup></td></tr>\n<tr><td><a href=\"https://docs.rs/cxx/1.0/cxx/struct.SharedPtr.html\">SharedPtr&lt;T&gt;</a></td><td>std::shared_ptr&lt;T&gt;</td><td><sup><i>cannot hold opaque Rust type</i></sup></td></tr>\n<tr><td>[T; N]</td><td>std::array&lt;T, N&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n<tr><td>Vec&lt;T&gt;</td><td>rust::Vec&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n<tr><td><a href=\"https://docs.rs/cxx/1.0/cxx/struct.CxxVector.html\">CxxVector&lt;T&gt;</a></td><td>std::vector&lt;T&gt;</td><td><sup><i>cannot be passed by value, cannot hold opaque Rust type</i></sup></td></tr>\n<tr><td>*mut T, *const T</td><td>T*, const T*</td><td><sup><i>fn with a raw pointer argument must be declared unsafe to call</i></sup></td></tr>\n<tr><td>fn(T, U) -&gt; V</td><td>rust::Fn&lt;V(T, U)&gt;</td><td><sup><i>only passing from Rust to C++ is implemented so far</i></sup></td></tr>\n<tr><td>Result&lt;T&gt;</td><td>throw/catch</td><td><sup><i>allowed as return type only</i></sup></td></tr>\n</table>\n\nThe C++ API of the `rust` namespace is defined by the *include/cxx.h* file in\nthis repo. You will need to include this header in your C++ code when working\nwith those types.\n\nThe following types are intended to be supported \"soon\" but are just not\nimplemented yet. I don't expect any of these to be hard to make work but it's a\nmatter of designing a nice API for each in its non-native language.\n\n<table>\n<tr><th>name in Rust</th><th>name in C++</th></tr>\n<tr><td>BTreeMap&lt;K, V&gt;</td><td><sup><i>tbd</i></sup></td></tr>\n<tr><td>HashMap&lt;K, V&gt;</td><td><sup><i>tbd</i></sup></td></tr>\n<tr><td>Arc&lt;T&gt;</td><td><sup><i>tbd</i></sup></td></tr>\n<tr><td>Option&lt;T&gt;</td><td><sup><i>tbd</i></sup></td></tr>\n<tr><td><sup><i>tbd</i></sup></td><td>std::map&lt;K, V&gt;</td></tr>\n<tr><td><sup><i>tbd</i></sup></td><td>std::unordered_map&lt;K, V&gt;</td></tr>\n</table>\n\n<br>\n\n## Remaining work\n\nThis is still early days for CXX; I am releasing it as a minimum viable product\nto collect feedback on the direction and invite collaborators. Please check the\nopen issues.\n\nEspecially please report issues if you run into trouble building or linking any\nof this stuff. I'm sure there are ways to make the build aspects friendlier or\nmore robust.\n\nFinally, I know more about Rust library design than C++ library design so I\nwould appreciate help making the C++ APIs in this project more idiomatic where\nanyone has suggestions.\n\n<br>\n\n#### License\n\n<sup>\nLicensed under either of <a href=\"LICENSE-APACHE\">Apache License, Version\n2.0</a> or <a href=\"LICENSE-MIT\">MIT license</a> at your option.\n</sup>\n\n<br>\n\n<sub>\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this project by you, as defined in the Apache-2.0 license,\nshall be dual licensed as above, without any additional terms or conditions.\n</sub>\n"
  },
  {
    "path": "book/.gitignore",
    "content": "/build/\n/mdbook\n/node_modules/\n"
  },
  {
    "path": "book/README.md",
    "content": "Published automatically to https://cxx.rs from master branch.\n\nTo build and view locally:\n\n- Install [mdBook]: `cargo install mdbook`.\n- Run `mdbook build` in this directory.\n- Open the generated *build/index.html*.\n\n[mdBook]: https://github.com/rust-lang/mdBook\n"
  },
  {
    "path": "book/book.toml",
    "content": "[book]\n#title = \"Rust ♡ C++\"\nauthors = [\"David Tolnay\"]\ndescription = \"CXX — safe interop between Rust and C++ by David Tolnay. This library provides a safe mechanism for calling C++ code from Rust and Rust code from C++.\"\n\n[rust]\nedition = \"2021\"\n\n[build]\nbuild-dir = \"build\"\ncreate-missing = false\n\n[output.html]\nadditional-css = [\"css/cxx.css\"]\ncname = \"cxx.rs\"\ngit-repository-url = \"https://github.com/dtolnay/cxx\"\nplayground = { copyable = false }\nprint = { enable = false }\n\n[output.html.redirect]\n\"binding/index.html\" = \"../bindings.html\"\n\"build/index.html\" = \"../building.html\"\n"
  },
  {
    "path": "book/build.js",
    "content": "#!/usr/bin/env node\n\nconst fs = require('fs');\nconst cheerio = require('cheerio');\nconst entities = require('html-entities');\nconst hljs = require('./build/highlight.js');\n\nconst githublink = `\\\n<li class=\"part-title\">\\\n<a href=\"https://github.com/dtolnay/cxx\">\\\n<i class=\"fa fa-github\"></i>\\\nhttps://github.com/dtolnay/cxx\\\n</a>\\\n</li>`;\n\nconst opengraph = `\\\n<meta property=\"og:image\" content=\"https://cxx.rs/cxx.png\" />\\\n<meta property=\"og:site_name\" content=\"CXX\" />\\\n<meta property=\"og:title\" content=\"CXX — safe interop between Rust and C++\" />\\\n<meta name=\"twitter:image:src\" content=\"https://cxx.rs/cxx.png\" />\\\n<meta name=\"twitter:site\" content=\"@davidtolnay\" />\\\n<meta name=\"twitter:card\" content=\"summary\" />\\\n<meta name=\"twitter:title\" content=\"CXX — safe interop between Rust and C++\" />`;\n\nconst themejs = `\\\nvar theme;\ntry { theme = localStorage.getItem('mdbook-theme'); } catch(e) {}\nif (theme === null || theme === undefined) { theme = default_theme; }\nconst html = document.documentElement;\nhtml.classList.remove('light')\nhtml.classList.add(theme);\nhtml.classList.add(\"js\");`;\n\nconst themejsReplacement = `\\\nconst html = document.documentElement;\nhtml.classList.add('js');`;\n\nconst dirs = ['build'];\nwhile (dirs.length) {\n  const dir = dirs.pop();\n  fs.readdirSync(dir).forEach((entry) => {\n    const path = dir + '/' + entry;\n    const stat = fs.statSync(path);\n    if (stat.isDirectory()) {\n      dirs.push(path);\n      return;\n    }\n\n    if (!path.endsWith('.html')) {\n      return;\n    }\n\n    const index = fs.readFileSync(path, 'utf8');\n    const $ = cheerio.load(index, {\n      decodeEntities: false,\n      xml: { xmlMode: false },\n    });\n\n    $('head').append(opengraph);\n    $('nav#sidebar ol.chapter').append(githublink);\n    $('head link[href=\"tomorrow-night.css\"]').attr('disabled', true);\n    $('head link[href=\"ayu-highlight.css\"]').attr('disabled', true);\n    $('button#theme-toggle').attr('style', 'display:none');\n    $('pre code').each(function () {\n      const node = $(this);\n      const langClass = node.attr('class').split(' ', 2)[0];\n      if (!langClass.startsWith('language-')) {\n        return;\n      }\n      const lang = langClass.replace('language-', '');\n      const originalLines = node.html().split('\\n');\n      const boring = originalLines.map((line) =>\n        line.includes('<span class=\"boring\">'),\n      );\n      const ellipsis = originalLines.map((line) => line.includes('// ...'));\n      const target = entities.decode(node.text());\n      const highlightedLines = hljs.highlight(lang, target).value.split('\\n');\n      const result = highlightedLines\n        .map(function (line, i) {\n          if (boring[i]) {\n            line = '<span class=\"boring\">' + line;\n          } else if (ellipsis[i]) {\n            line = '<span class=\"ellipsis\">' + line;\n          }\n          if (i > 0 && (boring[i - 1] || ellipsis[i - 1])) {\n            line = '</span>' + line;\n          }\n          if (i + 1 === highlightedLines.length && (boring[i] || ellipsis[i])) {\n            line = line + '</span>';\n          }\n          return line;\n        })\n        .join('\\n');\n      node.text(result);\n      node.removeClass(langClass);\n      if (!node.hasClass('focuscomment')) {\n        node.addClass('hidelines');\n        node.addClass('hide-boring');\n      }\n    });\n    $('code').each(function () {\n      $(this).addClass('hljs');\n    });\n\n    var foundScript = false;\n    $('body script').each(function () {\n      const node = $(this);\n      if (node.text().replace(/\\s/g, '') === themejs.replace(/\\s/g, '')) {\n        node.text(themejsReplacement);\n        foundScript = true;\n      }\n    });\n    const pathsWithoutScript = [\n      'build/toc.html',\n      'build/build/index.html',\n      'build/binding/index.html',\n    ];\n    if (!foundScript && !pathsWithoutScript.includes(path)) {\n      throw new Error(`theme script not found in ${path}`);\n    }\n\n    const out = $.html();\n    fs.writeFileSync(path, out);\n  });\n}\n\nfs.copyFileSync('build/highlight.css', 'build/tomorrow-night.css');\nfs.copyFileSync('build/highlight.css', 'build/ayu-highlight.css');\n\nvar bookjs = fs.readFileSync('build/book.js', 'utf8');\nbookjs = bookjs\n  .replace('set_theme(theme, false);', '')\n  .replace(\n    'document.querySelectorAll(\"code.hljs\")',\n    'document.querySelectorAll(\"code.hidelines\")',\n  );\nfs.writeFileSync('build/book.js', bookjs);\n"
  },
  {
    "path": "book/build.sh",
    "content": "#!/bin/bash\n\nset -e\n\ncd \"$(dirname \"$0\")\"\n\nif [ -f ./mdbook ]; then\n    ./mdbook build\nelse\n    mdbook build\nfi\n\nif [ ! -d node_modules ]; then\n    npm install\nfi\n\n./build.js\n"
  },
  {
    "path": "book/css/cxx.css",
    "content": ":root {\n    --sidebar-width: 310px;\n}\n\n.badges img {\n    margin: 0 7px 7px 0;\n}\n\n.badges {\n    margin: 16px 0 120px;\n}\n\n.boring {\n    opacity: 0.5;\n}\n\n.no-js code:not(.focuscomment) .boring {\n    display: none;\n}\n\n.js code:not(.hide-boring) .ellipsis {\n    display: none;\n}\n\n.focuscomment .hljs-comment {\n    font-weight: bold;\n    color: black;\n}\n\n.focuscomment .boring {\n    opacity: 0.5;\n}\n\nnav.sidebar li.part-title i.fa-github {\n    font-size: 20px;\n    padding-right: 5px;\n    padding-top: 12px;\n    position: relative;\n    top: 1px;\n}\n\n.sidebar .sidebar-scrollbox {\n    padding: 10px 0 10px 10px;\n}\n\npre > .buttons {\n    visibility: visible;\n    opacity: 0.3;\n}\n"
  },
  {
    "path": "book/diagram/.gitignore",
    "content": "/*.aux\n/*.fdb_latexmk\n/*.fls\n/*.log\n/*.pdf\n/*.png\n/*.svg\n"
  },
  {
    "path": "book/diagram/Makefile",
    "content": "overview.svg: overview.pdf\n\tpdf2svg $< $@\n\noverview.pdf: overview.tex\n\tlatexmk $<\n\noverview.png: overview.svg\n\tsvgexport $< $@ 3x\n"
  },
  {
    "path": "book/diagram/overview.tex",
    "content": "\\documentclass{standalone}\n\\usepackage{makecell}\n\\usepackage{pgfplots}\n\\usepackage{sansmath}\n\\usetikzlibrary{arrows.meta}\n\\pgfplotsset{compat=1.16}\n\\begin{document}\n\\pagecolor{white}\n\\begin{tikzpicture}[\n  x=1cm,\n  y=-.6cm,\n  every node/.append style={\n    line width=1.5pt,\n    font=\\Large\\sansmath\\sffamily,\n  },\n  every path/.append style={\n    >={Latex[length=10pt,width=8pt]},\n    line width=1.5pt,\n  },\n  execute at end node={\\vphantom{bg}},\n]\n\\node[draw, rounded corners=5, inner xsep=30pt, inner ysep=2pt]\n  (bridge) at (0, .25) {\\makecell{\\texttt{\\#\\hspace{-1pt}[}cxx::bridge\\texttt{]} mod\\\\[-4pt]description of boundary}};\n\\node[draw, rounded corners, inner xsep=10pt, inner ysep=6pt, text depth=1pt]\n  (rust-bindings) at (-3.5, 6.5) {Rust bindings};\n\\node[draw, rounded corners, inner xsep=10pt, inner ysep=6pt, text depth=1pt]\n  (cpp-bindings) at (3.5, 6.5) {C\\texttt{++} bindings};\n\\node[inner xsep=4pt, inner ysep=-0pt]\n  (rust-code) at (-9, 6.5) {\\makecell[r]{\\\\[-8pt]Rust\\\\[-4pt]code}};\n\\node[inner xsep=4pt, inner ysep=-0pt]\n  (cpp-code) at (9, 6.5) {\\makecell[l]{\\\\[-8pt]C\\texttt{++}\\\\[-4pt]code}};\n\\draw (bridge) -- (0, 4);\n\\draw[<->] (rust-bindings) |- (0, 4) -| (cpp-bindings);\n\\draw[<->] (rust-code) -- (rust-bindings);\n\\draw[<->, dash pattern=on 8pt off 6pt] (rust-bindings) -- (cpp-bindings);\n\\draw[<->] (cpp-bindings) -- (cpp-code);\n\\draw (-.75, 4) node[anchor=south east] {Macro expansion};\n\\draw (.75, 4) node[anchor=south west] {Code generation};\n\\draw (0, 6.5) node[anchor=south, inner ysep=4pt] {Hidden C ABI};\n\\draw (-6.75, 6.5) node[anchor=south, inner ysep=1pt] {\\makecell{Safe\\\\[-4pt]straightforward\\\\[-4pt]Rust APIs}};\n\\draw (6.75, 6.5) node[anchor=south, inner ysep=1pt] {\\makecell{Straightforward\\\\[-4pt]C\\texttt{++} APIs}};\n\\pgfresetboundingbox\\path\n  (-9.5, 0) -- (rust-bindings.south)+(0, .3) -- (9.5, 0) -- (bridge.north);\n\\end{tikzpicture}\n\\end{document}\n"
  },
  {
    "path": "book/eslint.config.mjs",
    "content": "import pluginJs from '@eslint/js';\n\n/** @type {import('eslint').Linter.Config[]} */\nexport default [\n  { ignores: ['build/*'] },\n  { files: ['**/*.js'], languageOptions: { sourceType: 'commonjs' } },\n  pluginJs.configs.recommended,\n];\n"
  },
  {
    "path": "book/package.json",
    "content": "{\n  \"name\": \"cxx-book-build\",\n  \"version\": \"0.0.0\",\n  \"main\": \"build.js\",\n  \"dependencies\": {\n    \"cheerio\": \"^1.0.0\",\n    \"html-entities\": \"^2.5.2\"\n  },\n  \"devDependencies\": {\n    \"@eslint/js\": \"^9.19.0\",\n    \"eslint\": \"^9.19.0\"\n  },\n  \"prettier\": {\n    \"singleQuote\": true\n  }\n}\n"
  },
  {
    "path": "book/src/404.md",
    "content": "### Whoops, this page doesn’t exist :-(\n\n<br>\n\n<img src=\"https://www.rust-lang.org/static/images/ferris-error.png\" alt=\"ferris\" width=\"325\">\n"
  },
  {
    "path": "book/src/SUMMARY.md",
    "content": "# Summary\n\n- [Rust ❤️ C++](index.md)\n\n- [Core concepts](concepts.md)\n\n- [Tutorial](tutorial.md)\n\n- [Other Rust&ndash;C++ interop tools](context.md)\n\n- [Multi-language build system options](building.md)\n    - [Cargo](build/cargo.md)\n    - [Bazel or Buck2](build/bazel.md)\n    - [CMake](build/cmake.md)\n    - [More...](build/other.md)\n\n- [Reference: the bridge module](reference.md)\n    - [extern \"Rust\"](extern-rust.md)\n    - [extern \"C++\"](extern-c++.md)\n    - [Shared types](shared.md)\n    - [Attributes](attributes.md)\n    - [Async functions](async.md)\n    - [Error handling](binding/result.md)\n\n- [Reference: built-in bindings](bindings.md)\n    - [String &mdash; rust::String](binding/string.md)\n    - [&str &mdash; rust::Str](binding/str.md)\n    - [&&#91;T&#93;, &mut &#91;T&#93; &mdash; rust::Slice\\<T\\>](binding/slice.md)\n    - [CxxString &mdash; std::string](binding/cxxstring.md)\n    - [Box\\<T\\> &mdash; rust::Box\\<T\\>](binding/box.md)\n    - [UniquePtr\\<T\\> &mdash; std::unique\\_ptr\\<T\\>](binding/uniqueptr.md)\n    - [SharedPtr\\<T\\> &mdash; std::shared\\_ptr\\<T\\>](binding/sharedptr.md)\n    - [Vec\\<T\\> &mdash; rust::Vec\\<T\\>](binding/vec.md)\n    - [CxxVector\\<T\\> &mdash; std::vector\\<T\\>](binding/cxxvector.md)\n    - [*mut T, *const T raw pointers](binding/rawptr.md)\n    - [Function pointers](binding/fn.md)\n    - [Result\\<T\\>](binding/result.md)\n"
  },
  {
    "path": "book/src/async.md",
    "content": "{{#title Async functions — Rust ♡ C++}}\n# Async functions\n\nDirect FFI of async functions is absolutely in scope for CXX (on C++20 and up)\nbut is not implemented yet in the current release. We are aiming for an\nimplementation that is as easy as:\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        async fn doThing(arg: Arg) -> Ret;\n    }\n}\n```\n\n```cpp\nrust::Future<Ret> doThing(Arg arg) {\n  auto v1 = co_await f();\n  auto v2 = co_await g(arg);\n  co_return v1 + v2;\n}\n```\n\n## Workaround\n\nFor now the recommended approach is to handle the return codepath over a oneshot\nchannel (such as [`futures::channel::oneshot`]) represented in an opaque Rust\ntype on the FFI.\n\n[`futures::channel::oneshot`]: https://docs.rs/futures/0.3.31/futures/channel/oneshot/index.html\n\n```rust,noplayground\n// bridge.rs\n\nuse futures::channel::oneshot;\n\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type DoThingContext;\n    }\n\n    unsafe extern \"C++\" {\n        include!(\"path/to/bridge_shim.h\");\n\n        fn shim_doThing(\n            arg: Arg,\n            done: fn(Box<DoThingContext>, ret: Ret),\n            ctx: Box<DoThingContext>,\n        );\n    }\n}\n\nstruct DoThingContext(oneshot::Sender<Ret>);\n\npub async fn do_thing(arg: Arg) -> Ret {\n    let (tx, rx) = oneshot::channel();\n    let context = Box::new(DoThingContext(tx));\n\n    ffi::shim_doThing(\n        arg,\n        |context, ret| { let _ = context.0.send(ret); },\n        context,\n    );\n\n    rx.await.unwrap()\n}\n```\n\n```cpp\n// bridge_shim.cc\n\n#include \"path/to/bridge.rs.h\"\n#include \"rust/cxx.h\"\n\nvoid shim_doThing(\n    Arg arg,\n    rust::Fn<void(rust::Box<DoThingContext> ctx, Ret ret)> done,\n    rust::Box<DoThingContext> ctx) noexcept {\n  doThing(arg)\n      .then([done, ctx(std::move(ctx))](auto &&res) mutable {\n        (*done)(std::move(ctx), std::move(res));\n      });\n}\n```\n\n## Streams\n\nThrough a multishot channel such as [`futures::channel::mpsc::unbounded`] in\nplace of the `futures::channel::oneshot` from above, C++ can send a stream of\nvalues that become a `futures::Stream` in Rust.\n\n[`futures::channel::mpsc::unbounded`]: https://docs.rs/futures/0.3.31/futures/channel/mpsc/fn.unbounded.html\n\nIn this case the callback function will take the channel sender by reference,\nnot as a Box. `rust::Fn<void(const StreamThingsContext &ctx, Item item)>`\n"
  },
  {
    "path": "book/src/attributes.md",
    "content": "{{#title Attributes — Rust ♡ C++}}\n# Attributes\n\n## namespace\n\nThe top-level cxx::bridge attribute macro takes an optional `namespace` argument\nto control the C++ namespace into which to emit extern Rust items and the\nnamespace in which to expect to find the extern C++ items.\n\n```rust,noplayground\n#[cxx::bridge(namespace = \"path::of::my::company\")]\nmod ffi {\n    extern \"Rust\" {\n        type MyType;  // emitted to path::of::my::company::MyType\n    }\n\n    extern \"C++\" {\n        type TheirType;  // refers to path::of::my::company::TheirType\n    }\n}\n```\n\nAdditionally, a `#[namespace = \"...\"]` attribute may be used inside the bridge\nmodule on any extern block or individual item. An item will inherit the\nnamespace specified on its surrounding extern block if any, otherwise the\nnamespace specified with the top level cxx::bridge attribute if any, otherwise\nthe global namespace.\n\n```rust,noplayground\n#[cxx::bridge(namespace = \"third_priority\")]\nmod ffi {\n    #[namespace = \"second_priority\"]\n    extern \"Rust\" {\n        fn f();\n\n        #[namespace = \"first_priority\"]\n        fn g();\n    }\n\n    extern \"Rust\" {\n        fn h();\n    }\n}\n```\n\nThe above would result in functions `::second_priority::f`,\n`::first_priority::g`, `::third_priority::h`.\n\n## rust\\_name, cxx\\_name\n\nSometimes you want the Rust name of a function or type to differ from its C++\nname. Importantly, this enables binding multiple overloads of the same C++\nfunction name using distinct Rust names.\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        #[rust_name = \"i32_overloaded_function\"]\n        fn cOverloadedFunction(x: i32) -> String;\n        #[rust_name = \"str_overloaded_function\"]\n        fn cOverloadedFunction(x: &str) -> String;\n    }\n}\n```\n\nThe `#[rust_name = \"...\"]` attribute replaces the name that Rust should use for\nthis function, and an analogous `#[cxx_name = \"...\"]` attribute replaces the\nname that C++ should use.\n\nEither of the two attributes may be used on extern \"Rust\" as well as extern\n\"C++\" functions, according to which one you find clearer in context.\n\nThe same attribute works for renaming functions, opaque types, shared\nstructs and enums, and enum variants.\n\n## Self\n\nIndicates the name of the type in which to place a [Rust associated function] or\n[C++ static member function].\n\n[Rust associated function]: extern-rust.md#associated-functions\n[C++ static member function]: extern-c++.md#functions-and-member-functions\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type RustType;\n\n        #[Self = \"RustType\"]\n        fn member();  // callable from C++ as `RustType::member()`\n    }\n\n    unsafe extern \"C++\" {\n        type CppType;\n\n        #[Self = \"CppType\"]\n        fn member();  // callable from Rust as `CppType::member()`\n    }\n}\n```\n"
  },
  {
    "path": "book/src/binding/box.md",
    "content": "{{#title rust::Box<T> — Rust ♡ C++}}\n# rust::Box\\<T\\>\n\n### Public API:\n\n```cpp,hidelines=...\n// rust/cxx.h\n...\n...#include <type_traits>\n...\n...namespace rust {\n\ntemplate <typename T>\nclass Box final {\npublic:\n  using element_type = T;\n  using const_pointer =\n      typename std::add_pointer<typename std::add_const<T>::type>::type;\n  using pointer = typename std::add_pointer<T>::type;\n\n  Box(Box &&) noexcept;\n  ~Box() noexcept;\n\n  explicit Box(const T &);\n  explicit Box(T &&);\n\n  Box &operator=(Box &&) & noexcept;\n\n  const T *operator->() const noexcept;\n  const T &operator*() const noexcept;\n  T *operator->() noexcept;\n  T &operator*() noexcept;\n\n  template <typename... Fields>\n  static Box in_place(Fields &&...);\n\n  void swap(Box &) noexcept;\n\n  // Important: requires that `raw` came from an into_raw call. Do not\n  // pass a pointer from `new` or any other source.\n  static Box from_raw(T *) noexcept;\n\n  T *into_raw() noexcept;\n};\n...\n...} // namespace rust\n```\n\n### Restrictions:\n\nBox\\<T\\> does not support T being an opaque C++ type. You should use\n[UniquePtr\\<T\\>](uniqueptr.md) or [SharedPtr\\<T\\>](sharedptr.md) instead for\ntransferring ownership of opaque C++ types on the language boundary.\n\nIf T is an opaque Rust type, the Rust type is required to be [Sized] i.e. size\nknown at compile time. In the future we may introduce support for dynamically\nsized opaque Rust types.\n\n[Sized]: https://doc.rust-lang.org/std/marker/trait.Sized.html\n\n## Example\n\nThis program uses a Box to pass ownership of some opaque piece of Rust state\nover to C++ and then back to a Rust callback, which is a useful pattern for\nimplementing [async functions over FFI](../async.md).\n\n```rust,noplayground\n// src/main.rs\n\nuse std::io::Write;\n\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type File;\n    }\n\n    unsafe extern \"C++\" {\n        include!(\"example/include/example.h\");\n\n        fn f(\n            callback: fn(Box<File>, fst: &str, snd: &str),\n            out: Box<File>,\n        );\n    }\n}\n\npub struct File(std::fs::File);\n\nfn main() {\n    let out = std::fs::File::create(\"example.log\").unwrap();\n\n    ffi::f(\n        |mut out, fst, snd| { let _ = write!(out.0, \"{}{}\\n\", fst, snd); },\n        Box::new(File(out)),\n    );\n}\n```\n\n```cpp\n// include/example.h\n\n#pragma once\n#include \"example/src/main.rs.h\"\n#include \"rust/cxx.h\"\n\nvoid f(rust::Fn<void(rust::Box<File>, rust::Str, rust::Str)> callback,\n       rust::Box<File> out);\n```\n\n```cpp\n// include/example.cc\n\n#include \"example/include/example.h\"\n\nvoid f(rust::Fn<void(rust::Box<File>, rust::Str, rust::Str)> callback,\n       rust::Box<File> out) {\n  callback(std::move(out), \"fearless\", \"concurrency\");\n}\n```\n"
  },
  {
    "path": "book/src/binding/cxxstring.md",
    "content": "{{#title std::string — Rust ♡ C++}}\n# std::string\n\nThe Rust binding of std::string is called **[`CxxString`]**. See the link for\ndocumentation of the Rust API.\n\n[`CxxString`]: https://docs.rs/cxx/*/cxx/struct.CxxString.html\n\n### Restrictions:\n\nRust code can never obtain a CxxString by value. C++'s string requires a move\nconstructor and may hold internal pointers, which is not compatible with Rust's\nmove behavior. Instead in Rust code we will only ever look at a CxxString\nthrough a reference or smart pointer, as in &CxxString or Pin\\<&mut CxxString\\>\nor UniquePtr\\<CxxString\\>.\n\nIn order to construct a CxxString on the stack from Rust, you must use the\n[`let_cxx_string!`] macro which will pin the string properly. The code below\nuses this in one place, and the link covers the syntax.\n\n[`let_cxx_string!`]: https://docs.rs/cxx/*/cxx/macro.let_cxx_string.html\n\n## Example\n\nThis example uses C++17's std::variant to build a toy JSON type. JSON can hold\nvarious types including strings, and JSON's object type is a map with string\nkeys. The example demonstrates Rust indexing into one of those maps.\n\n```rust,noplayground\n// src/main.rs\n\nuse cxx::let_cxx_string;\n\n#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        include!(\"example/include/json.h\");\n\n        #[cxx_name = \"json\"]\n        type Json;\n        #[cxx_name = \"object\"]\n        type Object;\n\n        fn isNull(self: &Json) -> bool;\n        fn isNumber(self: &Json) -> bool;\n        fn isString(self: &Json) -> bool;\n        fn isArray(self: &Json) -> bool;\n        fn isObject(self: &Json) -> bool;\n\n        fn getNumber(self: &Json) -> f64;\n        fn getString(self: &Json) -> &CxxString;\n        fn getArray(self: &Json) -> &CxxVector<Json>;\n        fn getObject(self: &Json) -> &Object;\n\n        #[cxx_name = \"at\"]\n        fn get<'a>(self: &'a Object, key: &CxxString) -> &'a Json;\n\n        fn load_config() -> UniquePtr<Json>;\n    }\n}\n\nfn main() {\n    let config = ffi::load_config();\n\n    let_cxx_string!(key = \"name\");\n    println!(\"{}\", config.getObject().get(&key).getString());\n}\n```\n\n```cpp\n// include/json.h\n\n#pragma once\n#include <map>\n#include <memory>\n#include <string>\n#include <variant>\n#include <vector>\n\nclass json final {\npublic:\n  static const json null;\n  using number = double;\n  using string = std::string;\n  using array = std::vector<json>;\n  using object = std::map<string, json>;\n\n  json() noexcept = default;\n  json(const json &) = default;\n  json(json &&) = default;\n  template <typename... T>\n  json(T &&...value) : value(std::forward<T>(value)...) {}\n\n  bool isNull() const;\n  bool isNumber() const;\n  bool isString() const;\n  bool isArray() const;\n  bool isObject() const;\n\n  number getNumber() const;\n  const string &getString() const;\n  const array &getArray() const;\n  const object &getObject() const;\n\nprivate:\n  std::variant<std::monostate, number, string, array, object> value;\n};\n\nusing object = json::object;\n\nstd::unique_ptr<json> load_config();\n```\n\n```cpp\n// include/json.cc\n\n#include \"example/include/json.h\"\n#include <initializer_list>\n#include <utility>\n\nconst json json::null{};\nbool json::isNull() const { return std::holds_alternative<std::monostate>(value); }\nbool json::isNumber() const { return std::holds_alternative<number>(value); }\nbool json::isString() const { return std::holds_alternative<string>(value); }\nbool json::isArray() const { return std::holds_alternative<array>(value); }\nbool json::isObject() const { return std::holds_alternative<object>(value); }\njson::number json::getNumber() const { return std::get<number>(value); }\nconst json::string &json::getString() const { return std::get<string>(value); }\nconst json::array &json::getArray() const { return std::get<array>(value); }\nconst json::object &json::getObject() const { return std::get<object>(value); }\n\nstd::unique_ptr<json> load_config() {\n  return std::make_unique<json>(\n      std::in_place_type<json::object>,\n      std::initializer_list<std::pair<const std::string, json>>{\n          {\"name\", \"cxx-example\"},\n          {\"edition\", 2021.},\n          {\"repository\", json::null}});\n}\n```\n"
  },
  {
    "path": "book/src/binding/cxxvector.md",
    "content": "{{#title std::vector<T> — Rust ♡ C++}}\n# std::vector\\<T\\>\n\nThe Rust binding of std::vector\\<T\\> is called **[`CxxVector<T>`]**. See the\nlink for documentation of the Rust API.\n\n[`CxxVector<T>`]: https://docs.rs/cxx/*/cxx/struct.CxxVector.html\n\n### Restrictions:\n\nRust code can never obtain a CxxVector by value. Instead in Rust code we will\nonly ever look at a vector behind a reference or smart pointer, as in\n&CxxVector\\<T\\> or UniquePtr\\<CxxVector\\<T\\>\\>.\n\nCxxVector\\<T\\> does not support T being an opaque Rust type. You should use a\nVec\\<T\\> (C++ rust::Vec\\<T\\>) instead for collections of opaque Rust types on\nthe language boundary.\n\n## Example\n\nThis program involves Rust code converting a `CxxVector<CxxString>` (i.e.\n`std::vector<std::string>`) into a Rust `Vec<String>`.\n\n```rust,noplayground\n// src/main.rs\n\n#![no_main] // main defined in C++ by main.cc\n\nuse cxx::{CxxString, CxxVector};\n\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        fn f(vec: &CxxVector<CxxString>);\n    }\n}\n\nfn f(vec: &CxxVector<CxxString>) {\n    let vec: Vec<String> = vec\n        .iter()\n        .map(|s| s.to_string_lossy().into_owned())\n        .collect();\n    g(&vec);\n}\n\nfn g(vec: &[String]) {\n    println!(\"{:?}\", vec);\n}\n```\n\n```cpp\n// src/main.cc\n\n#include \"example/src/main.rs.h\"\n#include <string>\n#include <vector>\n\nint main() {\n  std::vector<std::string> vec{\"fearless\", \"concurrency\"};\n  f(vec);\n}\n```\n"
  },
  {
    "path": "book/src/binding/fn.md",
    "content": "{{#title Function pointers — Rust ♡ C++}}\n# Function pointers\n\n### Public API:\n\n```cpp,hidelines=...\n// rust/cxx.h\n...\n...namespace rust {\n\ntemplate <typename Signature>\nclass Fn;\n\ntemplate <typename Ret, typename... Args>\nclass Fn<Ret(Args...)> final {\npublic:\n  Ret operator()(Args... args) const noexcept;\n  Fn operator*() const noexcept;\n};\n...\n...} // namespace rust\n```\n\n### Restrictions:\n\nFunction pointers with a Result return type are not implemented yet.\n\nPassing a function pointer from C++ to Rust is not implemented yet, only from\nRust to an `extern \"C++\"` function is implemented.\n\n## Example\n\nFunction pointers are commonly useful for implementing [async functions over\nFFI](../async.md). See the example code on that page.\n"
  },
  {
    "path": "book/src/binding/rawptr.md",
    "content": "{{#title *mut T, *const T — Rust ♡ C++}}\n# *mut T,&ensp;*const T\n\nGenerally you should use references (`&mut T`, `&T`) or [std::unique_ptr\\<T\\>]\nwhere possible over raw pointers, but raw pointers are available too as an\nunsafe fallback option.\n\n[std::unique_ptr\\<T\\>]: uniqueptr.md\n\n### Restrictions:\n\nExtern functions and function pointers taking a raw pointer as an argument must\nbe declared `unsafe fn` i.e. unsafe to call. The same does not apply to\nfunctions which only *return* a raw pointer, though presumably doing anything\nuseful with the returned pointer is going to involve unsafe code elsewhere\nanyway.\n\n## Example\n\nThis example illustrates making a Rust call to a canonical C-style `main`\nsignature involving `char *argv[]`.\n\n```cpp\n// include/args.h\n\n#pragma once\n\nvoid parseArgs(int argc, char *argv[]);\n```\n\n```cpp\n// src/args.cc\n\n#include \"example/include/args.h\"\n#include <iostream>\n\nvoid parseArgs(int argc, char *argv[]) {\n  std::cout << argc << std::endl;\n  for (int i = 0; i < argc; i++) {\n    std::cout << '\"' << argv[i] << '\"' << std::endl;\n  }\n}\n```\n\n```rust,noplayground\n// src/main.rs\n\nuse std::env;\nuse std::ffi::CString;\nuse std::os::raw::c_char;\nuse std::os::unix::ffi::OsStrExt;\nuse std::ptr;\n\n#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        include!(\"example/include/args.h\");\n\n        unsafe fn parseArgs(argc: i32, argv: *mut *mut c_char);\n    }\n}\n\nfn main() {\n    // Convert from OsString to nul-terminated CString, truncating each argument\n    // at the first inner nul byte if present.\n    let args: Vec<CString> = env::args_os()\n        .map(|os_str| {\n            let bytes = os_str.as_bytes();\n            CString::new(bytes).unwrap_or_else(|nul_error| {\n                let nul_position = nul_error.nul_position();\n                let mut bytes = nul_error.into_vec();\n                bytes.truncate(nul_position);\n                CString::new(bytes).unwrap()\n            })\n        })\n        .collect();\n\n    // Convert from Vec<CString> of owned strings to Vec<*mut c_char> of\n    // borrowed string pointers.\n    //\n    // Once extern type stabilizes (https://github.com/rust-lang/rust/issues/43467)\n    // and https://internals.rust-lang.org/t/pre-rfc-make-cstr-a-thin-pointer/6258\n    // is implemented, and CStr pointers become thin, we can sidestep this step\n    // by accumulating the args as Vec<Box<CStr>> up front, then simply casting\n    // from *mut [Box<CStr>] to *mut [*mut CStr] to *mut *mut c_char.\n    let argc = args.len();\n    let mut argv: Vec<*mut c_char> = Vec::with_capacity(argc + 1);\n    for arg in &args {\n        argv.push(arg.as_ptr() as *mut c_char);\n    }\n    argv.push(ptr::null_mut()); // Nul terminator.\n\n    unsafe {\n        ffi::parseArgs(argc as i32, argv.as_mut_ptr());\n    }\n\n    // The CStrings go out of scope here. C function must not have held on to\n    // the pointers beyond this point.\n}\n```\n"
  },
  {
    "path": "book/src/binding/result.md",
    "content": "{{#title Result<T> — Rust ♡ C++}}\n# Result\\<T\\>\n\nResult\\<T\\> is allowed as the return type of an extern function in either\ndirection. Its behavior is to translate to/from C++ exceptions. If your codebase\ndoes not use C++ exceptions, or prefers to represent fallibility using something\nlike outcome\\<T\\>, leaf::result\\<T\\>, StatusOr\\<T\\>, etc then you'll need to\nhandle the translation of those to Rust Result\\<T\\> using your own shims for\nnow. Better support for this is planned.\n\nIf an exception is thrown from an `extern \"C++\"` function that is *not* declared\nby the CXX bridge to return Result, the program calls C++'s `std::terminate`.\nThe behavior is equivalent to the same exception being thrown through a\n`noexcept` C++ function.\n\nIf a panic occurs in *any* `extern \"Rust\"` function, regardless of whether it is\ndeclared by the CXX bridge to return Result, a message is logged and the program\ncalls Rust's `std::process::abort`.\n\n## Returning Result from Rust to C++\n\nAn `extern \"Rust\"` function returning a Result turns into a `throw` in C++ if\nthe Rust side produces an error.\n\nNote that the return type written inside of cxx::bridge must be written without\na second type parameter. Only the Ok type is specified for the purpose of the\nFFI. The Rust *implementation* (outside of the bridge module) may pick any error\ntype as long as it has a std::fmt::Display impl.\n\n```rust,noplayground\n# use std::io;\n#\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        fn fallible1(depth: usize) -> Result<String>;\n        fn fallible2() -> Result<()>;\n    }\n}\n\nfn fallible1(depth: usize) -> anyhow::Result<String> {\n    if depth == 0 {\n        return Err(anyhow::Error::msg(\"fallible1 requires depth > 0\"));\n    }\n    ...\n}\n\nfn fallible2() -> Result<(), io::Error> {\n    ...\n    Ok(())\n}\n```\n\nThe exception that gets thrown by CXX on the C++ side is always of type\n`rust::Error` and has the following C++ public API. The `what()` member function\ngives the error message according to the Rust error's std::fmt::Display impl.\n\n```cpp,hidelines=...\n// rust/cxx.h\n...\n...namespace rust {\n\nclass Error final : public std::exception {\npublic:\n  Error(const Error &);\n  Error(Error &&) noexcept;\n  ~Error() noexcept;\n\n  Error &operator=(const Error &) &;\n  Error &operator=(Error &&) & noexcept;\n\n  const char *what() const noexcept override;\n};\n...\n...} // namespace rust\n```\n\n## Returning Result from C++ to Rust\n\nAn `extern \"C++\"` function returning a Result turns into a `catch` in C++ that\nconverts the exception into an Err for Rust.\n\nNote that the return type written inside of cxx::bridge must be written without\na second type parameter. Only the Ok type is specified for the purpose of the\nFFI. The resulting error type created by CXX when an `extern \"C++\"` function\nthrows will always be of type **[`cxx::Exception`]**.\n\n[`cxx::Exception`]: https://docs.rs/cxx/*/cxx/struct.Exception.html\n\n```rust,noplayground\n# use std::process;\n#\n#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        include!(\"example/include/example.h\");\n        fn fallible1(depth: usize) -> Result<String>;\n        fn fallible2() -> Result<()>;\n    }\n}\n\nfn main() {\n    if let Err(err) = ffi::fallible1(99) {\n        eprintln!(\"Error: {}\", err);\n        process::exit(1);\n    }\n}\n```\n\nThe specific set of caught exceptions and the conversion to error message are\nboth customizable. The way you do this is by defining a template function\n`rust::behavior::trycatch` with a suitable signature inside any one of the\nheaders `include!`'d by your cxx::bridge.\n\nThe template signature is required to be:\n\n```cpp\nnamespace rust {\nnamespace behavior {\n\ntemplate <typename Try, typename Fail>\nstatic void trycatch(Try &&func, Fail &&fail) noexcept;\n\n} // namespace behavior\n} // namespace rust\n```\n\nThe default `trycatch` used by CXX if you have not provided your own is the\nfollowing. You must follow the same pattern: invoke `func` with no arguments,\ncatch whatever exception(s) you want, and invoke `fail` with the error message\nyou'd like for the Rust error to have.\n\n```cpp,hidelines=...\n...#include <exception>\n...\n...namespace rust {\n...namespace behavior {\n...\ntemplate <typename Try, typename Fail>\nstatic void trycatch(Try &&func, Fail &&fail) noexcept try {\n  func();\n} catch (const std::exception &e) {\n  fail(e.what());\n}\n...\n...} // namespace behavior\n...} // namespace rust\n```\n"
  },
  {
    "path": "book/src/binding/sharedptr.md",
    "content": "{{#title std::shared_ptr<T> — Rust ♡ C++}}\n# std::shared\\_ptr\\<T\\>\n\nThe Rust binding of std::shared\\_ptr\\<T\\> is called **[`SharedPtr<T>`]**. See\nthe link for documentation of the Rust API.\n\n[`SharedPtr<T>`]: https://docs.rs/cxx/*/cxx/struct.SharedPtr.html\n\n### Restrictions:\n\nSharedPtr\\<T\\> does not support T being an opaque Rust type. You should use a\nBox\\<T\\> (C++ [rust::Box\\<T\\>](box.md)) instead for transferring ownership of\nopaque Rust types on the language boundary.\n\n## Example\n\n```rust,noplayground\n// src/main.rs\n\nuse std::ops::Deref;\nuse std::ptr;\n\n#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        include!(\"example/include/example.h\");\n\n        type Object;\n\n        fn create_shared_ptr() -> SharedPtr<Object>;\n    }\n}\n\nfn main() {\n    let ptr1 = ffi::create_shared_ptr();\n\n    {\n        // Create a second shared_ptr holding shared ownership of the same\n        // object. There is still only one Object but two SharedPtr<Object>.\n        // Both pointers point to the same object on the heap.\n        let ptr2 = ptr1.clone();\n        assert!(ptr::eq(ptr1.deref(), ptr2.deref()));\n\n        // ptr2 goes out of scope, but Object is not destroyed yet.\n    }\n\n    println!(\"say goodbye to Object\");\n\n    // ptr1 goes out of scope and Object is destroyed.\n}\n```\n\n```cpp\n// include/example.h\n\n#pragma once\n#include <memory>\n\nclass Object {\npublic:\n  Object();\n  ~Object();\n};\n\nstd::shared_ptr<Object> create_shared_ptr();\n```\n\n```cpp\n// src/example.cc\n\n#include \"example/include/example.h\"\n#include <iostream>\n\nObject::Object() { std::cout << \"construct Object\" << std::endl; }\nObject::~Object() { std::cout << \"~Object\" << std::endl; }\n\nstd::shared_ptr<Object> create_shared_ptr() {\n  return std::make_shared<Object>();\n}\n```\n"
  },
  {
    "path": "book/src/binding/slice.md",
    "content": "{{#title rust::Slice<T> — Rust ♡ C++}}\n# rust::Slice\\<const T\\>,&ensp;rust::Slice\\<T\\>\n\n- Rust `&[T]` is written `rust::Slice<const T>` in C++\n- Rust `&mut [T]` is written `rust::Slice<T>` in C++\n\n### Public API:\n\n```cpp,hidelines=...\n// rust/cxx.h\n...\n...#include <iterator>\n...#include <type_traits>\n...\n...namespace rust {\n\ntemplate <typename T>\nclass Slice final {\npublic:\n  using value_type = T;\n\n  Slice() noexcept;\n  Slice(const Slice<T> &) noexcept;\n  Slice(T *, size_t count) noexcept;\n\n  template <typename C>\n  explicit Slice(C &c) : Slice(c.data(), c.size());\n\n  Slice &operator=(Slice<T> &&) & noexcept;\n  Slice &operator=(const Slice<T> &) & noexcept\n    requires std::is_const_v<T>;\n\n  T *data() const noexcept;\n  size_t size() const noexcept;\n  bool empty() const noexcept;\n\n  T &operator[](size_t n) const noexcept;\n  T &at(size_t n) const;\n  T &front() const noexcept;\n  T &back() const noexcept;\n\n  class iterator;\n  iterator begin() const noexcept;\n  iterator end() const noexcept;\n\n  void swap(Slice &) noexcept;\n};\n...\n...template <typename T>\n...class Slice<T>::iterator final {\n...public:\n...#if __cplusplus >= 202002L\n...  using iterator_category = std::contiguous_iterator_tag;\n...#else\n...  using iterator_category = std::random_access_iterator_tag;\n...#endif\n...  using value_type = T;\n...  using pointer = T *;\n...  using reference = T &;\n...\n...  T &operator*() const noexcept;\n...  T *operator->() const noexcept;\n...  T &operator[](ptrdiff_t) const noexcept;\n...\n...  iterator &operator++() noexcept;\n...  iterator operator++(int) noexcept;\n...  iterator &operator--() noexcept;\n...  iterator operator--(int) noexcept;\n...\n...  iterator &operator+=(ptrdiff_t) noexcept;\n...  iterator &operator-=(ptrdiff_t) noexcept;\n...  iterator operator+(ptrdiff_t) const noexcept;\n...  iterator operator-(ptrdiff_t) const noexcept;\n...  ptrdiff_t operator-(const iterator &) const noexcept;\n...\n...  bool operator==(const iterator &) const noexcept;\n...  bool operator!=(const iterator &) const noexcept;\n...  bool operator<(const iterator &) const noexcept;\n...  bool operator>(const iterator &) const noexcept;\n...  bool operator<=(const iterator &) const noexcept;\n...  bool operator>=(const iterator &) const noexcept;\n...};\n...\n...} // namespace rust\n```\n\n### Restrictions:\n\nT must not be an opaque Rust type or opaque C++ type. Support for opaque Rust\ntypes in slices is coming.\n\nAllowed as function argument or return value. Not supported in shared structs.\n\nOnly rust::Slice\\<const T\\> is copy-assignable, not rust::Slice\\<T\\>. (Both are\nmove-assignable.) You'll need to write std::move occasionally as a reminder that\naccidentally exposing overlapping &amp;mut \\[T\\] to Rust is UB.\n\n## Example\n\nThis example is a C++ program that constructs a slice containing JSON data (by\nreading from stdin, but it could be from anywhere), then calls into Rust to\npretty-print that JSON data into a std::string via the [serde_json] and\n[serde_transcode] crates.\n\n[serde_json]: https://github.com/serde-rs/json\n[serde_transcode]: https://github.com/sfackler/serde-transcode\n\n```rust,noplayground\n// src/main.rs\n\n#![no_main] // main defined in C++ by main.cc\n\nuse cxx::CxxString;\nuse std::io::{self, Write};\nuse std::pin::Pin;\n\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        fn prettify_json(input: &[u8], output: Pin<&mut CxxString>) -> Result<()>;\n    }\n}\n\nstruct WriteToCxxString<'a>(Pin<&'a mut CxxString>);\n\nimpl<'a> Write for WriteToCxxString<'a> {\n    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n        self.0.as_mut().push_bytes(buf);\n        Ok(buf.len())\n    }\n    fn flush(&mut self) -> io::Result<()> {\n        Ok(())\n    }\n}\n\nfn prettify_json(input: &[u8], output: Pin<&mut CxxString>) -> serde_json::Result<()> {\n    let writer = WriteToCxxString(output);\n    let mut deserializer = serde_json::Deserializer::from_slice(input);\n    let mut serializer = serde_json::Serializer::pretty(writer);\n    serde_transcode::transcode(&mut deserializer, &mut serializer)\n}\n```\n\n```cpp\n// src/main.cc\n\n#include \"example/src/main.rs.h\"\n#include <iostream>\n#include <iterator>\n#include <string>\n#include <vector>\n\nint main() {\n  // Read json from stdin.\n  std::istreambuf_iterator<char> begin{std::cin}, end;\n  std::vector<unsigned char> input{begin, end};\n  rust::Slice<const uint8_t> slice{input.data(), input.size()};\n\n  // Prettify using serde_json and serde_transcode.\n  std::string output;\n  prettify_json(slice, output);\n\n  // Write to stdout.\n  std::cout << output << std::endl;\n}\n```\n\nTesting the example:\n\n```console\n$  echo '{\"fearless\":\"concurrency\"}' | cargo run\n    Finished dev [unoptimized + debuginfo] target(s) in 0.02s\n     Running `target/debug/example`\n{\n  \"fearless\": \"concurrency\"\n}\n```\n"
  },
  {
    "path": "book/src/binding/str.md",
    "content": "{{#title rust::Str — Rust ♡ C++}}\n# rust::Str\n\n### Public API:\n\n```cpp,hidelines=...\n// rust/cxx.h\n...\n...#include <iosfwd>\n...#include <string>\n...\n...namespace rust {\n\nclass Str final {\npublic:\n  Str() noexcept;\n  Str(const Str &) noexcept;\n  Str(const String &) noexcept;\n\n  // Throws std::invalid_argument if not utf-8.\n  Str(const std::string &);\n  Str(const char *);\n  Str(const char *, size_t);\n\n  Str &operator=(const Str &) & noexcept;\n\n  explicit operator std::string() const;\n#if __cplusplus >= 201703L\n  explicit operator std::string_view() const;\n#endif\n\n  // Note: no null terminator.\n  const char *data() const noexcept;\n  // Length in bytes.\n  size_t size() const noexcept;\n  // Length in bytes, same as size().\n  size_t length() const noexcept;\n  bool empty() const noexcept;\n\n  using iterator = const char *;\n  using const_iterator = const char *;\n  const_iterator begin() const noexcept;\n  const_iterator end() const noexcept;\n  const_iterator cbegin() const noexcept;\n  const_iterator cend() const noexcept;\n\n  bool operator==(const Str &) const noexcept;\n  bool operator!=(const Str &) const noexcept;\n  bool operator<(const Str &) const noexcept;\n  bool operator<=(const Str &) const noexcept;\n  bool operator>(const Str &) const noexcept;\n  bool operator>=(const Str &) const noexcept;\n\n  void swap(Str &) noexcept;\n};\n\nstd::ostream &operator<<(std::ostream &, const Str &);\n...\n...} // namespace rust\n```\n\n### Notes:\n\n**Be aware that rust::Str behaves like &amp;str i.e. it is a borrow!**&ensp;C++\nneeds to be mindful of the lifetimes at play.\n\nJust to reiterate: &amp;str is rust::Str. Do not try to write &amp;str as `const\nrust::Str &`. A language-level C++ reference is not able to capture the fat\npointer nature of &amp;str.\n\n### Restrictions:\n\nAllowed as function argument or return value. Not supported in shared structs\nyet. `&mut str` is not supported yet, but is also extremely obscure so this is\nfine.\n\n## Example\n\n```rust,noplayground\n// src/main.rs\n\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        fn r(greeting: &str);\n    }\n\n    unsafe extern \"C++\" {\n        include!(\"example/include/greeting.h\");\n        fn c(greeting: &str);\n    }\n}\n\nfn r(greeting: &str) {\n    println!(\"{}\", greeting);\n}\n\nfn main() {\n    ffi::c(\"hello from Rust\");\n}\n```\n\n```cpp\n// include/greeting.h\n\n#pragma once\n#include \"example/src/main.rs.h\"\n#include \"rust/cxx.h\"\n\nvoid c(rust::Str greeting);\n```\n\n```cpp\n// src/greeting.cc\n\n#include \"example/include/greeting.h\"\n#include <iostream>\n\nvoid c(rust::Str greeting) {\n  std::cout << greeting << std::endl;\n  r(\"hello from C++\");\n}\n```\n"
  },
  {
    "path": "book/src/binding/string.md",
    "content": "{{#title rust::String — Rust ♡ C++}}\n# rust::String\n\n### Public API:\n\n```cpp,hidelines=...\n// rust/cxx.h\n...\n...#include <iosfwd>\n...#include <string>\n...\n...namespace rust {\n\nclass String final {\npublic:\n  String() noexcept;\n  String(const String &) noexcept;\n  String(String &&) noexcept;\n  ~String() noexcept;\n\n  // Throws std::invalid_argument if not UTF-8.\n  String(const std::string &);\n  String(const char *);\n  String(const char *, size_t);\n  String(const char8_t *);\n  String(const char8_t *, size_t);\n\n  // Replaces invalid UTF-8 data with the replacement character (U+FFFD).\n  static String lossy(const std::string &) noexcept;\n  static String lossy(const char *) noexcept;\n  static String lossy(const char *, size_t) noexcept;\n\n  // Throws std::invalid_argument if not UTF-16.\n  String(const char16_t *);\n  String(const char16_t *, size_t);\n\n  // Replaces invalid UTF-16 data with the replacement character (U+FFFD).\n  static String lossy(const char16_t *) noexcept;\n  static String lossy(const char16_t *, size_t) noexcept;\n\n  String &operator=(const String &) & noexcept;\n  String &operator=(String &&) & noexcept;\n\n  explicit operator std::string() const;\n\n  // Note: no null terminator.\n  const char *data() const noexcept;\n  // Length in bytes.\n  size_t size() const noexcept;\n  // Length in bytes, same as size().\n  size_t length() const noexcept;\n  bool empty() const noexcept;\n\n  const char *c_str() noexcept;\n\n  size_t capacity() const noexcept;\n  void reserve(size_t new_cap) noexcept;\n\n  using iterator = char *;\n  iterator begin() noexcept;\n  iterator end() noexcept;\n\n  using const_iterator = const char *;\n  const_iterator begin() const noexcept;\n  const_iterator end() const noexcept;\n  const_iterator cbegin() const noexcept;\n  const_iterator cend() const noexcept;\n\n  bool operator==(const String &) const noexcept;\n  bool operator!=(const String &) const noexcept;\n  bool operator<(const String &) const noexcept;\n  bool operator<=(const String &) const noexcept;\n  bool operator>(const String &) const noexcept;\n  bool operator>=(const String &) const noexcept;\n\n  void swap(String &) noexcept;\n};\n\nstd::ostream &operator<<(std::ostream &, const String &);\n...\n...} // namespace rust\n```\n\n### Restrictions:\n\nNone. Strings may be used as function arguments and function return values, by\nvalue or by reference, as well as fields of shared structs.\n\n## Example\n\n```rust,noplayground\n// src/main.rs\n\n#[cxx::bridge]\nmod ffi {\n    struct ConcatRequest {\n        fst: String,\n        snd: String,\n    }\n\n    unsafe extern \"C++\" {\n        include!(\"example/include/concat.h\");\n        fn concat(r: ConcatRequest) -> String;\n    }\n}\n\nfn main() {\n    let concatenated = ffi::concat(ffi::ConcatRequest {\n        fst: \"fearless\".to_owned(),\n        snd: \"concurrency\".to_owned(),\n    });\n    println!(\"concatenated: {:?}\", concatenated);\n}\n```\n\n```cpp\n// include/concat.h\n\n#pragma once\n#include \"example/src/main.rs.h\"\n#include \"rust/cxx.h\"\n\nrust::String concat(ConcatRequest r);\n```\n\n```cpp\n// src/concat.cc\n\n#include \"example/include/concat.h\"\n\nrust::String concat(ConcatRequest r) {\n  // The full suite of operator overloads hasn't been added\n  // yet on rust::String, but we can get it done like this:\n  return std::string(r.fst) + std::string(r.snd);\n}\n```\n"
  },
  {
    "path": "book/src/binding/uniqueptr.md",
    "content": "{{#title std::unique_ptr<T> — Rust ♡ C++}}\n# std::unique\\_ptr\\<T\\>\n\nThe Rust binding of std::unique\\_ptr\\<T\\> is called **[`UniquePtr<T>`]**. See\nthe link for documentation of the Rust API.\n\n[`UniquePtr<T>`]: https://docs.rs/cxx/*/cxx/struct.UniquePtr.html\n\n### Restrictions:\n\nOnly `std::unique_ptr<T, std::default_delete<T>>` is currently supported. Custom\ndeleters may be supported in the future.\n\nUniquePtr\\<T\\> does not support T being an opaque Rust type. You should use a\nBox\\<T\\> (C++ [rust::Box\\<T\\>](box.md)) instead for transferring ownership of\nopaque Rust types on the language boundary.\n\n## Example\n\nUniquePtr is commonly useful for returning opaque C++ objects to Rust. This use\ncase was featured in the [*blobstore tutorial*](../tutorial.md).\n\n```rust,noplayground\n// src/main.rs\n\n#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        include!(\"example/include/blobstore.h\");\n\n        type BlobstoreClient;\n\n        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;\n        // ...\n    }\n}\n\nfn main() {\n    let client = ffi::new_blobstore_client();\n    // ...\n}\n```\n\n```cpp\n// include/blobstore.h\n\n#pragma once\n#include <memory>\n\nclass BlobstoreClient;\n\nstd::unique_ptr<BlobstoreClient> new_blobstore_client();\n```\n\n```cpp\n// src/blobstore.cc\n\n#include \"example/include/blobstore.h\"\n\nstd::unique_ptr<BlobstoreClient> new_blobstore_client() {\n  return std::make_unique<BlobstoreClient>();\n}\n```\n"
  },
  {
    "path": "book/src/binding/vec.md",
    "content": "{{#title rust::Vec<T> — Rust ♡ C++}}\n# rust::Vec\\<T\\>\n\n### Public API:\n\n```cpp,hidelines=...\n// rust/cxx.h\n...\n...#include <initializer_list>\n...#include <iterator>\n...#include <type_traits>\n...\n...namespace rust {\n\ntemplate <typename T>\nclass Vec final {\npublic:\n  using value_type = T;\n\n  Vec() noexcept;\n  Vec(std::initializer_list<T>);\n  Vec(const Vec &);\n  Vec(Vec &&) noexcept;\n  ~Vec() noexcept;\n\n  Vec &operator=(Vec &&) & noexcept;\n  Vec &operator=(const Vec &) &;\n\n  size_t size() const noexcept;\n  bool empty() const noexcept;\n  const T *data() const noexcept;\n  T *data() noexcept;\n  size_t capacity() const noexcept;\n\n  const T &operator[](size_t n) const noexcept;\n  const T &at(size_t n) const;\n  const T &front() const;\n  const T &back() const;\n\n  T &operator[](size_t n) noexcept;\n  T &at(size_t n);\n  T &front();\n  T &back();\n\n  void reserve(size_t new_cap);\n  void push_back(const T &value);\n  void push_back(T &&value);\n  template <typename... Args>\n  void emplace_back(Args &&...args);\n  void truncate(size_t len);\n  void clear();\n\n  class iterator;\n  iterator begin() noexcept;\n  iterator end() noexcept;\n\n  class const_iterator;\n  const_iterator begin() const noexcept;\n  const_iterator end() const noexcept;\n  const_iterator cbegin() const noexcept;\n  const_iterator cend() const noexcept;\n\n  void swap(Vec &) noexcept;\n};\n...\n...template <typename T>\n...class Vec<T>::iterator final {\n...public:\n...#if __cplusplus >= 202002L\n...  using iterator_category = std::contiguous_iterator_tag;\n...#else\n...  using iterator_category = std::random_access_iterator_tag;\n...#endif\n...  using value_type = T;\n...  using pointer = T *;\n...  using reference = T &;\n...\n...  T &operator*() const noexcept;\n...  T *operator->() const noexcept;\n...  T &operator[](ptrdiff_t) const noexcept;\n...\n...  iterator &operator++() noexcept;\n...  iterator operator++(int) noexcept;\n...  iterator &operator--() noexcept;\n...  iterator operator--(int) noexcept;\n...\n...  iterator &operator+=(ptrdiff_t) noexcept;\n...  iterator &operator-=(ptrdiff_t) noexcept;\n...  iterator operator+(ptrdiff_t) const noexcept;\n...  iterator operator-(ptrdiff_t) const noexcept;\n...  ptrdiff_t operator-(const iterator &) const noexcept;\n...\n...  bool operator==(const iterator &) const noexcept;\n...  bool operator!=(const iterator &) const noexcept;\n...  bool operator<(const iterator &) const noexcept;\n...  bool operator<=(const iterator &) const noexcept;\n...  bool operator>(const iterator &) const noexcept;\n...  bool operator>=(const iterator &) const noexcept;\n...};\n...\n...template <typename T>\n...class Vec<T>::const_iterator final {\n...public:\n...#if __cplusplus >= 202002L\n...  using iterator_category = std::contiguous_iterator_tag;\n...#else\n...  using iterator_category = std::random_access_iterator_tag;\n...#endif\n...  using value_type = const T;\n...  using pointer = const T *;\n...  using reference = const T &;\n...\n...  const T &operator*() const noexcept;\n...  const T *operator->() const noexcept;\n...  const T &operator[](ptrdiff_t) const noexcept;\n...\n...  const_iterator &operator++() noexcept;\n...  const_iterator operator++(int) noexcept;\n...  const_iterator &operator--() noexcept;\n...  const_iterator operator--(int) noexcept;\n...\n...  const_iterator &operator+=(ptrdiff_t) noexcept;\n...  const_iterator &operator-=(ptrdiff_t) noexcept;\n...  const_iterator operator+(ptrdiff_t) const noexcept;\n...  const_iterator operator-(ptrdiff_t) const noexcept;\n...  ptrdiff_t operator-(const const_iterator &) const noexcept;\n...\n...  bool operator==(const const_iterator &) const noexcept;\n...  bool operator!=(const const_iterator &) const noexcept;\n...  bool operator<(const const_iterator &) const noexcept;\n...  bool operator<=(const const_iterator &) const noexcept;\n...  bool operator>(const const_iterator &) const noexcept;\n...  bool operator>=(const const_iterator &) const noexcept;\n...};\n...\n...} // namespace rust\n```\n\n### Restrictions:\n\nVec\\<T\\> does not support T being an opaque C++ type. You should use\nCxxVector\\<T\\> (C++ std::vector\\<T\\>) instead for collections of opaque C++\ntypes on the language boundary.\n\n## Example\n\n```rust,noplayground\n// src/main.rs\n\n#[cxx::bridge]\nmod ffi {\n    struct Shared {\n        v: u32,\n    }\n\n    unsafe extern \"C++\" {\n        include!(\"example/include/example.h\");\n\n        fn f(elements: Vec<Shared>);\n    }\n}\n\nfn main() {\n    let shared = |v| ffi::Shared { v };\n    let elements = vec![shared(3), shared(2), shared(1)];\n    ffi::f(elements);\n}\n```\n\n```cpp\n// include/example.h\n\n#pragma once\n#include \"example/src/main.rs.h\"\n#include \"rust/cxx.h\"\n\nvoid f(rust::Vec<Shared> elements);\n```\n\n```cpp\n// src/example.cc\n\n#include \"example/include/example.h\"\n#include <algorithm>\n#include <cassert>\n#include <iostream>\n#include <iterator>\n#include <vector>\n\nvoid f(rust::Vec<Shared> v) {\n  for (auto shared : v) {\n    std::cout << shared.v << std::endl;\n  }\n\n  // Copy the elements to a C++ std::vector using STL algorithm.\n  std::vector<Shared> stdv;\n  std::copy(v.begin(), v.end(), std::back_inserter(stdv));\n  assert(v.size() == stdv.size());\n}\n```\n"
  },
  {
    "path": "book/src/bindings.md",
    "content": "{{#title Built-in bindings — Rust ♡ C++}}\n# Built-in bindings reference\n\nIn addition to all the primitive types (i32 &lt;=&gt; int32_t), the following\ncommon types may be used in the fields of shared structs and the arguments and\nreturns of extern functions.\n\n<br>\n\n<table>\n<tr><th>name in Rust</th><th>name in C++</th><th>restrictions</th></tr>\n<tr><td style=\"padding:3px 6px\">String</td><td style=\"padding:3px 6px\"><b><a href=\"binding/string.md\">rust::String</a></b></td><td style=\"padding:3px 6px\"></td></tr>\n<tr><td style=\"padding:3px 6px\">&amp;str</td><td style=\"padding:3px 6px\"><b><a href=\"binding/str.md\">rust::Str</a></b></td><td style=\"padding:3px 6px\"></td></tr>\n<tr><td style=\"padding:3px 6px\">&amp;[T]</td><td style=\"padding:3px 6px\"><b><a href=\"binding/slice.md\">rust::Slice&lt;const&nbsp;T&gt;</a></b></td><td style=\"padding:3px 6px\"><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n<tr><td style=\"padding:3px 6px\">&amp;mut [T]</td><td style=\"padding:3px 6px\"><b><a href=\"binding/slice.md\">rust::Slice&lt;T&gt;</a></b></td><td style=\"padding:3px 6px\"><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n<tr><td style=\"padding:3px 6px\"><b><a href=\"binding/cxxstring.md\">CxxString</a></b></td><td style=\"padding:3px 6px\">std::string</td><td style=\"padding:3px 6px\"><sup><i>cannot be passed by value</i></sup></td></tr>\n<tr><td style=\"padding:3px 6px\">Box&lt;T&gt;</td><td style=\"padding:3px 6px\"><b><a href=\"binding/box.md\">rust::Box&lt;T&gt;</a></b></td><td style=\"padding:3px 6px\"><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n<tr><td style=\"padding:3px 6px\"><b><a href=\"binding/uniqueptr.md\">UniquePtr&lt;T&gt;</a></b></td><td style=\"padding:3px 6px\">std::unique_ptr&lt;T&gt;</td><td style=\"padding:3px 6px\"><sup><i>cannot hold opaque Rust type</i></sup></td></tr>\n<tr><td style=\"padding:3px 6px\"><b><a href=\"binding/sharedptr.md\">SharedPtr&lt;T&gt;</a></b></td><td style=\"padding:3px 6px\">std::shared_ptr&lt;T&gt;</td><td style=\"padding:3px 6px\"><sup><i>cannot hold opaque Rust type</i></sup></td></tr>\n<tr><td style=\"padding:3px 6px\">[T; N]</td><td style=\"padding:3px 6px\">std::array&lt;T, N&gt;</td><td style=\"padding:3px 6px\"><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n<tr><td style=\"padding:3px 6px\">Vec&lt;T&gt;</td><td style=\"padding:3px 6px\"><b><a href=\"binding/vec.md\">rust::Vec&lt;T&gt;</a></b></td><td style=\"padding:3px 6px\"><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n<tr><td style=\"padding:3px 6px\"><b><a href=\"binding/cxxvector.md\">CxxVector&lt;T&gt;</a></b></td><td style=\"padding:3px 6px\">std::vector&lt;T&gt;</td><td style=\"padding:3px 6px\"><sup><i>cannot be passed by value, cannot hold opaque Rust type</i></sup></td></tr>\n<tr><td style=\"padding:3px 6px\"><b><a href=\"binding/rawptr.md\">*mut T, *const T</a></b></td><td style=\"padding:3px 6px\">T*, const T*</td><td style=\"padding:3px 6px\"><sup><i>fn with a raw pointer argument must be declared unsafe to call</i></sup></td></tr>\n<tr><td style=\"padding:3px 6px\">fn(T, U) -&gt; V</td><td style=\"padding:3px 6px\"><b><a href=\"binding/fn.md\">rust::Fn&lt;V(T, U)&gt;</a></b></td><td style=\"padding:3px 6px\"><sup><i>only passing from Rust to C++ is implemented so far</i></sup></td></tr>\n<tr><td style=\"padding:3px 6px\"><b><a href=\"binding/result.md\">Result&lt;T&gt;</a></b></td><td style=\"padding:3px 6px\">throw/catch</td><td style=\"padding:3px 6px\"><sup><i>allowed as return type only</i></sup></td></tr>\n</table>\n\n<br>\n\nThe C++ API of the `rust` namespace is defined by the *include/cxx.h* file in\nthe CXX GitHub repo. You will need to include this header in your C++ code when\nworking with those types. **When using Cargo and the cxx-build crate, the header\nis made available to you at `#include \"rust/cxx.h\"`.**\n\nThe `rust` namespace additionally provides lowercase type aliases of all the\ntypes mentioned in the table, for use in codebases preferring that style. For\nexample `rust::String`, `rust::Vec` may alternatively be written `rust::string`,\n`rust::vec` etc.\n\n## Pending bindings\n\nThe following types are intended to be supported \"soon\" but are just not\nimplemented yet. I don't expect any of these to be hard to make work but it's a\nmatter of designing a nice API for each in its non-native language.\n\n<br>\n\n<table>\n<tr><th>name in Rust</th><th>name in C++</th></tr>\n<tr><td>BTreeMap&lt;K, V&gt;</td><td><sup><i>tbd</i></sup></td></tr>\n<tr><td>HashMap&lt;K, V&gt;</td><td><sup><i>tbd</i></sup></td></tr>\n<tr><td>Arc&lt;T&gt;</td><td><sup><i>tbd</i></sup></td></tr>\n<tr><td>Option&lt;T&gt;</td><td><sup><i>tbd</i></sup></td></tr>\n<tr><td><sup><i>tbd</i></sup></td><td>std::map&lt;K, V&gt;</td></tr>\n<tr><td><sup><i>tbd</i></sup></td><td>std::unordered_map&lt;K, V&gt;</td></tr>\n</table>\n"
  },
  {
    "path": "book/src/build/bazel.md",
    "content": "{{#title Bazel, Buck2 — Rust ♡ C++}}\n## Bazel, Buck2, potentially other similar environments\n\nStarlark-based build systems with the ability to compile a code generator and\ninvoke it as a `genrule` will run CXX's C++ code generator via its `cxxbridge`\ncommand line interface.\n\nThe tool is packaged as the `cxxbridge-cmd` crate on crates.io or can be built\nfrom the *gen/cmd/* directory of the CXX GitHub repo.\n\n```console\n$  cargo install cxxbridge-cmd\n\n$  cxxbridge src/bridge.rs --header > path/to/bridge.rs.h\n$  cxxbridge src/bridge.rs > path/to/bridge.rs.cc\n```\n\n<div class=\"warning\">\n\n**Important:** The version number of `cxxbridge-cmd` used for the C++ side of\nthe binding must always be identical to the version number of `cxx` used for the\nRust side. You must use some form of lockfile or version pinning to ensure that\nthis is the case.\n\n</div>\n\nThe CXX repo maintains working [Bazel] `BUILD.bazel` and [Buck2] `BUCK` targets\nfor the complete blobstore tutorial (chapter 3) for your reference, tested in\nCI. These aren't meant to be directly what you use in your codebase, but serve\nas an illustration of one possible working pattern.\n\n[Bazel]: https://bazel.build\n[Buck2]: https://buck2.build\n\n```python\n# tools/bazel/rust_cxx_bridge.bzl\n\nload(\"@bazel_skylib//rules:run_binary.bzl\", \"run_binary\")\nload(\"@rules_cc//cc:defs.bzl\", \"cc_library\")\n\ndef rust_cxx_bridge(name, src, deps = []):\n    native.alias(\n        name = \"%s/header\" % name,\n        actual = src + \".h\",\n    )\n\n    native.alias(\n        name = \"%s/source\" % name,\n        actual = src + \".cc\",\n    )\n\n    run_binary(\n        name = \"%s/generated\" % name,\n        srcs = [src],\n        outs = [\n            src + \".h\",\n            src + \".cc\",\n        ],\n        args = [\n            \"$(location %s)\" % src,\n            \"-o\",\n            \"$(location %s.h)\" % src,\n            \"-o\",\n            \"$(location %s.cc)\" % src,\n        ],\n        tool = \"//:codegen\",\n    )\n\n    cc_library(\n        name = name,\n        srcs = [src + \".cc\"],\n        deps = deps + [\":%s/include\" % name],\n    )\n\n    cc_library(\n        name = \"%s/include\" % name,\n        hdrs = [src + \".h\"],\n    )\n```\n\n```python\n# demo/BUILD.bazel\n\nload(\"@rules_cc//cc:defs.bzl\", \"cc_library\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_binary\")\nload(\"//tools/bazel:rust_cxx_bridge.bzl\", \"rust_cxx_bridge\")\n\nrust_binary(\n    name = \"demo\",\n    srcs = glob([\"src/**/*.rs\"]),\n    deps = [\n        \":blobstore-sys\",\n        \":bridge\",\n        \"//:cxx\",\n    ],\n)\n\nrust_cxx_bridge(\n    name = \"bridge\",\n    src = \"src/main.rs\",\n    deps = [\":blobstore-include\"],\n)\n\ncc_library(\n    name = \"blobstore-sys\",\n    srcs = [\"src/blobstore.cc\"],\n    deps = [\n        \":blobstore-include\",\n        \":bridge/include\",\n    ],\n)\n\ncc_library(\n    name = \"blobstore-include\",\n    hdrs = [\"include/blobstore.h\"],\n    deps = [\"//:core\"],\n)\n```\n"
  },
  {
    "path": "book/src/build/cargo.md",
    "content": "{{#title Cargo-based setup — Rust ♡ C++}}\n# Cargo-based builds\n\nAs one aspect of delivering a good Rust&ndash;C++ interop experience, CXX turns\nCargo into a quite usable build system for C++ projects published as a\ncollection of crates.io packages, including a consistent and frictionless\nexperience `#include`-ing C++ headers across dependencies.\n\n## Canonical setup\n\nCXX's integration with Cargo is handled through the [cxx-build] crate.\n\n[cxx-build]: https://docs.rs/cxx-build\n\n```toml,hidelines=...\n# Cargo.toml\n...[package]\n...name = \"...\"\n...version = \"...\"\n...edition = \"2021\"\n\n[dependencies]\ncxx = \"1.0\"\n\n[build-dependencies]\ncxx-build = \"1.0\"\n```\n\nThe canonical build script is as follows. The indicated line returns a\n[`cc::Build`] instance (from the usual widely used `cc` crate) on which you can\nset up any additional source files and compiler flags as normal.\n\n[`cc::Build`]: https://docs.rs/cc/1.0/cc/struct.Build.html\n\n```rust,noplayground\n// build.rs\n\nfn main() {\n    cxx_build::bridge(\"src/main.rs\")  // returns a cc::Build\n        .file(\"src/demo.cc\")\n        .std(\"c++11\")\n        .compile(\"cxxbridge-demo\");\n\n    println!(\"cargo:rerun-if-changed=src/demo.cc\");\n    println!(\"cargo:rerun-if-changed=include/demo.h\");\n}\n```\n\nThe `rerun-if-changed` lines are optional but make it so that Cargo does not\nspend time recompiling your C++ code when only non-C++ code has changed since\nthe previous Cargo build. By default without any `rerun-if-changed`, Cargo will\nre-execute the build script after *any* file changed in the project.\n\nIf stuck, try comparing what you have against the *demo/* directory of the CXX\nGitHub repo, which maintains a working Cargo-based setup for the blobstore\ntutorial (chapter 3).\n\n## Header include paths\n\nWith cxx-build, by default your include paths always start with the crate name.\nThis applies to both `#include` within your C++ code, and `include!` in the\n`extern \"C++\"` section of your Rust cxx::bridge.\n\nYour crate name is determined by the `name` entry in Cargo.toml.\n\nFor example if your crate is named `yourcratename` and contains a C++ header\nfile `path/to/header.h` relative to Cargo.toml, that file will be includable as:\n\n```cpp\n#include \"yourcratename/path/to/header.h\"\n```\n\nA crate can choose a prefix for its headers that is different from the crate\nname by modifying **[`CFG.include_prefix`][CFG]** from build.rs:\n\n[CFG]: https://docs.rs/cxx-build/*/cxx_build/static.CFG.html\n\n```rust,noplayground\n// build.rs\n\nuse cxx_build::CFG;\n\nfn main() {\n    CFG.include_prefix = \"my/project\";\n\n    cxx_build::bridge(...)...\n}\n```\n\nSubsequently the header located at `path/to/header.h` would now be includable\nas:\n\n```cpp\n#include \"my/project/path/to/header.h\"\n```\n\nThe empty string `\"\"` is a valid include prefix and will make it possible to\nhave `#include \"path/to/header.h\"`. However, if your crate is a library, be\nconsiderate of possible name collisions that may occur in downstream crates. If\nusing an empty include prefix, you'll want to make sure your headers' local path\nwithin the crate is sufficiently namespaced or unique.\n\n## Including generated code\n\nIf your `#[cxx::bridge]` module contains an `extern \"Rust\"` block i.e. types or\nfunctions exposed from Rust to C++, or any shared data structures, the\nCXX-generated C++ header declaring those things is available using a `.rs.h`\nextension on the Rust source file's name.\n\n```cpp\n// the header generated from path/to/lib.rs\n#include \"yourcratename/path/to/lib.rs.h\"\n```\n\nFor giggles, it's also available using just a plain `.rs` extension as if you\nwere including the Rust file directly. Use whichever you find more palatable.\n\n```cpp\n#include \"yourcratename/path/to/lib.rs\"\n```\n\n## Including headers from dependencies\n\nYou get to include headers from your dependencies, both handwritten ones\ncontained as `.h` files in their Cargo package, as well as CXX-generated ones.\n\nIt works the same as an include of a local header: use the crate name (or their\ninclude\\_prefix if their crate changed it) followed by the relative path of the\nheader within the crate.\n\n```cpp\n#include \"dependencycratename/path/to/their/header.h`\n```\n\nNote that cross-crate imports are only made available between **direct\ndependencies**. You must directly depend on the other crate in order to #include\nits headers; a transitive dependency is not sufficient.\n\nAdditionally, headers from a direct dependency are only importable if the\ndependency's Cargo.toml manifest contains a `links` key. If not, its headers\nwill not be importable from outside of the same crate. See *[the `links`\nmanifest key][links]* in the Cargo reference.\n\n[links]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key\n\n<br><br><br>\n\n# Advanced features\n\nThe following CFG settings are only relevant to you if you are writing a library\nthat needs to support downstream crates `#include`-ing its C++ public headers.\n\n## Publicly exporting header directories\n\n**[`CFG.exported_header_dirs`][CFG]** (vector of absolute paths) defines a set\nof additional directories from which the current crate, directly dependent\ncrates, and further crates to which this crate's headers are exported (more\nbelow) will be able to `#include` headers.\n\nAdding a directory to `exported_header_dirs` is similar to adding it to the\ncurrent build via the `cc` crate's [`Build::include`], but *also* makes the\ndirectory available to downstream crates that want to `#include` one of the\nheaders from your crate. If the dir were added only using `Build::include`, the\ndownstream crate including your header would need to manually add the same\ndirectory to their own build as well.\n\n[`Build::include`]: https://docs.rs/cc/1/cc/struct.Build.html#method.include\n\nWhen using `exported_header_dirs`, your crate must also set a `links` key for\nitself in Cargo.toml. See [*the `links` manifest key*][links]. The reason is\nthat Cargo imposes no ordering on the execution of build scripts without a\n`links` key, which means the downstream crate's build script might otherwise\nexecute before yours decides what to put into `exported_header_dirs`.\n\n### Example\n\nOne of your crate's headers wants to include a system library, such as `#include\n\"Python.h\"`.\n\n```rust,noplayground\n// build.rs\n\nuse cxx_build::CFG;\nuse std::path::PathBuf;\n\nfn main() {\n    let python3 = pkg_config::probe_library(\"python3\").unwrap();\n    let python_include_paths = python3.include_paths.iter().map(PathBuf::as_path);\n    CFG.exported_header_dirs.extend(python_include_paths);\n\n    cxx_build::bridge(\"src/bridge.rs\").compile(\"demo\");\n}\n```\n\n### Example\n\nYour crate wants to rearrange the headers that it exports vs how they're laid\nout locally inside the crate's source directory.\n\nSuppose the crate as published contains a file at `./include/myheader.h` but\nwants it available to downstream crates as `#include \"foo/v1/public.h\"`.\n\n```rust,noplayground\n// build.rs\n\nuse cxx_build::CFG;\nuse std::path::Path;\nuse std::{env, fs};\n\nfn main() {\n    let out_dir = env::var_os(\"OUT_DIR\").unwrap();\n    let headers = Path::new(&out_dir).join(\"headers\");\n    CFG.exported_header_dirs.push(&headers);\n\n    // We contain `include/myheader.h` locally, but\n    // downstream will use `#include \"foo/v1/public.h\"`\n    let foo = headers.join(\"foo\").join(\"v1\");\n    fs::create_dir_all(&foo).unwrap();\n    fs::copy(\"include/myheader.h\", foo.join(\"public.h\")).unwrap();\n\n    cxx_build::bridge(\"src/bridge.rs\").compile(\"demo\");\n}\n```\n\n## Publicly exporting dependencies\n\n**[`CFG.exported_header_prefixes`][CFG]** (vector of strings) each refer to the\n`include_prefix` of one of your direct dependencies, or a prefix thereof. They\ndescribe which of your dependencies participate in your crate's C++ public API,\nas opposed to private use by your crate's implementation.\n\nAs a general rule, if one of your headers `#include`s something from one of your\ndependencies, you need to put that dependency's `include_prefix` into\n`CFG.exported_header_prefixes` (*or* their `links` key into\n`CFG.exported_header_links`; see below). On the other hand if only your C++\nimplementation files and *not* your headers are importing from the dependency,\nyou do not export that dependency.\n\nThe significance of exported headers is that if downstream code (crate **𝒜**)\ncontains an `#include` of a header from your crate (**ℬ**) and your header\ncontains an `#include` of something from your dependency (**𝒞**), the exported\ndependency **𝒞** becomes available during the downstream crate **𝒜**'s build.\nOtherwise the downstream crate **𝒜** doesn't know about **𝒞** and wouldn't be\nable to find what header your header is referring to, and would fail to build.\n\nWhen using `exported_header_prefixes`, your crate must also set a `links` key\nfor itself in Cargo.toml.\n\n### Example\n\nSuppose you have a crate with 5 direct dependencies and the `include_prefix` for\neach one are:\n\n- \"crate0\"\n- \"group/api/crate1\"\n- \"group/api/crate2\"\n- \"group/api/contrib/crate3\"\n- \"detail/crate4\"\n\nYour header involves types from the first four so we re-export those as part of\nyour public API, while crate4 is only used internally by your cc file not your\nheader, so we do not export:\n\n```rust,noplayground\n// build.rs\n\nuse cxx_build::CFG;\n\nfn main() {\n    CFG.exported_header_prefixes = vec![\"crate0\", \"group/api\"];\n\n    cxx_build::bridge(\"src/bridge.rs\")\n        .file(\"src/impl.cc\")\n        .compile(\"demo\");\n}\n```\n\n<br>\n\nFor more fine grained control, there is **[`CFG.exported_header_links`][CFG]**\n(vector of strings) which each refer to the `links` attribute ([*the `links`\nmanifest key*][links]) of one of your crate's direct dependencies.\n\nThis achieves an equivalent result to `CFG.exported_header_prefixes` by\nre-exporting a C++ dependency as part of your crate's public API, except with\nfiner control for cases when multiple crates might be sharing the same\n`include_prefix` and you'd like to export some but not others. Links attributes\nare guaranteed to be unique identifiers by Cargo.\n\nWhen using `exported_header_links`, your crate must also set a `links` key for\nitself in Cargo.toml.\n\n### Example\n\n```rust,noplayground\n// build.rs\n\nuse cxx_build::CFG;\n\nfn main() {\n    CFG.exported_header_links.push(\"git2\");\n\n    cxx_build::bridge(\"src/bridge.rs\").compile(\"demo\");\n}\n```\n"
  },
  {
    "path": "book/src/build/cmake.md",
    "content": "{{#title CMake — Rust ♡ C++}}\n# CMake\n\nThere is not an officially endorsed CMake setup for CXX, but a few developers\nhave shared one that they got working. You can try one of these as a starting\npoint. If you feel that you have arrived at a CMake setup that is superior to\nwhat is available in these links, feel free to make a PR adding it to this list.\n\n<br>\n\n---\n\n- **<https://github.com/XiangpengHao/cxx-cmake-example>**\n\n  - Supports cross-language link time optimization (LTO)\n\n---\n\n- **<https://github.com/david-cattermole/cxx-demo-example>**\n\n  - Includes a cbindgen component\n  - Tested on Windows 10 with MSVC, and on Linux\n\n---\n\n- **<https://github.com/trondhe/rusty_cmake>**\n\n  - Alias target that can be linked into a C++ project\n  - Tested on Windows 10 with GNU target, and on Linux\n\n---\n\n- **<https://github.com/geekbrother/cxx-corrosion-cmake>**\n\n  - Improved rusty_cmake CMake file to use modern C++\n  - Rich examples of using different primitive types and Rust's Result return to C++\n  - MacOS and Linux only\n\n---\n\n- **<https://github.com/paandahl/cpp-with-rust>**\n\n  - Same blobstore example as the official demo, but inverted languages\n  - Minimal CMake configuration\n  - Tested on Linux, macOS, and Windows\n\n---\n"
  },
  {
    "path": "book/src/build/other.md",
    "content": "{{#title Other build systems — Rust ♡ C++}}\n# Some other build system\n\nYou will need to achieve at least these three things:\n\n- Produce the CXX-generated C++ bindings code.\n- Compile the generated C++ code.\n- Link the resulting objects together with your other C++ and Rust objects.\n\n*Not all build systems are created equal. If you're hoping to use a build system\nfrom the '90s, especially if you're hoping to overlay the limitations of 2 or\nmore build systems (like automake+cargo) and expect to solve them\nsimultaneously, then be mindful that your expectations are set accordingly and\nseek sympathy from those who have imposed the same approach on themselves.*\n\n### Producing the generated code\n\nCXX's Rust code generation automatically happens when the `#[cxx::bridge]`\nprocedural macro is expanded during the normal Rust compilation process, so no\nspecial build steps are required there.\n\nBut the C++ side of the bindings needs to be generated. Your options are:\n\n- Use the `cxxbridge` command, which is a standalone command line interface to\n  the CXX C++ code generator. Wire up your build system to compile and invoke\n  this tool.\n\n  ```console\n  $  cxxbridge src/bridge.rs --header > path/to/bridge.rs.h\n  $  cxxbridge src/bridge.rs > path/to/bridge.rs.cc\n  ```\n\n  It's packaged as the `cxxbridge-cmd` crate on crates.io or can be built from\n  the *gen/cmd/* directory of the CXX GitHub repo.\n\n- Or, build your own code generator frontend on top of the [cxx-gen] crate. This\n  is currently unofficial and unsupported.\n\n<div class=\"warning\">\n\n**Important:** The Rust side and C++ side of a binding must always be created\nusing the same release of CXX. If using `cxxbridge-cmd` for the C++ side, the\nversion number of `cxxbridge-cmd` must be identical to the version number of\n`cxx` used for the Rust side. If using `cxx-gen` for the C++ side, its patch\nnumber must be identical to the patch number of `cxx`.\n\n</div>\n\n[cxx-gen]: https://docs.rs/cxx-gen\n\n### Compiling C++\n\nHowever you like. We can provide no guidance.\n\n### Linking the C++ and Rust together\n\nWhen linking a binary which contains mixed Rust and C++ code, you will have to\nchoose between using the Rust toolchain (`rustc`) or the C++ toolchain which you\nmay already have extensively tuned.\n\nThe generated C++ code and the Rust code generated by the procedural macro both\ndepend on each other. Simple examples may only require one or the other, but in\ngeneral your linking will need to handle both directions. For some linkers, such\nas LLD, this is not a problem at all. For others, such as GNU ld, flags like\n`--start-lib`/`--end-lib` may help.\n\nRust does not generate simple standalone `.o` files, so you can't just throw the\nRust-generated code into your existing C++ toolchain linker. Instead you need to\nchoose one of these options:\n\n* Use `rustc` as the final linker. Pass any non-Rust libraries using `-L\n  <directory>` and `-l<library>` rustc arguments, and/or `#[link]` directives in\n  your Rust code. If you need to link against C/C++ `.o` files you can use\n  `-Clink-arg=file.o`.\n\n* Use your C++ linker. In this case, you first need to use `rustc` and/or\n  `cargo` to generate a _single_ Rust `staticlib` target and pass that into your\n  foreign linker invocation.\n\n  * If you need to link multiple Rust subsystems, you will need to generate a\n    _single_ `staticlib` perhaps using lots of `extern crate` statements to\n    include multiple Rust `rlib`s.  Multiple Rust `staticlib` files are likely\n    to conflict.\n\nPassing Rust `rlib`s directly into your non-Rust linker is not supported (but\napparently sometimes works).\n\nSee the [Rust reference's *Linkage*][linkage] page for some general information\nhere.\n\n[linkage]: https://doc.rust-lang.org/reference/linkage.html\n\nThe following open rust-lang issues might hold more recent guidance or\ninspiration: [rust-lang/rust#73632], [rust-lang/rust#73295].\n\n[rust-lang/rust#73632]: https://github.com/rust-lang/rust/issues/73632\n[rust-lang/rust#73295]: https://github.com/rust-lang/rust/issues/73295\n"
  },
  {
    "path": "book/src/building.md",
    "content": "{{#title Multi-language build system options — Rust ♡ C++}}\n# Multi-language build system options\n\nCXX is designed to be convenient to integrate into a variety of build systems.\n\nIf you are working in a project that does not already have a preferred build\nsystem for its C++ code *or* which will be relying heavily on open source\nlibraries from the Rust package registry, you're likely to have the easiest\nexperience with Cargo which is the build system commonly used by open source\nRust projects. Refer to the ***[Cargo](build/cargo.md)*** chapter about CXX's\nCargo support.\n\nAmong build systems designed for first class multi-language support, Bazel is a\nsolid choice. Refer to the ***[Bazel](build/bazel.md)*** chapter.\n\nIf your codebase is already invested in CMake, refer to the\n***[CMake](build/cmake.md)*** chapter.\n\nIf you have some other build system that you'd like to try to make work with\nCXX, see [this page](build/other.md) for notes.\n"
  },
  {
    "path": "book/src/concepts.md",
    "content": "{{#title Core concepts — Rust ♡ C++}}\n# Core concepts\n\nThis page is a brief overview of the major concepts of CXX, enough so that you\nrecognize the shape of things as you read the tutorial and following chapters.\n\nIn CXX, the language of the FFI boundary involves 3 kinds of items:\n\n- **Shared structs** &mdash; data structures whose fields are made visible to\n  both languages. The definition written within cxx::bridge in Rust is usually\n  the single source of truth, though there are ways to do sharing based on a\n  bindgen-generated definition with C++ as source of truth.\n\n- **Opaque types** &mdash; their fields are secret from the other language.\n  These cannot be passed across the FFI by value but only behind an indirection,\n  such as a reference `&`, a Rust `Box`, or a C++ `unique_ptr`. Can be a type\n  alias for an arbitrarily complicated generic language-specific type depending\n  on your use case.\n\n- **Functions** &mdash; implemented in either language, callable from the other\n  language.\n\n```rust,noplayground,focuscomment\n# #[cxx::bridge]\n# mod ffi {\n    // Any shared structs, whose fields will be visible to both languages.\n#     struct BlobMetadata {\n#         size: usize,\n#         tags: Vec<String>,\n#     }\n#\n#     extern \"Rust\" {\n        // Zero or more opaque types which both languages can pass around\n        // but only Rust can see the fields.\n#         type MultiBuf;\n#\n        // Functions implemented in Rust.\n#         fn next_chunk(buf: &mut MultiBuf) -> &[u8];\n#     }\n#\n#     unsafe extern \"C++\" {\n        // One or more headers with the matching C++ declarations for the\n        // enclosing extern \"C++\" block. Our code generators don't read it\n        // but it gets #include'd and used in static assertions to ensure\n        // our picture of the FFI boundary is accurate.\n#         include!(\"demo/include/blobstore.h\");\n#\n        // Zero or more opaque types which both languages can pass around\n        // but only C++ can see the fields.\n#         type BlobstoreClient;\n#\n        // Functions implemented in C++.\n#         fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;\n#         fn put(&self, parts: &mut MultiBuf) -> u64;\n#         fn tag(&self, blobid: u64, tag: &str);\n#         fn metadata(&self, blobid: u64) -> BlobMetadata;\n#     }\n# }\n```\n\nWithin the `extern \"Rust\"` part of the CXX bridge we list the types and\nfunctions for which Rust is the source of truth. These all implicitly refer to\nthe `super` module, the parent module of the CXX bridge. You can think of the\ntwo items listed in the example above as being like `use super::MultiBuf` and\n`use super::next_chunk` except re-exported to C++. The parent module will either\ncontain the definitions directly for simple things, or contain the relevant\n`use` statements to bring them into scope from elsewhere.\n\nWithin the `extern \"C++\"` part, we list types and functions for which C++ is the\nsource of truth, as well as the header(s) that declare those APIs. In the future\nit's possible that this section could be generated bindgen-style from the\nheaders but for now we need the signatures written out; static assertions verify\nthat they are accurate.\n\n<br><br>\n\nBe aware that the design of this library is intentionally restrictive and\nopinionated! It isn't a goal to be flexible enough to handle an arbitrary\nsignature in either language. Instead this project is about carving out a highly\nexpressive set of functionality about which we can make powerful safety\nguarantees today and extend over time. You may find that it takes some practice\nto use CXX bridge effectively as it won't work in all the ways that you may be\nused to.\n\n<br>\n"
  },
  {
    "path": "book/src/context.md",
    "content": "{{#title Other Rust–C++ interop tools — Rust ♡ C++}}\n# Context: other Rust&ndash;C++ interop tools\n\nWhen it comes to interacting with an idiomatic Rust API or idiomatic C++ API\nfrom the other language, the generally applicable approaches outside of the CXX\ncrate are:\n\n- Build a C-compatible wrapper around the code (expressed using `extern \"C\"`\n  signatures, primitives, C-compatible structs, raw pointers). Translate that\n  manually to equivalent `extern \"C\"` declarations in the other language and\n  keep them in sync. Preferably, build a safe/idiomatic wrapper around the\n  translated `extern \"C\"` signatures for callers to use.\n\n- Build a C wrapper around the C++ code and use **[bindgen]** to translate that\n  programmatically to `extern \"C\"` Rust signatures. Preferably, build a\n  safe/idiomatic Rust wrapper on top.\n\n- Build a C-compatible Rust wrapper around the Rust code and use **[cbindgen]**\n  to translate that programmatically to an `extern \"C\"` C++ header. Preferably,\n  build an idiomatic C++ wrapper.\n\n**If the code you are binding is already *\"effectively C\"*, the above has you\ncovered.** You should use bindgen or cbindgen, or manually translated C\nsignatures if there aren't too many and they seldom change.\n\n[bindgen]: https://github.com/rust-lang/rust-bindgen\n[cbindgen]: https://github.com/eqrion/cbindgen\n\n## C++ vs C\n\nBindgen has some basic support for C++. It can reason about classes, member\nfunctions, and the layout of templated types. However, everything it does\nrelated to C++ is best-effort only. Bindgen starts from a point of wanting to\ngenerate declarations for everything, so any C++ detail that it hasn't\nimplemented will cause a crash if you are lucky ([bindgen#388]) or more likely\nsilently emit an incompatible signature ([bindgen#380], [bindgen#607],\n[bindgen#652], [bindgen#778], [bindgen#1194]) which will do arbitrary\nmemory-unsafe things at runtime whenever called.\n\n[bindgen#388]: https://github.com/rust-lang/rust-bindgen/issues/388\n[bindgen#380]: https://github.com/rust-lang/rust-bindgen/issues/380\n[bindgen#607]: https://github.com/rust-lang/rust-bindgen/issues/607\n[bindgen#652]: https://github.com/rust-lang/rust-bindgen/issues/652\n[bindgen#778]: https://github.com/rust-lang/rust-bindgen/issues/778\n[bindgen#1194]: https://github.com/rust-lang/rust-bindgen/issues/1194\n\nThus using bindgen correctly requires not just juggling all your pointers\ncorrectly at the language boundary, but also understanding ABI details and their\nworkarounds and reliably applying them. For example, the programmer will\ndiscover that their program sometimes segfaults if they call a function that\nreturns std::unique\\_ptr\\<T\\> through bindgen. Why? Because unique\\_ptr, despite\nbeing \"just a pointer\", has a different ABI than a pointer or a C struct\ncontaining a pointer ([bindgen#778]) and is not directly expressible in Rust.\nBindgen emitted something that *looks* reasonable and you will have a hell of a\ntime in gdb working out what went wrong. Eventually people learn to avoid\nanything involving a non-trivial copy constructor, destructor, or inheritance,\nand instead stick to raw pointers and primitives and trivial structs only\n&mdash; in other words C.\n\n## Geometric intuition for why there is so much opportunity for improvement\n\nThe CXX project attempts a different approach to C++ FFI.\n\nImagine Rust and C and C++ as three vertices of a scalene triangle, with length\nof the edges being related to similarity of the languages when it comes to\nlibrary design.\n\nThe most similar pair (the shortest edge) is Rust&ndash;C++. These languages\nhave largely compatible concepts of things like ownership, vectors, strings,\nfallibility, etc that translate clearly from signatures in either language to\nsignatures in the other language.\n\nWhen we make a binding for an idiomatic C++ API using bindgen, and we fall down\nto raw pointers and primitives and trivial structs as described above, what we\nare really doing is coding the two longest edges of the triangle: getting from\nC++ down to C, and C back up to Rust. The Rust&ndash;C edge always involves a\ngreat deal of `unsafe` code, and the C++&ndash;C edge similarly requires care\njust for basic memory safety. Something as basic as \"how do I pass ownership of\na string to the other language?\" becomes a strap-yourself-in moment,\nparticularly for someone not already an expert in one or both sides.\n\nYou should think of the `cxx` crate as being the midpoint of the Rust&ndash;C++\nedge. Rather than coding the two long edges, you will code half the short edge\nin Rust and half the short edge in C++, in both cases with the library playing\nto the strengths of the Rust type system *and* the C++ type system to help\nassure correctness.\n\nIf you've already been through the tutorial in the previous chapter, take a\nmoment to appreciate that the C++ side *really* looks like we are just writing\nC++ and the Rust side *really* looks like we are just writing Rust. Anything you\ncould do wrong in Rust, and almost anything you could reasonably do wrong in\nC++, will be caught by the compiler. This highlights that we are on the \"short\nedge of the triangle\".\n\nBut it all still boils down to the same things: it's still FFI from one piece of\nnative code to another, nothing is getting serialized or allocated or\nruntime-checked in between.\n\n## Role of CXX\n\nThe role of CXX is to capture the language boundary with more fidelity than what\n`extern \"C\"` is able to represent. You can think of CXX as being a replacement\nfor `extern \"C\"` in a sense.\n\nFrom this perspective, CXX is a lower level tool than the bindgens. Just as\nbindgen and cbindgen are built on top of `extern \"C\"`, it makes sense to think\nabout higher level tools built on top of CXX. Such a tool might consume a C++\nheader and/or Rust module (and/or IDL like Thrift) and emit the corresponding\nsafe cxx::bridge language boundary, leveraging CXX's static analysis and\nunderlying implementation of that boundary. We are beginning to see this space\nexplored by the [autocxx] tool, though nothing yet ready for broad use in the\nway that CXX on its own is.\n\n[autocxx]: https://github.com/google/autocxx\n\nBut note in other ways CXX is higher level than the bindgens, with rich support\nfor common standard library types. CXX's types serve as an intuitive vocabulary\nfor designing a good boundary between components in different languages.\n"
  },
  {
    "path": "book/src/extern-c++.md",
    "content": "{{#title extern \"C++\" — Rust ♡ C++}}\n# extern \"C++\"\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        include!(\"path/to/header.h\");\n        include!(\"path/to/another.h\");\n\n        ...\n    }\n}\n```\n\nThe `extern \"C++\"` section of a CXX bridge declares C++ types and signatures to\nbe made available to Rust, and gives the paths of the header(s) which contain\nthe corresponding C++ declarations.\n\nA bridge module may contain zero or more extern \"C++\" blocks.\n\n## Opaque C++ types\n\nType defined in C++ that are made available to Rust, but only behind an\nindirection.\n\n```rust,noplayground\n# #[cxx::bridge]\n# mod ffi {\n    extern \"C++\" {\n        # include!(\"path/to/header.h\");\n        #\n        type MyType;\n        type MyOtherType;\n    }\n# }\n```\n\nFor example in the ***[Tutorial](tutorial.md)*** we saw `BlobstoreClient`\nimplemented as an opaque C++ type. The blobstore client was created in C++ and\nreturned to Rust by way of a UniquePtr.\n\n**Mutability:** Unlike extern Rust types and shared types, an extern C++ type is\nnot permitted to be passed by plain mutable reference `&mut MyType` across the\nFFI bridge. For mutation support, the bridge is required to use `Pin<&mut\nMyType>`. This is to safeguard against things like mem::swap-ing the contents of\ntwo mutable references, given that Rust doesn't have information about the size\nof the underlying object and couldn't invoke an appropriate C++ move constructor\nanyway.\n\n**Thread safety:** Be aware that CXX does not assume anything about the thread\nsafety of your extern C++ types. In other words the `MyType` etc bindings which\nCXX produces for you in Rust *do not* come with `Send` and `Sync` impls. If you\nare sure that your C++ type satisfies the requirements of `Send` and/or `Sync`\nand need to leverage that fact from Rust, you must provide your own unsafe\nmarker trait impls.\n\n```rust,noplayground\n# #[cxx::bridge]\n# mod ffi {\n#     extern \"C++\" {\n#         include!(\"path/to/header.h\");\n#\n#         type MyType;\n#     }\n# }\n#\n/// The C++ implementation of MyType is thread safe.\nunsafe impl Send for ffi::MyType {}\nunsafe impl Sync for ffi::MyType {}\n```\n\nTake care in doing this because thread safety in C++ can be extremely tricky to\nassess if you are coming from a Rust background. For example the\n`BlobstoreClient` type in the tutorial is *not thread safe* despite doing only\ncompletely innocuous things in its implementation. Concurrent calls to the `tag`\nmember function trigger a data race on the `blobs` map.\n\n## Functions and member functions\n\nThis largely follows the same principles as ***[extern\n\"Rust\"](extern-rust.md)*** functions and methods. In particular, any signature\nwith a `self` parameter is interpreted as a C++ non-static member function and\nexposed to Rust as a method; any signature with a `#[Self = \"…\"]` attribute is\ninterpreted as a C++ static member function and exposed to Rust as an associated\nfunction.\n\nThe programmer **does not** need to promise that the signatures they have typed\nin are accurate; that would be unreasonable. CXX performs static assertions that\nthe signatures exactly correspond with what is declared in C++. Rather, the\nprogrammer is only on the hook for things that C++'s static information is not\nprecise enough to capture, i.e. things that would only be represented at most by\ncomments in the C++ code unintelligible to a static assertion: namely whether\nthe C++ function is safe or unsafe to be called from Rust.\n\n**Safety:** the extern \"C++\" block is responsible for deciding whether to expose\neach signature inside as safe-to-call or unsafe-to-call. If an extern block\ncontains at least one safe-to-call signature, it must be written as an `unsafe\nextern` block, which serves as an item level unsafe block to indicate that an\nunchecked safety claim is being made about the contents of the block.\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        # include!(\"path/to/header.h\");\n        #\n        fn f();  // safe to call\n    }\n\n    extern \"C++\" {\n        unsafe fn g();  // unsafe to call\n    }\n}\n```\n\n## Lifetimes\n\nC++ types holding borrowed data may be described naturally in Rust by an extern\ntype with a generic lifetime parameter. For example in the case of the following\npair of types:\n\n```cpp\n// header.h\n\nclass Resource;\n\nclass TypeContainingBorrow {\n  TypeContainingBorrow(const Resource &res) : res(res) {}\n  const Resource &res;\n};\n\nstd::shared_ptr<TypeContainingBorrow> create(const Resource &res);\n```\n\nwe'd want to expose this to Rust as:\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        # include!(\"path/to/header.h\");\n        #\n        type Resource;\n        type TypeContainingBorrow<'a>;\n\n        fn create<'a>(res: &'a Resource) -> SharedPtr<TypeContainingBorrow<'a>>;\n\n        // or with lifetime elision:\n        fn create(res: &Resource) -> SharedPtr<TypeContainingBorrow>;\n    }\n}\n```\n\n## Reusing existing binding types\n\nExtern C++ types support a syntax for declaring that a Rust binding of the\ncorrect C++ type already exists outside of the current bridge module. This\navoids generating a fresh new binding which Rust's type system would consider\nnon-interchangeable with the first.\n\n```rust,noplayground\n#[cxx::bridge(namespace = \"path::to\")]\nmod ffi {\n    extern \"C++\" {\n        type MyType = crate::existing::MyType;\n    }\n\n    extern \"Rust\" {\n        fn f(x: &MyType) -> usize;\n    }\n}\n```\n\nIn this case rather than producing a unique new Rust type `ffi::MyType` for the\nRust binding of C++'s `::path::to::MyType`, CXX will reuse the already existing\nbinding at `crate::existing::MyType` in expressing the signature of `f` and any\nother uses of `MyType` within the bridge module.\n\nCXX safely validates that `crate::existing::MyType` is in fact a binding for the\nright C++ type `::path::to::MyType` by generating a static assertion based on\n`crate::existing::MyType`'s implementation of [`ExternType`], which is a trait\nautomatically implemented by CXX for bindings that it generates but can also be\nmanually implemented as described below.\n\n[`ExternType`]: https://docs.rs/cxx/*/cxx/trait.ExternType.html\n\n`ExternType` serves the following two related use cases.\n\n#### Safely unifying occurrences of an extern type across bridges\n\nIn the following snippet, two #\\[cxx::bridge\\] invocations in different files\n(possibly different crates) both contain function signatures involving the same\nC++ type `example::Demo`. If both were written just containing `type Demo;`,\nthen both macro expansions would produce their own separate Rust type called\n`Demo` and thus the compiler wouldn't allow us to take the `Demo` returned by\n`file1::ffi::create_demo` and pass it as the `Demo` argument accepted by\n`file2::ffi::take_ref_demo`. Instead, one of the two `Demo`s has been defined as\nan extern type alias of the other, making them the same type in Rust.\n\n```rust,noplayground\n// file1.rs\n#[cxx::bridge(namespace = \"example\")]\npub mod ffi {\n    unsafe extern \"C++\" {\n        type Demo;\n\n        fn create_demo() -> UniquePtr<Demo>;\n    }\n}\n```\n\n```rust,noplayground\n// file2.rs\n#[cxx::bridge(namespace = \"example\")]\npub mod ffi {\n    unsafe extern \"C++\" {\n        type Demo = crate::file1::ffi::Demo;\n\n        fn take_ref_demo(demo: &Demo);\n    }\n}\n```\n\n#### Integrating with bindgen-generated or handwritten unsafe bindings\n\nHandwritten `ExternType` impls make it possible to plug in a data structure\nemitted by bindgen as the definition of a C++ type emitted by CXX.\n\nBy writing the unsafe `ExternType` impl, the programmer asserts that the C++\nnamespace and type name given in the type id refers to a C++ type that is\nequivalent to Rust type that is the `Self` type of the impl.\n\n```rust,noplayground\nmod folly_sys;  // the bindgen-generated bindings\n\nuse cxx::{type_id, ExternType};\n\nunsafe impl ExternType for folly_sys::StringPiece {\n    type Id = type_id!(\"folly::StringPiece\");\n    type Kind = cxx::kind::Opaque;\n}\n\n#[cxx::bridge(namespace = \"folly\")]\npub mod ffi {\n    unsafe extern \"C++\" {\n        include!(\"rust_cxx_bindings.h\");\n\n        type StringPiece = crate::folly_sys::StringPiece;\n\n        fn print_string_piece(s: &StringPiece);\n    }\n}\n\n// Now if we construct a StringPiece or obtain one through one\n// of the bindgen-generated signatures, we are able to pass it\n// along to ffi::print_string_piece.\n```\n\nThe `ExternType::Id` associated type encodes a type-level representation of the\ntype's C++ namespace and type name. It will always be defined using the\n`type_id!` macro exposed in the cxx crate.\n\nThe `ExternType::Kind` associated type will always be either\n[`cxx::kind::Opaque`] or [`cxx::kind::Trivial`] identifying whether a C++ type\nis soundly relocatable by Rust's move semantics. A C++ type is only okay to hold\nand pass around by value in Rust if its [move constructor is trivial] and it has\nno destructor. In CXX, these are called Trivial extern C++ types, while types\nwith nontrivial move behavior or a destructor must be considered Opaque and\nhandled by Rust only behind an indirection, such as a reference or UniquePtr.\n\n[`cxx::kind::Opaque`]: https://docs.rs/cxx/*/cxx/kind/enum.Opaque.html\n[`cxx::kind::Trivial`]: https://docs.rs/cxx/*/cxx/kind/enum.Trivial.html\n[move constructor is trivial]: https://en.cppreference.com/w/cpp/types/is_move_constructible\n\nIf you believe your C++ type reflected by the ExternType impl is indeed fine to\nhold by value and move in Rust, you can specify:\n\n```rust,noplayground\n# unsafe impl cxx::ExternType for TypeName {\n#     type Id = cxx::type_id!(\"name::space::of::TypeName\");\n    type Kind = cxx::kind::Trivial;\n# }\n```\n\nwhich will enable you to pass it into C++ functions by value, return it by\nvalue, and include it in `struct`s that you have declared to `cxx::bridge`. Your\nclaim about the triviality of the C++ type will be checked by a `static_assert`\nin the generated C++ side of the binding.\n\n## Explicit shim trait impls\n\nThis is a somewhat niche feature, but important when you need it.\n\nCXX's support for C++'s std::unique\\_ptr and std::vector is built on a set of\ninternal trait impls connecting the Rust API of UniquePtr and CxxVector to\nunderlying template instantiations performed by the C++ compiler.\n\nWhen reusing a binding type across multiple bridge modules as described in the\nprevious section, you may find that your code needs some trait impls which CXX\nhasn't decided to generate.\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi1 {\n    extern \"C++\" {\n        include!(\"path/to/header.h\");\n\n        type A;\n        type B;\n\n        // Okay: CXX sees UniquePtr<B> using a type B defined within the same\n        // bridge, and automatically emits the right template instantiations\n        // corresponding to std::unique_ptr<B>.\n        fn get_b() -> UniquePtr<B>;\n    }\n}\n\n#[cxx::bridge]\nmod ffi2 {\n    extern \"C++\" {\n        type A = crate::ffi1::A;\n\n        // Rust trait error: CXX processing this module has no visibility into\n        // whether template instantiations corresponding to std::unique_ptr<A>\n        // have already been emitted by the upstream library, so it does not\n        // emit them here. If the upstream library does not have any signatures\n        // involving UniquePtr<A>, an explicit instantiation of the template\n        // needs to be requested in one module or the other.\n        fn get_a() -> UniquePtr<A>;\n    }\n}\n```\n\nYou can request a specific template instantiation at a particular location in\nthe Rust crate hierarchy by writing `impl UniquePtr<A> {}` inside of the bridge\nmodule which defines `A` but does not otherwise contain any use of\n`UniquePtr<A>`.\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi1 {\n    extern \"C++\" {\n        include!(\"path/to/header.h\");\n\n        type A;\n        type B;\n\n        fn get_b() -> UniquePtr<B>;\n    }\n\n    impl UniquePtr<A> {}  // explicit instantiation\n}\n```\n"
  },
  {
    "path": "book/src/extern-rust.md",
    "content": "{{#title extern \"Rust\" — Rust ♡ C++}}\n# extern \"Rust\"\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n\n    }\n}\n```\n\nThe `extern \"Rust\"` section of a CXX bridge declares Rust types and signatures\nto be made available to C++.\n\nThe CXX code generator uses your extern \"Rust\" section(s) to produce a C++\nheader file containing the corresponding C++ declarations. The generated header\nhas the same path as the Rust source file containing the bridge, except with a\n`.rs.h` file extension.\n\nA bridge module may contain zero or more extern \"Rust\" blocks.\n\n## Opaque Rust types\n\nTypes defined in Rust that are made available to C++, but only behind an\nindirection.\n\n```rust,noplayground\n# #[cxx::bridge]\n# mod ffi {\n    extern \"Rust\" {\n        type MyType;\n        type MyOtherType;\n        type OneMoreType<'a>;\n    }\n# }\n```\n\nFor example in the ***[Tutorial](tutorial.md)*** we saw `MultiBuf` used in this\nway. Rust code created the `MultiBuf`, passed a `&mut MultiBuf` to C++, and C++\nlater passed a `&mut MultiBuf` back across the bridge to Rust.\n\nAnother example is the one on the ***[Box\\<T\\>](binding/box.md)*** page, which\nexposes the Rust standard library's `std::fs::File` to C++ as an opaque type in\na similar way but with Box as the indirection rather than &mut.\n\nThe types named as opaque types (`MyType` etc) refer to types in the `super`\nmodule, the parent module of the CXX bridge. You can think of an opaque type `T`\nas being like a re-export `use super::T` made available to C++ via the generated\nheader.\n\nOpaque types are currently required to be [`Sized`] and [`Unpin`]. In\nparticular, a trait object `dyn MyTrait` or slice `[T]` may not be used for an\nopaque Rust type. These restrictions may be lifted in the future.\n\n[`Sized`]: https://doc.rust-lang.org/std/marker/trait.Sized.html\n[`Unpin`]: https://doc.rust-lang.org/std/marker/trait.Unpin.html\n\nFor now, types used as extern Rust types are required to be defined by the same\ncrate that contains the bridge using them. This restriction may be lifted in the\nfuture.\n\nThe bridge's parent module will contain the appropriate imports or definitions\nfor these types.\n\n```rust,noplayground\nuse path::to::MyType;\n\npub struct MyOtherType {\n    ...\n}\n#\n# #[cxx::bridge]\n# mod ffi {\n#     extern \"Rust\" {\n#         type MyType;\n#         type MyOtherType;\n#     }\n# }\n```\n\n## Functions\n\nRust functions made callable to C++.\n\nJust like for opaque types, these functions refer implicitly to something in\nscope in the `super` module, whether defined there or imported by some `use`\nstatement.\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type MyType;\n        fn f() -> Box<MyType>;\n    }\n}\n\nstruct MyType(i32);\n\nfn f() -> Box<MyType> {\n    return Box::new(MyType(1));\n}\n```\n\nExtern Rust function signature may consist of types defined in the bridge,\nprimitives, and [any of these additional bindings](bindings.md).\n\n## Methods\n\nAny signature with a `self` parameter is interpreted as a Rust method and\nexposed to C++ as a non-static member function.\n\n```rust,noplayground\n# #[cxx::bridge]\n# mod ffi {\n    extern \"Rust\" {\n        type MyType;\n        fn f(&self) -> usize;\n    }\n# }\n```\n\nThe `self` parameter may be a shared reference `&self`, an exclusive reference\n`&mut self`, or a pinned reference `self: Pin<&mut Self>`. A by-value `self` is\nnot currently supported.\n\nIf the surrounding `extern \"Rust\"` block contains exactly one extern type, that\ntype is implicitly the receiver for a `&self` or `&mut self` method. If the\nsurrounding block contains *more than one* extern type, a receiver type must be\nprovided explicitly for the self parameter, or you can consider splitting into\nmultiple extern blocks.\n\n```rust,noplayground\n# #[cxx::bridge]\n# mod ffi {\n    extern \"Rust\" {\n        type First;\n        type Second;\n        fn bar(self: &First);\n        fn foo(self: &mut Second);\n    }\n# }\n```\n\n## Associated functions\n\nA function with a `Self` attribute is interpreted as a Rust associated function\nand exposed to C++ as a static member function. These must not have a `self`\nargument.\n\nIn the following example, the `builder` associated function is callable as\n`MyType::builder()` from both Rust and C++.\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type MyType;\n        type MyTypeBuilder;\n\n        #[Self = \"MyType\"]\n        fn builder() -> Box<MyTypeBuilder>;\n    }\n}\n\npub struct MyType;\npub struct MyTypeBuilder;\n\nimpl MyType {\n    pub fn builder() -> Box<MyTypeBuilder> {\n        ...\n    }\n}\n```\n\n## Functions with explicit lifetimes\n\nAn extern Rust function signature is allowed to contain explicit lifetimes but\nin this case the function must be declared unsafe-to-call. This is pretty\nmeaningless given we're talking about calls from C++, but at least it draws some\nextra attention from the caller that they may be responsible for upholding some\natypical lifetime relationship.\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type MyType;\n        unsafe fn f<'a>(&'a self, s: &str) -> &'a str;\n    }\n}\n```\n\nBounds on a lifetime (like `<'a, 'b: 'a>`) are not currently supported. Nor are\ntype parameters or where-clauses.\n"
  },
  {
    "path": "book/src/index.md",
    "content": "<div class=\"badges\">\n<a href=\"https://github.com/dtolnay/cxx\"><img src=\"https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github\" alt=\"github\" height=\"28\" class=\"badge\"></a><a href=\"https://crates.io/crates/cxx\"><img src=\"https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust\" alt=\"crates-io\" height=\"28\" class=\"badge\"></a><a href=\"https://docs.rs/cxx\"><img src=\"https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\" alt=\"docs-rs\" height=\"28\" class=\"badge\"></a>\n</div>\n\n# CXX — safe interop between Rust and C++\n\nThis library provides a safe mechanism for calling C++ code from Rust and Rust\ncode from C++. It carves out a regime of commonality where Rust and C++ are\nsemantically very similar and guides the programmer to express their language\nboundary effectively within this regime. CXX fills in the low level stuff so\nthat you get a safe binding, preventing the pitfalls of doing a foreign function\ninterface over unsafe C-style signatures.\n\n<div style=\"height:190px;width=718px;padding:44px 0 44px\">\n<object type=\"image/svg+xml\" data=\"overview.svg\"></object>\n</div>\n\nFrom a high level description of the language boundary, CXX uses static analysis\nof the types and function signatures to protect both Rust's and C++'s\ninvariants. Then it uses a pair of code generators to implement the boundary\nefficiently on both sides together with any necessary static assertions for\nlater in the build process to verify correctness.\n\nThe resulting FFI bridge operates at zero or negligible overhead, i.e. no\ncopying, no serialization, no memory allocation, no runtime checks needed.\n\nThe FFI signatures are able to use native data structures from whichever side\nthey please. In addition, CXX provides builtin bindings for key standard library\ntypes like strings, vectors, Box, unique\\_ptr, etc to expose an idiomatic API on\nthose types to the other language.\n\n## Example\n\nIn this example we are writing a Rust application that calls a C++ client of a\nlarge-file blobstore service. The blobstore supports a `put` operation for a\ndiscontiguous buffer upload. For example we might be uploading snapshots of a\ncircular buffer which would tend to consist of 2 pieces, or fragments of a file\nspread across memory for some other reason (like a rope data structure).\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type MultiBuf;\n\n        fn next_chunk(buf: &mut MultiBuf) -> &[u8];\n    }\n\n    unsafe extern \"C++\" {\n        include!(\"example/include/blobstore.h\");\n\n        type BlobstoreClient;\n\n        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;\n        fn put(self: &BlobstoreClient, buf: &mut MultiBuf) -> Result<u64>;\n    }\n}\n```\n\nNow we simply provide Rust definitions of all the things in the `extern \"Rust\"`\nblock and C++ definitions of all the things in the `extern \"C++\"` block, and get\nto call back and forth safely.\n\nThe [***Tutorial***](tutorial.md) chapter walks through a fleshed out version of\nthis blobstore example in full detail, including all of the Rust code and all of\nthe C++ code. The code is also provided in runnable form in the *demo* directory\nof <https://github.com/dtolnay/cxx>. To try it out, run `cargo run` from that\ndirectory.\n\n- [demo/src/main.rs](https://github.com/dtolnay/cxx/blob/master/demo/src/main.rs)\n- [demo/include/blobstore.h](https://github.com/dtolnay/cxx/blob/master/demo/include/blobstore.h)\n- [demo/src/blobstore.cc](https://github.com/dtolnay/cxx/blob/master/demo/src/blobstore.cc)\n\nThe key takeaway, which is enabled by the CXX library, is that the Rust code in\nmain.rs is 100% ordinary safe Rust code working idiomatically with Rust types\nwhile the C++ code in blobstore.cc is 100% ordinary C++ code working\nidiomatically with C++ types. The Rust code feels like Rust and the C++ code\nfeels like C++, not like C-style \"FFI glue\".\n\n<br>\n\n***Chapter outline:** See the hamburger menu in the top left if you are on a\nsmall screen and it didn't open with a sidebar by default.*\n"
  },
  {
    "path": "book/src/reference.md",
    "content": "{{#title The bridge module — Rust ♡ C++}}\n# The bridge module reference\n\nThe ***[Core concepts](concepts.md)*** in chapter 2 covered the high level model\nthat CXX uses to represent a language boundary. This chapter builds on that one\nto document an exhaustive reference on the syntax and functionality of\n\\#\\[cxx::bridge\\].\n\n- ***[extern \"Rust\"](extern-rust.md)*** &mdash; exposing opaque Rust types, Rust\n  functions, Rust methods to C++; functions with lifetimes.\n\n- ***[extern \"C++\"](extern-c++.md)*** &mdash; binding opaque C++ types, C++\n  functions, C++ member functions; sharing an opaque type definition across\n  multiple bridge modules or different crates; using bindgen-generated data\n  structures across a CXX bridge; Rust orphan-rule-compatible way to request\n  that particular glue code be emitted in a specific bridge module.\n\n- ***[Shared types](shared.md)*** &mdash; shared structs; shared enums; using\n  Rust as source of truth vs C++ as source of truth.\n\n- ***[Attributes](attributes.md)*** &mdash; working with namespaces; giving\n  functions a different name in their non-native language.\n\n- ***[Async functions](async.md)*** &mdash; integrating async C++ with async\n  Rust.\n\n- ***[Error handling](binding/result.md)*** &mdash; representing fallibility on\n  the language boundary; accessing a Rust error message from C++; customizing\n  the set of caught exceptions and their conversion to a Rust error message.\n"
  },
  {
    "path": "book/src/shared.md",
    "content": "{{#title Shared types — Rust ♡ C++}}\n# Shared types\n\nShared types enable *both* languages to have visibility into the internals of a\ntype. This is in contrast to opaque Rust types and opaque C++ types, for which\nonly one side gets to manipulate the internals.\n\nUnlike opaque types, the FFI bridge is allowed to pass and return shared types\nby value.\n\nThe order in which shared types are written is not important. C++ is order\nsensitive but CXX will topologically sort and forward-declare your types as\nnecessary.\n\n## Shared structs and enums\n\nFor enums, only C-like a.k.a. unit variants are currently supported.\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    struct PlayingCard {\n        suit: Suit,\n        value: u8,  // A=1, J=11, Q=12, K=13\n    }\n\n    enum Suit {\n        Clubs,\n        Diamonds,\n        Hearts,\n        Spades,\n    }\n\n    unsafe extern \"C++\" {\n        fn deck() -> Vec<PlayingCard>;\n        fn sort(cards: &mut Vec<PlayingCard>);\n    }\n}\n```\n\n## The generated data structures\n\nShared structs compile to an aggregate-initialization compatible C++ struct.\n\nShared enums compile to a C++ `enum class` with a sufficiently sized integral\nbase type decided by CXX.\n\n```cpp\n// generated header\n\nstruct PlayingCard final {\n  Suit suit;\n  uint8_t value;\n};\n\nenum class Suit : uint8_t {\n  Clubs = 0,\n  Diamonds = 1,\n  Hearts = 2,\n  Spades = 3,\n};\n```\n\nBecause it is not UB in C++ for an `enum class` to hold a value different from\nall of the listed variants, we use a Rust representation for shared enums that\nis compatible with this. The API you'll get is something like:\n\n```rust,noplayground\n#[derive(Copy, Clone, PartialEq, Eq)]\n#[repr(transparent)]\npub struct Suit {\n    pub repr: u8,\n}\n#[allow(non_upper_case_globals)]\nimpl Suit {\n    pub const Clubs: Self = Suit { repr: 0 };\n    pub const Diamonds: Self = Suit { repr: 1 };\n    pub const Hearts: Self = Suit { repr: 2 };\n    pub const Spades: Self = Suit { repr: 3 };\n}\n```\n\nNotice you're free to treat the enum as an integer in Rust code via the public\n`repr` field.\n\nPattern matching with `match` still works but will require you to write wildcard\narms to handle the situation of an enum value that is not one of the listed\nvariants.\n\n```rust,noplayground\nfn main() {\n    let suit: Suit = /*...*/;\n    match suit {\n        Suit::Clubs => ...,\n        Suit::Diamonds => ...,\n        Suit::Hearts => ...,\n        Suit::Spades => ...,\n        _ => ...,  // fallback arm\n    }\n}\n```\n\nIf a shared struct has generic lifetime parameters, the lifetimes are simply not\nrepresented on the C++ side. C++ code will need care when working with borrowed\ndata (as usual in C++).\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    struct Borrowed<'a> {\n        flags: &'a [&'a str],\n    }\n}\n```\n\n```cpp\n// generated header\n\nstruct Borrowed final {\n  rust::Slice<const rust::Str> flags;\n};\n```\n\n## Enum discriminants\n\nYou may provide explicit discriminants for some or all of the enum variants, in\nwhich case those numbers will be propagated into the generated C++ `enum class`.\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    enum SmallPrime {\n        Two = 2,\n        Three = 3,\n        Five = 5,\n        Seven = 7,\n    }\n}\n```\n\nVariants without an explicit discriminant are assigned the previous discriminant\nplus 1. If the first variant has not been given an explicit discriminant, it is\nassigned discriminant 0.\n\nBy default CXX represents your enum using the smallest integer type capable of\nfitting all the discriminants (whether explicit or implicit). If you need a\ndifferent representation for reasons, provide a `repr` attribute.\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    #[repr(i32)]\n    enum Enum {\n        Zero,\n        One,\n        Five = 5,\n        Six,\n    }\n}\n```\n\n```cpp\n// generated header\n\nenum class Enum : int32_t {\n  Zero = 0,\n  One = 1,\n  Five = 5,\n  Six = 6,\n};\n```\n\n## Extern enums\n\nIf you need to interoperate with an already existing enum for which an existing\nC++ definition is the source of truth, make sure that definition is provided by\nsome header in the bridge and then declare your enum *additionally* as an extern\nC++ type.\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    enum Enum {\n        Yes,\n        No,\n    }\n\n    extern \"C++\" {\n        include!(\"path/to/the/header.h\");\n        type Enum;\n    }\n}\n```\n\nCXX will recognize this pattern and, instead of generating a C++ definition of\nthe enum, will instead generate C++ static assertions asserting that the\nvariants and discriminant values and integer representation written in Rust all\ncorrectly match the existing C++ enum definition.\n\nExtern enums support all the same features as ordinary shared enums (explicit\ndiscriminants, repr). Again, CXX will static assert that all of those things you\nwrote are correct.\n\n## Derives\n\nThe following standard traits are supported in `derive(...)` within the CXX\nbridge module.\n\n- `Clone`\n- `Copy`\n- `Debug`\n- `Default`\n- `Eq`\n- `Hash`\n- `Ord`\n- `PartialEq`\n- `PartialOrd`\n- `BitAnd` (enums only)\n- `BitOr` (enums only)\n- `BitXor` (enums only)\n\nNote that shared enums automatically always come with impls of `Copy`, `Clone`,\n`Eq`, and `PartialEq`, so you're free to omit those derives on an enum.\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    #[derive(Clone, Debug, Hash)]\n    struct ExampleStruct {\n        x: u32,\n        s: String,\n    }\n\n    #[derive(Hash, Ord, PartialOrd)]\n    enum ExampleEnum {\n        Yes,\n        No,\n    }\n}\n```\n\nThe derives naturally apply to *both* the Rust data type *and* the corresponding\nC++ data type:\n\n- `Hash` gives you a specialization of [`template <> struct std::hash<T>`][hash] in C++\n- `PartialEq` produces `operator==` and `operator!=`\n- `PartialOrd` produces `operator<`, `operator<=`, `operator>`, `operator>=`\n- `BitAnd` produces `operator&`\n- `BitOr` produces `operator|`\n- `BitXor` produces `operator^`\n\n[hash]: https://en.cppreference.com/w/cpp/utility/hash\n\n## Alignment\n\nThe attribute `repr(align(…))` sets a minimum required alignment for a shared\nstruct. The alignment value must be a power of two in the range 2<sup>0</sup> to\n2<sup>13</sup>.\n\nThis turns into an [`alignas`] specifier in C++.\n\n[`alignas`]: https://en.cppreference.com/w/cpp/language/alignas.html\n\n```rust,noplayground\n#[cxx::bridge]\nmod ffi {\n    #[repr(align(4))]\n    struct ExampleStruct {\n        b: [u8; 4],\n    }\n}\n```\n"
  },
  {
    "path": "book/src/tutorial.md",
    "content": "{{#title Tutorial — Rust ♡ C++}}\n# Tutorial: CXX blobstore client\n\nThis example walks through a Rust application that calls into a C++ client of a\nblobstore service. In fact we'll see calls going in both directions: Rust to C++\nas well as C++ to Rust. For your own use case it may be that you need just one\nof these directions.\n\nAll of the code involved in the example is shown on this page, but it's also\nprovided in runnable form in the *demo* directory of\n<https://github.com/dtolnay/cxx>. To try it out directly, run `cargo run` from\nthat directory.\n\nThis tutorial assumes you've read briefly about **shared structs**, **opaque\ntypes**, and **functions** in the [*Core concepts*](concepts.md) page.\n\n## Creating the project\n\nWe'll use Cargo, which is the build system commonly used by open source Rust\nprojects. (CXX works with other build systems too; refer to chapter 5.)\n\nCreate a blank Cargo project: `mkdir cxx-demo`; `cd cxx-demo`; `cargo init`.\n\nEdit the Cargo.toml to add a dependency on the `cxx` crate:\n\n```toml,hidelines=...\n# Cargo.toml\n...[package]\n...name = \"cxx-demo\"\n...version = \"0.1.0\"\n...edition = \"2021\"\n\n[dependencies]\ncxx = \"1.0\"\n```\n\nWe'll revisit this Cargo.toml later when we get to compiling some C++ code.\n\n## Defining the language boundary\n\nCXX relies on a description of the function signatures that will be exposed from\neach language to the other. You provide this description using `extern` blocks\nin a Rust module annotated with the `#[cxx::bridge]` attribute macro.\n\nWe'll open with just the following at the top of src/main.rs and walk through\neach item in detail.\n\n```rust,noplayground\n// src/main.rs\n\n#[cxx::bridge]\nmod ffi {\n\n}\n#\n# fn main() {}\n```\n\nThe contents of this module will be everything that needs to be agreed upon by\nboth sides of the FFI boundary.\n\n## Calling a C++ function from Rust\n\nLet's obtain an instance of the C++ blobstore client, a class `BlobstoreClient`\ndefined in C++.\n\nWe'll treat `BlobstoreClient` as an *opaque type* in CXX's classification so\nthat Rust does not need to assume anything about its implementation, not even\nits size or alignment. In general, a C++ type might have a move-constructor\nwhich is incompatible with Rust's move semantics, or may hold internal\nreferences which cannot be modeled by Rust's borrowing system. Though there are\nalternatives, the easiest way to not care about any such thing on an FFI\nboundary is to require no knowledge about a type by treating it as opaque.\n\nOpaque types may only be manipulated behind an indirection such as a reference\n`&`, a Rust `Box`, or a `UniquePtr` (Rust binding of `std::unique_ptr`). We'll\nadd a function through which C++ can return a `std::unique_ptr<BlobstoreClient>`\nto Rust.\n\n```rust,noplayground\n// src/main.rs\n\n#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        include!(\"cxx-demo/include/blobstore.h\");\n\n        type BlobstoreClient;\n\n        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;\n    }\n}\n\nfn main() {\n    let client = ffi::new_blobstore_client();\n}\n```\n\nThe nature of `unsafe` extern blocks is clarified in more detail in the\n[*extern \"C++\"*](extern-c++.md) chapter. In brief: the programmer is **not**\npromising that the signatures they have typed in are accurate; that would be\nunreasonable. CXX performs static assertions that the signatures exactly match\nwhat is declared in C++. Rather, the programmer is only on the hook for things\nthat C++'s semantics are not precise enough to capture, i.e. things that would\nonly be represented at most by comments in the C++ code. In this case, it's\nwhether `new_blobstore_client` is safe or unsafe to call. If that function said\nsomething like \"must be called at most once or we'll stomp yer memery\", Rust\nwould instead want to expose it as `unsafe fn new_blobstore_client`, this time\ninside a safe `extern \"C++\"` block because the programmer is no longer on the\nhook for any safety claim about the signature.\n\nIf you build this file right now with `cargo build`, it won't build because we\nhaven't written a C++ implementation of `new_blobstore_client` nor instructed\nCargo about how to link it into the resulting binary. You'll see an error from\nthe linker like this:\n\n```console\nerror: linking with `cc` failed: exit code: 1\n |\n = /bin/ld: target/debug/deps/cxx-demo-7cb7fddf3d67d880.rcgu.o: in function `cxx_demo::ffi::new_blobstore_client':\n   src/main.rs:1: undefined reference to `cxxbridge1$new_blobstore_client'\n   collect2: error: ld returned 1 exit status\n```\n\n## Adding in the C++ code\n\nIn CXX's integration with Cargo, all #include paths begin with a crate name by\ndefault (when not explicitly selected otherwise by a crate; see\n`CFG.include_prefix` in chapter 5). That's why we see\n`include!(\"cxx-demo/include/blobstore.h\")` above &mdash; we'll be putting the\nC++ header at relative path `include/blobstore.h` within the Rust crate. If your\ncrate is named something other than `cxx-demo` according to the `name` field in\nCargo.toml, you will need to use that name everywhere in place of `cxx-demo`\nthroughout this tutorial.\n\n```cpp\n// include/blobstore.h\n\n#pragma once\n#include <memory>\n\nclass BlobstoreClient {\npublic:\n  BlobstoreClient();\n};\n\nstd::unique_ptr<BlobstoreClient> new_blobstore_client();\n```\n\n```cpp\n// src/blobstore.cc\n\n#include \"cxx-demo/include/blobstore.h\"\n\nBlobstoreClient::BlobstoreClient() {}\n\nstd::unique_ptr<BlobstoreClient> new_blobstore_client() {\n  return std::unique_ptr<BlobstoreClient>(new BlobstoreClient());\n}\n```\n\nUsing `std::make_unique` would work too, as long as you pass `std(\"c++14\")` to\nthe C++ compiler as described later on.\n\nThe placement in *include/* and *src/* is not significant; you can place C++\ncode anywhere else in the crate as long as you use the right paths throughout\nthe tutorial.\n\nBe aware that *CXX does not look at any of these files.* You're free to put\narbitrary C++ code in here, #include your own libraries, etc. All we do is emit\nstatic assertions against what you provide in the headers.\n\n## Compiling the C++ code with Cargo\n\nCargo has a [build scripts] feature suitable for compiling non-Rust code.\n\nWe need to introduce a new build-time dependency on CXX's C++ code generator in\nCargo.toml:\n\n```toml,hidelines=...\n# Cargo.toml\n...[package]\n...name = \"cxx-demo\"\n...version = \"0.1.0\"\n...edition = \"2021\"\n\n[dependencies]\ncxx = \"1.0\"\n\n[build-dependencies]\ncxx-build = \"1.0\"\n```\n\nThen add a build.rs build script adjacent to Cargo.toml to run the cxx-build\ncode generator and C++ compiler. The relevant arguments are the path to the Rust\nsource file containing the cxx::bridge language boundary definition, and the\npaths to any additional C++ source files to be compiled during the Rust crate's\nbuild.\n\n```rust,noplayground\n// build.rs\n\nfn main() {\n    cxx_build::bridge(\"src/main.rs\")\n        .file(\"src/blobstore.cc\")\n        .compile(\"cxx-demo\");\n\n    println!(\"cargo:rerun-if-changed=src/blobstore.cc\");\n    println!(\"cargo:rerun-if-changed=include/blobstore.h\");\n}\n```\n\nThis build.rs would also be where you set up C++ compiler flags, for example if\nyou'd like to have access to `std::make_unique` from C++14. See the page on\n***[Cargo-based builds](build/cargo.md)*** for more details about CXX's Cargo\nintegration.\n\n```rust,noplayground\n# // build.rs\n#\n# fn main() {\n    cxx_build::bridge(\"src/main.rs\")\n        .file(\"src/blobstore.cc\")\n        .std(\"c++14\")\n        .compile(\"cxx-demo\");\n# }\n```\n\n[build scripts]: https://doc.rust-lang.org/cargo/reference/build-scripts.html\n\nThe project should now build and run successfully, though not do anything useful\nyet.\n\n```console\ncxx-demo$  cargo run\n  Compiling cxx-demo v0.1.0\n  Finished dev [unoptimized + debuginfo] target(s) in 0.34s\n  Running `target/debug/cxx-demo`\n\ncxx-demo$\n```\n\n## Calling a Rust function from C++\n\nOur C++ blobstore supports a `put` operation for a discontiguous buffer upload.\nFor example we might be uploading snapshots of a circular buffer which would\ntend to consist of 2 pieces, or fragments of a file spread across memory for\nsome other reason (like a rope data structure).\n\nWe'll express this by handing off an iterator over contiguous borrowed chunks.\nThis loosely resembles the API of the widely used `bytes` crate's `Buf` trait.\nDuring a `put`, we'll make C++ call back into Rust to obtain contiguous chunks\nof the upload (all with no copying or allocation on the language boundary). In\nreality the C++ client might contain some sophisticated batching of chunks\nand/or parallel uploading that all of this ties into.\n\n```rust,noplayground\n// src/main.rs\n\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type MultiBuf;\n\n        fn next_chunk(buf: &mut MultiBuf) -> &[u8];\n    }\n\n    unsafe extern \"C++\" {\n        include!(\"cxx-demo/include/blobstore.h\");\n\n        type BlobstoreClient;\n\n        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;\n        fn put(&self, parts: &mut MultiBuf) -> u64;\n    }\n}\n#\n# fn main() {\n#     let client = ffi::new_blobstore_client();\n# }\n```\n\nAny signature having a `self` parameter (the Rust name for C++'s `this`) is\nconsidered a method / non-static member function. If there is only one `type` in\nthe surrounding extern block, it'll be a method of that type. If there is more\nthan one `type`, you can disambiguate which one a method belongs to by writing\n`self: &BlobstoreClient` in the argument list.\n\nAs usual, now we need to provide Rust definitions of everything declared by the\n`extern \"Rust\"` block and a C++ definition of the new signature declared by the\n`extern \"C++\"` block.\n\n```rust,noplayground\n// src/main.rs\n#\n# #[cxx::bridge]\n# mod ffi {\n#     extern \"Rust\" {\n#         type MultiBuf;\n#\n#         fn next_chunk(buf: &mut MultiBuf) -> &[u8];\n#     }\n#\n#     unsafe extern \"C++\" {\n#         include!(\"cxx-demo/include/blobstore.h\");\n#\n#         type BlobstoreClient;\n#\n#         fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;\n#         fn put(&self, parts: &mut MultiBuf) -> u64;\n#     }\n# }\n\n// An iterator over contiguous chunks of a discontiguous file object. Toy\n// implementation uses a Vec<Vec<u8>> but in reality this might be iterating\n// over some more complex Rust data structure like a rope, or maybe loading\n// chunks lazily from somewhere.\npub struct MultiBuf {\n    chunks: Vec<Vec<u8>>,\n    pos: usize,\n}\n\npub fn next_chunk(buf: &mut MultiBuf) -> &[u8] {\n    let next = buf.chunks.get(buf.pos);\n    buf.pos += 1;\n    next.map_or(&[], Vec::as_slice)\n}\n#\n# fn main() {\n#     let client = ffi::new_blobstore_client();\n# }\n```\n\n```cpp,hidelines=...\n// include/blobstore.h\n\n...#pragma once\n...#include <memory>\n...\nstruct MultiBuf;\n\nclass BlobstoreClient {\npublic:\n  BlobstoreClient();\n  uint64_t put(MultiBuf &buf) const;\n};\n...\n...std::unique_ptr<BlobstoreClient> new_blobstore_client();\n```\n\nIn blobstore.cc we're able to call the Rust `next_chunk` function, exposed to\nC++ by a header `main.rs.h` generated by the CXX code generator. In CXX's Cargo\nintegration this generated header has a path containing the crate name, the\nrelative path of the Rust source file within the crate, and a `.rs.h` extension.\n\n```cpp,hidelines=...\n// src/blobstore.cc\n\n#include \"cxx-demo/include/blobstore.h\"\n#include \"cxx-demo/src/main.rs.h\"\n#include <functional>\n#include <string>\n...\n...BlobstoreClient::BlobstoreClient() {}\n...\n...std::unique_ptr<BlobstoreClient> new_blobstore_client() {\n...  return std::make_unique<BlobstoreClient>();\n...}\n\n// Upload a new blob and return a blobid that serves as a handle to the blob.\nuint64_t BlobstoreClient::put(MultiBuf &buf) const {\n  // Traverse the caller's chunk iterator.\n  std::string contents;\n  while (true) {\n    auto chunk = next_chunk(buf);\n    if (chunk.size() == 0) {\n      break;\n    }\n    contents.append(reinterpret_cast<const char *>(chunk.data()), chunk.size());\n  }\n\n  // Pretend we did something useful to persist the data.\n  auto blobid = std::hash<std::string>{}(contents);\n  return blobid;\n}\n```\n\nThis is now ready to use. :)\n\n```rust,noplayground\n// src/main.rs\n#\n# #[cxx::bridge]\n# mod ffi {\n#     extern \"Rust\" {\n#         type MultiBuf;\n#\n#         fn next_chunk(buf: &mut MultiBuf) -> &[u8];\n#     }\n#\n#     unsafe extern \"C++\" {\n#         include!(\"cxx-demo/include/blobstore.h\");\n#\n#         type BlobstoreClient;\n#\n#         fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;\n#         fn put(&self, parts: &mut MultiBuf) -> u64;\n#     }\n# }\n#\n# pub struct MultiBuf {\n#     chunks: Vec<Vec<u8>>,\n#     pos: usize,\n# }\n# pub fn next_chunk(buf: &mut MultiBuf) -> &[u8] {\n#     let next = buf.chunks.get(buf.pos);\n#     buf.pos += 1;\n#     next.map_or(&[], Vec::as_slice)\n# }\n\nfn main() {\n    let client = ffi::new_blobstore_client();\n\n    // Upload a blob.\n    let chunks = vec![b\"fearless\".to_vec(), b\"concurrency\".to_vec()];\n    let mut buf = MultiBuf { chunks, pos: 0 };\n    let blobid = client.put(&mut buf);\n    println!(\"blobid = {blobid}\");\n}\n```\n\n```console\ncxx-demo$  cargo run\n  Compiling cxx-demo v0.1.0\n  Finished dev [unoptimized + debuginfo] target(s) in 0.41s\n  Running `target/debug/cxx-demo`\n\nblobid = 9851996977040795552\n```\n\n## Interlude: What gets generated?\n\nFor the curious, it's easy to look behind the scenes at what CXX has done to\nmake these function calls work. You shouldn't need to do this during normal\nusage of CXX, but for the purpose of this tutorial it can be educative.\n\nCXX comprises *two* code generators: a Rust one (which is the cxx::bridge\nattribute procedural macro) and a C++ one.\n\n### Rust generated code\n\nIt's easiest to view the output of the procedural macro by installing\n[cargo-expand]. Then run `cargo expand ::ffi` to macro-expand the `mod ffi`\nmodule.\n\n[cargo-expand]: https://github.com/dtolnay/cargo-expand\n\n```console\ncxx-demo$  cargo install cargo-expand\ncxx-demo$  cargo expand ::ffi\n```\n\nYou'll see some deeply unpleasant code involving `#[repr(C)]`, `#[link_name]`,\nand `#[export_name]`.\n\n### C++ generated code\n\nFor debugging convenience, `cxx_build` links all generated C++ code into Cargo's\ntarget directory under *target/cxxbridge/*.\n\n```console\ncxx-demo$  exa -T target/cxxbridge/\ntarget/cxxbridge\n├── cxx-demo\n│  └── src\n│     ├── main.rs.cc -> ../../../debug/build/cxx-demo-11c6f678ce5c3437/out/cxxbridge/sources/cxx-demo/src/main.rs.cc\n│     └── main.rs.h -> ../../../debug/build/cxx-demo-11c6f678ce5c3437/out/cxxbridge/include/cxx-demo/src/main.rs.h\n└── rust\n   └── cxx.h -> ~/.cargo/registry/src/github.com-1ecc6299db9ec823/cxx-1.0.0/include/cxx.h\n```\n\nIn those files you'll see declarations or templates of any CXX Rust types\npresent in your language boundary (like `rust::Slice<T>` for `&[T]`) and `extern\n\"C\"` signatures corresponding to your extern functions.\n\nIf it fits your workflow better, the CXX C++ code generator is also available as\na standalone executable which outputs generated code to stdout.\n\n```console\ncxx-demo$  cargo install cxxbridge-cmd\ncxx-demo$  cxxbridge src/main.rs\n```\n\n## Shared data structures\n\nSo far the calls in both directions above only used **opaque types**, not\n**shared structs**.\n\nShared structs are data structures whose complete definition is visible to both\nlanguages, making it possible to pass them by value across the language\nboundary. Shared structs translate to a C++ aggregate-initialization compatible\nstruct exactly matching the layout of the Rust one.\n\nAs the last step of this demo, we'll use a shared struct `BlobMetadata` to pass\nmetadata about blobs between our Rust application and C++ blobstore client.\n\n```rust,noplayground\n// src/main.rs\n\n#[cxx::bridge]\nmod ffi {\n    struct BlobMetadata {\n        size: usize,\n        tags: Vec<String>,\n    }\n\n    extern \"Rust\" {\n        // ...\n#         type MultiBuf;\n#\n#         fn next_chunk(buf: &mut MultiBuf) -> &[u8];\n    }\n\n    unsafe extern \"C++\" {\n        // ...\n#         include!(\"cxx-demo/include/blobstore.h\");\n#\n#         type BlobstoreClient;\n#\n#         fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;\n#         fn put(&self, parts: &mut MultiBuf) -> u64;\n        fn tag(&self, blobid: u64, tag: &str);\n        fn metadata(&self, blobid: u64) -> BlobMetadata;\n    }\n}\n#\n# pub struct MultiBuf {\n#     chunks: Vec<Vec<u8>>,\n#     pos: usize,\n# }\n# pub fn next_chunk(buf: &mut MultiBuf) -> &[u8] {\n#     let next = buf.chunks.get(buf.pos);\n#     buf.pos += 1;\n#     next.map_or(&[], Vec::as_slice)\n# }\n\nfn main() {\n    let client = ffi::new_blobstore_client();\n\n    // Upload a blob.\n    let chunks = vec![b\"fearless\".to_vec(), b\"concurrency\".to_vec()];\n    let mut buf = MultiBuf { chunks, pos: 0 };\n    let blobid = client.put(&mut buf);\n    println!(\"blobid = {blobid}\");\n\n    // Add a tag.\n    client.tag(blobid, \"rust\");\n\n    // Read back the tags.\n    let metadata = client.metadata(blobid);\n    println!(\"tags = {:?}\", metadata.tags);\n}\n```\n\n```cpp,hidelines=...\n// include/blobstore.h\n\n#pragma once\n#include \"rust/cxx.h\"\n...#include <memory>\n\nstruct MultiBuf;\nstruct BlobMetadata;\n\nclass BlobstoreClient {\npublic:\n  BlobstoreClient();\n  uint64_t put(MultiBuf &buf) const;\n  void tag(uint64_t blobid, rust::Str tag) const;\n  BlobMetadata metadata(uint64_t blobid) const;\n\nprivate:\n  class impl;\n  std::shared_ptr<impl> impl;\n};\n...\n...std::unique_ptr<BlobstoreClient> new_blobstore_client();\n```\n\n```cpp,hidelines=...\n// src/blobstore.cc\n\n#include \"cxx-demo/include/blobstore.h\"\n#include \"cxx-demo/src/main.rs.h\"\n#include <algorithm>\n#include <functional>\n#include <set>\n#include <string>\n#include <unordered_map>\n\n// Toy implementation of an in-memory blobstore.\n//\n// In reality the implementation of BlobstoreClient could be a large\n// complex C++ library.\nclass BlobstoreClient::impl {\n  friend BlobstoreClient;\n  using Blob = struct {\n    std::string data;\n    std::set<std::string> tags;\n  };\n  std::unordered_map<uint64_t, Blob> blobs;\n};\n\nBlobstoreClient::BlobstoreClient() : impl(new class BlobstoreClient::impl) {}\n...\n...// Upload a new blob and return a blobid that serves as a handle to the blob.\n...uint64_t BlobstoreClient::put(MultiBuf &buf) const {\n...  // Traverse the caller's chunk iterator.\n...  std::string contents;\n...  while (true) {\n...    auto chunk = next_chunk(buf);\n...    if (chunk.size() == 0) {\n...      break;\n...    }\n...    contents.append(reinterpret_cast<const char *>(chunk.data()), chunk.size());\n...  }\n...\n...  // Insert into map and provide caller the handle.\n...  auto blobid = std::hash<std::string>{}(contents);\n...  impl->blobs[blobid] = {std::move(contents), {}};\n...  return blobid;\n...}\n\n// Add tag to an existing blob.\nvoid BlobstoreClient::tag(uint64_t blobid, rust::Str tag) const {\n  impl->blobs[blobid].tags.emplace(tag);\n}\n\n// Retrieve metadata about a blob.\nBlobMetadata BlobstoreClient::metadata(uint64_t blobid) const {\n  BlobMetadata metadata{};\n  auto blob = impl->blobs.find(blobid);\n  if (blob != impl->blobs.end()) {\n    metadata.size = blob->second.data.size();\n    std::for_each(blob->second.tags.cbegin(), blob->second.tags.cend(),\n                  [&](auto &t) { metadata.tags.emplace_back(t); });\n  }\n  return metadata;\n}\n...\n...std::unique_ptr<BlobstoreClient> new_blobstore_client() {\n...  return std::make_unique<BlobstoreClient>();\n...}\n```\n\n```console\ncxx-demo$  cargo run\n  Running `target/debug/cxx-demo`\n\nblobid = 9851996977040795552\ntags = [\"rust\"]\n```\n\n*You've now seen all the code involved in the tutorial. It's available all\ntogether in runnable form in the* demo *directory of\n<https://github.com/dtolnay/cxx>. You can run it directly without stepping\nthrough the steps above by running `cargo run` from that directory.*\n\n<br>\n\n# Takeaways\n\nThe key contribution of CXX is it gives you Rust&ndash;C++ interop in which\n*all* of the Rust side of the code you write *really* looks like you are just\nwriting normal Rust, and the C++ side *really* looks like you are just writing\nnormal C++.\n\nYou've seen in this tutorial that none of the code involved feels like C or like\nthe usual perilous \"FFI glue\" prone to leaks or memory safety flaws.\n\nAn expressive system of opaque types, shared types, and key standard library\ntype bindings enables API design on the language boundary that captures the\nproper ownership and borrowing contracts of the interface.\n\nCXX plays to the strengths of the Rust type system *and* C++ type system *and*\nthe programmer's intuitions. An individual working on the C++ side without a\nRust background, or the Rust side without a C++ background, will be able to\napply all their usual intuitions and best practices about development in their\nlanguage to maintain a correct FFI.\n\n<br><br>\n"
  },
  {
    "path": "book/theme/head.hbs",
    "content": "<script async src=\"https://www.googletagmanager.com/gtag/js?id=G-DG41MK6DDN\"></script>\n<script>\n  window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n  gtag('config', 'G-DG41MK6DDN', {anonymize_ip: true, cookie_domain: 'cxx.rs', cookie_flags: 'samesite=strict;secure'});\n</script>\n"
  },
  {
    "path": "build.rs",
    "content": "#![expect(unexpected_cfgs)]\n\nuse std::env;\nuse std::path::{Path, PathBuf};\nuse std::process::Command;\n\nfn main() {\n    let manifest_dir_opt = env::var_os(\"CARGO_MANIFEST_DIR\").map(PathBuf::from);\n    let manifest_dir = manifest_dir_opt.as_deref().unwrap_or(Path::new(\"\"));\n\n    cc::Build::new()\n        .file(manifest_dir.join(\"src/cxx.cc\"))\n        .cpp(true)\n        .cpp_link_stdlib(None) // linked via link-cplusplus crate\n        .std(cxxbridge_flags::STD)\n        .warnings_into_errors(cfg!(deny_warnings))\n        .compile(\"cxxbridge1\");\n\n    println!(\"cargo:rerun-if-changed=src/cxx.cc\");\n    println!(\"cargo:rerun-if-changed=include/cxx.h\");\n    println!(\"cargo:rustc-cfg=built_with_cargo\");\n\n    if let Some(manifest_dir) = &manifest_dir_opt {\n        let cxx_h = manifest_dir.join(\"include\").join(\"cxx.h\");\n        println!(\"cargo:HEADER={}\", cxx_h.to_string_lossy());\n    }\n\n    println!(\"cargo:rustc-check-cfg=cfg(built_with_cargo)\");\n    println!(\"cargo:rustc-check-cfg=cfg(compile_error_if_alloc)\");\n    println!(\"cargo:rustc-check-cfg=cfg(compile_error_if_std)\");\n    println!(\"cargo:rustc-check-cfg=cfg(cxx_experimental_no_alloc)\");\n    println!(\"cargo:rustc-check-cfg=cfg(skip_ui_tests)\");\n\n    if let Some(rustc) = rustc_version() {\n        if rustc.minor < 85 {\n            println!(\"cargo:warning=The cxx crate requires a rustc version 1.85.0 or newer.\");\n            println!(\n                \"cargo:warning=You appear to be building with: {}\",\n                rustc.version,\n            );\n        }\n    }\n\n    if let (Some(manifest_links), Some(pkg_version_major)) = (\n        env::var_os(\"CARGO_MANIFEST_LINKS\"),\n        env::var_os(\"CARGO_PKG_VERSION_MAJOR\"),\n    ) {\n        assert_eq!(\n            manifest_links,\n            *format!(\"cxxbridge{}\", pkg_version_major.to_str().unwrap()),\n        );\n    }\n}\n\nstruct RustVersion {\n    version: String,\n    minor: u32,\n}\n\nfn rustc_version() -> Option<RustVersion> {\n    let rustc = env::var_os(\"RUSTC\")?;\n    let output = Command::new(rustc).arg(\"--version\").output().ok()?;\n    let version = String::from_utf8(output.stdout).ok()?;\n    let mut pieces = version.split('.');\n    if pieces.next() != Some(\"rustc 1\") {\n        return None;\n    }\n    let minor = pieces.next()?.parse().ok()?;\n    Some(RustVersion { version, minor })\n}\n"
  },
  {
    "path": "compile_flags.txt",
    "content": "-std=c++20\n"
  },
  {
    "path": "demo/BUCK",
    "content": "load(\"//tools/buck:rust_cxx_bridge.bzl\", \"rust_cxx_bridge\")\n\nrust_binary(\n    name = \"demo\",\n    srcs = glob([\"src/**/*.rs\"]),\n    edition = \"2021\",\n    deps = [\n        \":blobstore-sys\",\n        \":bridge\",\n        \"//:cxx\",\n    ],\n)\n\nrust_cxx_bridge(\n    name = \"bridge\",\n    src = \"src/main.rs\",\n    deps = [\":blobstore-include\"],\n)\n\ncxx_library(\n    name = \"blobstore-sys\",\n    srcs = [\"src/blobstore.cc\"],\n    preferred_linkage = \"static\",\n    deps = [\n        \":blobstore-include\",\n        \":bridge/include\",\n    ],\n)\n\ncxx_library(\n    name = \"blobstore-include\",\n    exported_deps = [\"//:core\"],\n    exported_headers = [\"include/blobstore.h\"],\n)\n"
  },
  {
    "path": "demo/BUILD.bazel",
    "content": "load(\"@rules_cc//cc:defs.bzl\", \"cc_library\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_binary\")\nload(\"//tools/bazel:rust_cxx_bridge.bzl\", \"rust_cxx_bridge\")\n\nrust_binary(\n    name = \"demo\",\n    srcs = glob([\"src/**/*.rs\"]),\n    edition = \"2021\",\n    deps = [\n        \":blobstore-sys\",\n        \":bridge\",\n        \"//:cxx\",\n    ],\n)\n\nrust_cxx_bridge(\n    name = \"bridge\",\n    src = \"src/main.rs\",\n    deps = [\":blobstore-include\"],\n)\n\ncc_library(\n    name = \"blobstore-sys\",\n    srcs = [\"src/blobstore.cc\"],\n    linkstatic = True,\n    deps = [\n        \":blobstore-include\",\n        \":bridge/include\",\n    ],\n)\n\ncc_library(\n    name = \"blobstore-include\",\n    hdrs = [\"include/blobstore.h\"],\n    deps = [\"//:core\"],\n)\n"
  },
  {
    "path": "demo/Cargo.toml",
    "content": "[package]\nname = \"demo\"\nversion = \"0.0.0\"\nauthors = [\"David Tolnay <dtolnay@gmail.com>\"]\ndescription = \"Toy project from https://github.com/dtolnay/cxx\"\nedition = \"2021\"\nlicense = \"MIT OR Apache-2.0\"\npublish = false\nrepository = \"https://github.com/dtolnay/cxx\"\n\n[dependencies]\ncxx = \"1.0\"\n\n[build-dependencies]\ncxx-build = \"1.0\"\n"
  },
  {
    "path": "demo/build.rs",
    "content": "fn main() {\n    cxx_build::bridge(\"src/main.rs\")\n        .file(\"src/blobstore.cc\")\n        .std(\"c++14\")\n        .compile(\"cxxbridge-demo\");\n\n    println!(\"cargo:rerun-if-changed=src/blobstore.cc\");\n    println!(\"cargo:rerun-if-changed=include/blobstore.h\");\n}\n"
  },
  {
    "path": "demo/include/blobstore.h",
    "content": "#pragma once\n#include \"rust/cxx.h\"\n#include <memory>\n\nnamespace org {\nnamespace blobstore {\n\nstruct MultiBuf;\nstruct BlobMetadata;\n\nclass BlobstoreClient {\npublic:\n  BlobstoreClient();\n  uint64_t put(MultiBuf &buf) const;\n  void tag(uint64_t blobid, rust::Str tag) const;\n  BlobMetadata metadata(uint64_t blobid) const;\n\nprivate:\n  class impl;\n  std::shared_ptr<impl> impl;\n};\n\nstd::unique_ptr<BlobstoreClient> new_blobstore_client();\n\n} // namespace blobstore\n} // namespace org\n"
  },
  {
    "path": "demo/src/blobstore.cc",
    "content": "#include \"demo/include/blobstore.h\"\n#include \"demo/src/main.rs.h\"\n#include <algorithm>\n#include <functional>\n#include <set>\n#include <string>\n#include <unordered_map>\n\nnamespace org {\nnamespace blobstore {\n\n// Toy implementation of an in-memory blobstore.\n//\n// In reality the implementation of BlobstoreClient could be a large complex C++\n// library.\nclass BlobstoreClient::impl {\n  friend BlobstoreClient;\n  using Blob = struct {\n    std::string data;\n    std::set<std::string> tags;\n  };\n  std::unordered_map<uint64_t, Blob> blobs;\n};\n\nBlobstoreClient::BlobstoreClient() : impl(new class BlobstoreClient::impl) {}\n\n// Upload a new blob and return a blobid that serves as a handle to the blob.\nuint64_t BlobstoreClient::put(MultiBuf &buf) const {\n  std::string contents;\n\n  // Traverse the caller's chunk iterator.\n  //\n  // In reality there might be sophisticated batching of chunks and/or parallel\n  // upload implemented by the blobstore's C++ client.\n  while (true) {\n    auto chunk = next_chunk(buf);\n    if (chunk.size() == 0) {\n      break;\n    }\n    contents.append(reinterpret_cast<const char *>(chunk.data()), chunk.size());\n  }\n\n  // Insert into map and provide caller the handle.\n  auto blobid = std::hash<std::string>{}(contents);\n  impl->blobs[blobid] = {std::move(contents), {}};\n  return blobid;\n}\n\n// Add tag to an existing blob.\nvoid BlobstoreClient::tag(uint64_t blobid, rust::Str tag) const {\n  impl->blobs[blobid].tags.emplace(tag);\n}\n\n// Retrieve metadata about a blob.\nBlobMetadata BlobstoreClient::metadata(uint64_t blobid) const {\n  BlobMetadata metadata{};\n  auto blob = impl->blobs.find(blobid);\n  if (blob != impl->blobs.end()) {\n    metadata.size = blob->second.data.size();\n    std::for_each(blob->second.tags.cbegin(), blob->second.tags.cend(),\n                  [&](auto &t) { metadata.tags.emplace_back(t); });\n  }\n  return metadata;\n}\n\nstd::unique_ptr<BlobstoreClient> new_blobstore_client() {\n  return std::make_unique<BlobstoreClient>();\n}\n\n} // namespace blobstore\n} // namespace org\n"
  },
  {
    "path": "demo/src/main.rs",
    "content": "#[cxx::bridge(namespace = \"org::blobstore\")]\nmod ffi {\n    // Shared structs with fields visible to both languages.\n    struct BlobMetadata {\n        size: usize,\n        tags: Vec<String>,\n    }\n\n    // Rust types and signatures exposed to C++.\n    extern \"Rust\" {\n        type MultiBuf;\n\n        fn next_chunk(buf: &mut MultiBuf) -> &[u8];\n    }\n\n    // C++ types and signatures exposed to Rust.\n    unsafe extern \"C++\" {\n        include!(\"demo/include/blobstore.h\");\n\n        type BlobstoreClient;\n\n        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;\n        fn put(&self, parts: &mut MultiBuf) -> u64;\n        fn tag(&self, blobid: u64, tag: &str);\n        fn metadata(&self, blobid: u64) -> BlobMetadata;\n    }\n}\n\n// An iterator over contiguous chunks of a discontiguous file object.\n//\n// Toy implementation uses a Vec<Vec<u8>> but in reality this might be iterating\n// over some more complex Rust data structure like a rope, or maybe loading\n// chunks lazily from somewhere.\npub struct MultiBuf {\n    chunks: Vec<Vec<u8>>,\n    pos: usize,\n}\npub fn next_chunk(buf: &mut MultiBuf) -> &[u8] {\n    let next = buf.chunks.get(buf.pos);\n    buf.pos += 1;\n    next.map_or(&[], Vec::as_slice)\n}\n\nfn main() {\n    let client = ffi::new_blobstore_client();\n\n    // Upload a blob.\n    let chunks = vec![b\"fearless\".to_vec(), b\"concurrency\".to_vec()];\n    let mut buf = MultiBuf { chunks, pos: 0 };\n    let blobid = client.put(&mut buf);\n    println!(\"blobid = {blobid}\");\n\n    // Add a tag.\n    client.tag(blobid, \"rust\");\n\n    // Read back the tags.\n    let metadata = client.metadata(blobid);\n    println!(\"tags = {:?}\", metadata.tags);\n}\n"
  },
  {
    "path": "flags/Cargo.toml",
    "content": "[package]\nname = \"cxxbridge-flags\"\nversion = \"1.0.194\"\nauthors = [\"David Tolnay <dtolnay@gmail.com>\"]\ncategories = [\"development-tools::ffi\", \"compilers\"]\ndescription = \"Compiler configuration of the `cxx` crate (implementation detail)\"\nedition = \"2021\"\nlicense = \"MIT OR Apache-2.0\"\nrepository = \"https://github.com/dtolnay/cxx\"\nrust-version = \"1.85\"\n\n[features]\ndefault = [] # c++11\n\"c++14\" = []\n\"c++17\" = []\n\"c++20\" = []\n\n[package.metadata.docs.rs]\ntargets = [\"x86_64-unknown-linux-gnu\"]\nrustdoc-args = [\n    \"--generate-link-to-definition\",\n    \"--generate-macro-expansion\",\n    \"--extern-html-root-url=core=https://doc.rust-lang.org\",\n    \"--extern-html-root-url=alloc=https://doc.rust-lang.org\",\n    \"--extern-html-root-url=std=https://doc.rust-lang.org\",\n]\n"
  },
  {
    "path": "flags/src/impl.rs",
    "content": "#[allow(unused_assignments, unused_mut, unused_variables)]\npub const STD: &str = {\n    let mut flag = \"c++11\";\n\n    #[cfg(feature = \"c++14\")]\n    (flag = \"c++14\");\n\n    #[cfg(feature = \"c++17\")]\n    (flag = \"c++17\");\n\n    #[cfg(feature = \"c++20\")]\n    (flag = \"c++20\");\n\n    flag\n};\n"
  },
  {
    "path": "flags/src/lib.rs",
    "content": "//! This crate is an implementation detail of the `cxx` and `cxx-build` crates,\n//! and does not expose any public API.\n\nmod r#impl;\n\n#[doc(hidden)]\npub use r#impl::*;\n"
  },
  {
    "path": "gen/README.md",
    "content": "This directory contains CXX's C++ code generator. This code generator has two\npublic frontends, one a command-line application (binary) in the *cmd* directory\nand the other a library intended to be used from a build.rs in the *build*\ndirectory.\n\nThere's also a 'lib' frontend which is intended to allow higher level code\ngenerators to embed cxx. This is not yet recommended for general use.\n"
  },
  {
    "path": "gen/build/Cargo.toml",
    "content": "[package]\nname = \"cxx-build\"\nversion = \"1.0.194\"\nauthors = [\"David Tolnay <dtolnay@gmail.com>\"]\ncategories = [\"development-tools::build-utils\", \"development-tools::ffi\"]\ndescription = \"C++ code generator for integrating `cxx` crate into a Cargo build.\"\ndocumentation = \"https://docs.rs/cxx-build\"\nedition = \"2021\"\nexclude = [\"build.rs\"]\nhomepage = \"https://cxx.rs\"\nkeywords = [\"ffi\", \"build-dependencies\"]\nlicense = \"MIT OR Apache-2.0\"\nrepository = \"https://github.com/dtolnay/cxx\"\nrust-version = \"1.85\"\n\n[features]\nparallel = [\"cc/parallel\"]\n\n[dependencies]\ncc = \"1.0.101\"\ncodespan-reporting = \"0.13.1\"\nindexmap = \"2.9.0\"\nproc-macro2 = { version = \"1.0.74\", default-features = false, features = [\"span-locations\"] }\nquote = { version = \"1.0.35\", default-features = false }\nscratch = \"1.0.5\"\nsyn = { version = \"2.0.46\", default-features = false, features = [\"clone-impls\", \"full\", \"parsing\", \"printing\"] }\n\n[dev-dependencies]\ncxx = { version = \"1.0\", path = \"../..\" }\ncxx-gen = { version = \"0.7\", path = \"../lib\" }\npkg-config = \"0.3.27\"\n\n[package.metadata.docs.rs]\ntargets = [\"x86_64-unknown-linux-gnu\"]\nrustdoc-args = [\n    \"--generate-link-to-definition\",\n    \"--generate-macro-expansion\",\n    \"--extern-html-root-url=core=https://doc.rust-lang.org\",\n    \"--extern-html-root-url=alloc=https://doc.rust-lang.org\",\n    \"--extern-html-root-url=std=https://doc.rust-lang.org\",\n]\n"
  },
  {
    "path": "gen/build/build.rs",
    "content": "include!(\"../../tools/cargo/build.rs\");\n"
  },
  {
    "path": "gen/build/src/cargo.rs",
    "content": "use crate::gen::{CfgEvaluator, CfgResult};\nuse std::borrow::Borrow;\nuse std::cmp::Ordering;\nuse std::collections::{BTreeMap as Map, BTreeSet as Set};\nuse std::env;\nuse std::ptr;\nuse std::sync::OnceLock;\n\nstatic ENV: OnceLock<CargoEnv> = OnceLock::new();\n\nstruct CargoEnv {\n    features: Set<Name>,\n    cfgs: Map<Name, String>,\n}\n\npub(super) struct CargoEnvCfgEvaluator;\n\nimpl CfgEvaluator for CargoEnvCfgEvaluator {\n    fn eval(&self, name: &str, query_value: Option<&str>) -> CfgResult {\n        let env = ENV.get_or_init(CargoEnv::load);\n        if name == \"feature\" {\n            return if let Some(query_value) = query_value {\n                CfgResult::from(env.features.contains(Lookup::new(query_value)))\n            } else {\n                let msg = \"expected `feature = \\\"...\\\"`\".to_owned();\n                CfgResult::Undetermined { msg }\n            };\n        }\n        if name == \"test\" && query_value.is_none() {\n            let msg = \"cfg(test) is not supported because Cargo runs your build script only once across the lib and test build of the same crate\".to_owned();\n            return CfgResult::Undetermined { msg };\n        }\n        if let Some(cargo_value) = env.cfgs.get(Lookup::new(name)) {\n            return if let Some(query_value) = query_value {\n                CfgResult::from(cargo_value.split(',').any(|value| value == query_value))\n            } else {\n                CfgResult::True\n            };\n        }\n        if name == \"debug_assertions\" && query_value.is_none() {\n            return CfgResult::from(cfg!(debug_assertions));\n        }\n        CfgResult::False\n    }\n}\n\nimpl CargoEnv {\n    fn load() -> Self {\n        const CARGO_FEATURE_PREFIX: &str = \"CARGO_FEATURE_\";\n        const CARGO_CFG_PREFIX: &str = \"CARGO_CFG_\";\n\n        let mut features = Set::new();\n        let mut cfgs = Map::new();\n        for (k, v) in env::vars_os() {\n            let Some(k) = k.to_str() else {\n                continue;\n            };\n            let Ok(v) = v.into_string() else {\n                continue;\n            };\n            if let Some(feature_name) = k.strip_prefix(CARGO_FEATURE_PREFIX) {\n                let feature_name = Name(feature_name.to_owned());\n                features.insert(feature_name);\n            } else if let Some(cfg_name) = k.strip_prefix(CARGO_CFG_PREFIX) {\n                let cfg_name = Name(cfg_name.to_owned());\n                cfgs.insert(cfg_name, v);\n            }\n        }\n        CargoEnv { features, cfgs }\n    }\n}\n\nstruct Name(String);\n\nimpl Ord for Name {\n    fn cmp(&self, rhs: &Self) -> Ordering {\n        Lookup::new(&self.0).cmp(Lookup::new(&rhs.0))\n    }\n}\n\nimpl PartialOrd for Name {\n    fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {\n        Some(self.cmp(rhs))\n    }\n}\n\nimpl Eq for Name {}\n\nimpl PartialEq for Name {\n    fn eq(&self, rhs: &Self) -> bool {\n        Lookup::new(&self.0).eq(Lookup::new(&rhs.0))\n    }\n}\n\n#[repr(transparent)]\nstruct Lookup(str);\n\nimpl Lookup {\n    fn new(name: &str) -> &Self {\n        unsafe { &*(ptr::from_ref::<str>(name) as *const Self) }\n    }\n}\n\nimpl Borrow<Lookup> for Name {\n    fn borrow(&self) -> &Lookup {\n        Lookup::new(&self.0)\n    }\n}\n\nimpl Ord for Lookup {\n    fn cmp(&self, rhs: &Self) -> Ordering {\n        self.0\n            .bytes()\n            .map(CaseAgnosticByte)\n            .cmp(rhs.0.bytes().map(CaseAgnosticByte))\n    }\n}\n\nimpl PartialOrd for Lookup {\n    fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {\n        Some(self.cmp(rhs))\n    }\n}\n\nimpl Eq for Lookup {}\n\nimpl PartialEq for Lookup {\n    fn eq(&self, rhs: &Self) -> bool {\n        self.0\n            .bytes()\n            .map(CaseAgnosticByte)\n            .eq(rhs.0.bytes().map(CaseAgnosticByte))\n    }\n}\n\nstruct CaseAgnosticByte(u8);\n\nimpl Ord for CaseAgnosticByte {\n    fn cmp(&self, rhs: &Self) -> Ordering {\n        self.0.to_ascii_lowercase().cmp(&rhs.0.to_ascii_lowercase())\n    }\n}\n\nimpl PartialOrd for CaseAgnosticByte {\n    fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {\n        Some(self.cmp(rhs))\n    }\n}\n\nimpl Eq for CaseAgnosticByte {}\n\nimpl PartialEq for CaseAgnosticByte {\n    fn eq(&self, rhs: &Self) -> bool {\n        self.cmp(rhs) == Ordering::Equal\n    }\n}\n"
  },
  {
    "path": "gen/build/src/cfg.rs",
    "content": "use std::fmt::{self, Debug};\nuse std::marker::PhantomData;\nuse std::path::Path;\n\n/// Build configuration. See [CFG].\npub struct Cfg<'a> {\n    /// See [`CFG.include_prefix`][CFG#cfginclude_prefix].\n    pub include_prefix: &'a str,\n    /// See [`CFG.exported_header_dirs`][CFG#cfgexported_header_dirs].\n    pub exported_header_dirs: Vec<&'a Path>,\n    /// See [`CFG.exported_header_prefixes`][CFG#cfgexported_header_prefixes].\n    pub exported_header_prefixes: Vec<&'a str>,\n    /// See [`CFG.exported_header_links`][CFG#cfgexported_header_links].\n    pub exported_header_links: Vec<&'a str>,\n    /// See [`CFG.doxygen`][CFG#cfgdoxygen].\n    pub doxygen: bool,\n    marker: PhantomData<*const ()>, // !Send + !Sync\n}\n\n/// Global configuration of the current build.\n///\n/// <br>\n///\n/// <div style=\"float:right;margin:22px 50px 0;font-size:1.15em;opacity:.73\"><strong>&amp;str</strong></div>\n///\n/// ## **`CFG.include_prefix`**\n///\n/// The prefix at which C++ code from your crate as well as directly dependent\n/// crates can access the code generated during this build.\n///\n/// By default, the `include_prefix` is equal to the name of the current crate.\n/// That means if your crate is called `demo` and has Rust source files in a\n/// *src/* directory and maybe some handwritten C++ header files in an\n/// *include/* directory, then the current crate as well as downstream crates\n/// might include them as follows:\n///\n/// ```\n/// # const _: &str = stringify! {\n///   // include one of the handwritten headers:\n/// #include \"demo/include/wow.h\"\n///\n///   // include a header generated from Rust cxx::bridge:\n/// #include \"demo/src/lib.rs.h\"\n/// # };\n/// ```\n///\n/// By modifying `CFG.include_prefix` we can substitute a prefix that is\n/// different from the crate name if desired. Here we'll change it to\n/// `\"path/to\"` which will make import paths take the form\n/// `\"path/to/include/wow.h\"` and `\"path/to/src/lib.rs.h\"`.\n///\n/// ```no_run\n/// // build.rs\n///\n/// use cxx_build::CFG;\n///\n/// fn main() {\n///     CFG.include_prefix = \"path/to\";\n///\n///     cxx_build::bridge(\"src/lib.rs\")\n///         .file(\"src/demo.cc\") // probably contains `#include \"path/to/src/lib.rs.h\"`\n///         /* ... */\n///         .compile(\"demo\");\n/// }\n/// ```\n///\n/// Note that cross-crate imports are only made available between **direct\n/// dependencies**. Another crate must directly depend on your crate in order to\n/// #include its headers; a transitive dependency is not sufficient.\n/// Additionally, headers from a direct dependency are only importable if the\n/// dependency's Cargo.toml manifest contains a `links` key. If not, its headers\n/// will not be importable from outside of the same crate.\n///\n/// <br>\n///\n/// <div style=\"float:right;margin:22px 50px 0;font-size:1.15em;opacity:.73\"><strong>Vec&lt;&amp;Path&gt;</strong></div>\n///\n/// ## **`CFG.exported_header_dirs`**\n///\n/// A vector of absolute paths. The current crate, directly dependent crates,\n/// and further crates to which this crate's headers are exported (see below)\n/// will be able to `#include` headers from these directories.\n///\n/// Adding a directory to `exported_header_dirs` is similar to adding it to the\n/// current build via the `cc` crate's [`Build::include`][cc::Build::include],\n/// but *also* makes the directory available to downstream crates that want to\n/// `#include` one of the headers from your crate. If the dir were added only\n/// using `Build::include`, the downstream crate including your header would\n/// need to manually add the same directory to their own build as well.\n///\n/// When using `exported_header_dirs`, your crate must also set a `links` key\n/// for itself in Cargo.toml. See [*the `links` manifest key*][links]. The\n/// reason is that Cargo imposes no ordering on the execution of build scripts\n/// without a `links` key, which means the downstream crate's build script might\n/// execute before yours decides what to put into `exported_header_dirs`.\n///\n/// [links]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key\n///\n/// ### Example\n///\n/// One of your crate's headers wants to include a system library, such as\n/// `#include \"Python.h\"`.\n///\n/// ```no_run\n/// // build.rs\n///\n/// use cxx_build::CFG;\n/// use std::path::PathBuf;\n///\n/// fn main() {\n///     let python3 = pkg_config::probe_library(\"python3\").unwrap();\n///     let python_include_paths = python3.include_paths.iter().map(PathBuf::as_path);\n///     CFG.exported_header_dirs.extend(python_include_paths);\n///\n///     cxx_build::bridge(\"src/bridge.rs\").compile(\"demo\");\n/// }\n/// ```\n///\n/// ### Example\n///\n/// Your crate wants to rearrange the headers that it exports vs how they're\n/// laid out locally inside the crate's source directory.\n///\n/// Suppose the crate as published contains a file at `./include/myheader.h` but\n/// wants it available to downstream crates as `#include \"foo/v1/public.h\"`.\n///\n/// ```no_run\n/// // build.rs\n///\n/// use cxx_build::CFG;\n/// use std::path::Path;\n/// use std::{env, fs};\n///\n/// fn main() {\n///     let out_dir = env::var_os(\"OUT_DIR\").unwrap();\n///     let headers = Path::new(&out_dir).join(\"headers\");\n///     CFG.exported_header_dirs.push(&headers);\n///\n///     // We contain `include/myheader.h` locally, but\n///     // downstream will use `#include \"foo/v1/public.h\"`\n///     let foo = headers.join(\"foo\").join(\"v1\");\n///     fs::create_dir_all(&foo).unwrap();\n///     fs::copy(\"include/myheader.h\", foo.join(\"public.h\")).unwrap();\n///\n///     cxx_build::bridge(\"src/bridge.rs\").compile(\"demo\");\n/// }\n/// ```\n///\n/// <p style=\"margin:0\"><br><br></p>\n///\n/// <div style=\"float:right;margin:22px 50px 0;font-size:1.15em;opacity:.73\"><strong>Vec&lt;&amp;str&gt;</strong></div>\n///\n/// ## **`CFG.exported_header_prefixes`**\n///\n/// Vector of strings. These each refer to the `include_prefix` of one of your\n/// direct dependencies, or a prefix thereof. They describe which of your\n/// dependencies participate in your crate's C++ public API, as opposed to\n/// private use by your crate's implementation.\n///\n/// As a general rule, if one of your headers `#include`s something from one of\n/// your dependencies, you need to put that dependency's `include_prefix` into\n/// `CFG.exported_header_prefixes` (*or* their `links` key into\n/// `CFG.exported_header_links`; see below). On the other hand if only your C++\n/// implementation files and *not* your headers are importing from the\n/// dependency, you do not export that dependency.\n///\n/// The significance of exported headers is that if downstream code (crate 𝒜)\n/// contains an `#include` of a header from your crate (ℬ) and your header\n/// contains an `#include` of something from your dependency (𝒞), the exported\n/// dependency 𝒞 becomes available during the downstream crate 𝒜's build.\n/// Otherwise the downstream crate 𝒜 doesn't know about 𝒞 and wouldn't be able\n/// to find what header your header is referring to, and would fail to build.\n///\n/// When using `exported_header_prefixes`, your crate must also set a `links`\n/// key for itself in Cargo.toml.\n///\n/// ### Example\n///\n/// Suppose you have a crate with 5 direct dependencies and the `include_prefix`\n/// for each one are:\n///\n/// - \"crate0\"\n/// - \"group/api/crate1\"\n/// - \"group/api/crate2\"\n/// - \"group/api/contrib/crate3\"\n/// - \"detail/crate4\"\n///\n/// Your header involves types from the first four so we re-export those as part\n/// of your public API, while crate4 is only used internally by your cc file not\n/// your header, so we do not export:\n///\n/// ```no_run\n/// // build.rs\n///\n/// use cxx_build::CFG;\n///\n/// fn main() {\n///     CFG.exported_header_prefixes = vec![\"crate0\", \"group/api\"];\n///\n///     cxx_build::bridge(\"src/bridge.rs\")\n///         .file(\"src/impl.cc\")\n///         .compile(\"demo\");\n/// }\n/// ```\n///\n/// <p style=\"margin:0\"><br><br></p>\n///\n/// <div style=\"float:right;margin:22px 50px 0;font-size:1.15em;opacity:.73\"><strong>Vec&lt;&amp;str&gt;</strong></div>\n///\n/// ## **`CFG.exported_header_links`**\n///\n/// Vector of strings. These each refer to the `links` attribute ([*the `links`\n/// manifest key*][links]) of one of your crate's direct dependencies.\n///\n/// This achieves an equivalent result to `CFG.exported_header_prefixes` by\n/// re-exporting a dependency as part of your crate's public API, except with\n/// finer grained control for cases when multiple crates might be sharing the\n/// same `include_prefix` and you'd like to export some but not others. Links\n/// attributes are guaranteed to be unique identifiers by Cargo.\n///\n/// When using `exported_header_links`, your crate must also set a `links` key\n/// for itself in Cargo.toml.\n///\n/// ### Example\n///\n/// ```no_run\n/// // build.rs\n///\n/// use cxx_build::CFG;\n///\n/// fn main() {\n///     CFG.exported_header_links.push(\"git2\");\n///\n///     cxx_build::bridge(\"src/bridge.rs\").compile(\"demo\");\n/// }\n/// ```\n///\n/// <p style=\"margin:0\"><br><br></p>\n///\n/// <div style=\"float:right;margin:22px 50px 0;font-size:1.15em;opacity:.73\"><strong>bool</strong></div>\n///\n/// ## **`CFG.doxygen`**\n///\n/// Boolean. Whether to propagate Rust documentation from inside the cxx::bridge\n/// module as Doxygen-style comments in the generated C++ header.\n///\n/// Documentation on the following are supported:\n///\n/// - shared structs, and fields of shared structs\n/// - shared enums, and their variants\n/// - extern \"Rust\" opaque types\n/// - extern \"Rust\" functions, including methods/member functions\n///\n/// ### Example\n///\n/// ```no_run\n/// // build.rs\n///\n/// use cxx_build::CFG;\n///\n/// fn main() {\n///     CFG.doxygen = true;\n///\n///     cxx_build::bridge(\"src/bridge.rs\").compile(\"demo\");\n/// }\n/// ```\n///\n/// ```rust\n/// // src/bridge.rs\n///\n/// #[cxx::bridge]\n/// mod ffi {\n///     /// documentation of MyStruct\n///     pub struct MyStruct {\n///         /// documentation of the struct field\n///         lol: String,\n///     }\n///\n///     extern \"Rust\" {\n///         /// documentation of MyType\n///         type MyType;\n///\n///         /// function documentation\n///         fn asdf() -> bool;\n///     }\n/// }\n/// #\n/// # pub struct MyType;\n/// # fn asdf() -> bool { true }\n/// # fn main() {}\n/// ```\n///\n/// With `CFG.doxygen` enabled, the generated C++ header through which\n/// downstream C++ code will be able to access these shared structs and extern\n/// \"Rust\" signatures will have the Rust documentation comments propagated as\n/// Doxygen-style comments:\n///\n/// ```cpp\n/// /// documentation of MyStruct\n/// struct MyStruct final {\n///   /// documentation of the struct field\n///   ::rust::String lol;\n///   …\n/// };\n/// ```\n///\n/// Otherwise by default (without `CFG.doxygen`) they'll just be `//` comments.\n#[cfg(doc)]\npub static mut CFG: Cfg = Cfg {\n    include_prefix: \"\",\n    exported_header_dirs: Vec::new(),\n    exported_header_prefixes: Vec::new(),\n    exported_header_links: Vec::new(),\n    doxygen: false,\n    marker: PhantomData,\n};\n\nimpl<'a> Debug for Cfg<'a> {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        let Self {\n            include_prefix,\n            exported_header_dirs,\n            exported_header_prefixes,\n            exported_header_links,\n            doxygen,\n            marker: _,\n        } = self;\n        formatter\n            .debug_struct(\"Cfg\")\n            .field(\"include_prefix\", include_prefix)\n            .field(\"exported_header_dirs\", exported_header_dirs)\n            .field(\"exported_header_prefixes\", exported_header_prefixes)\n            .field(\"exported_header_links\", exported_header_links)\n            .field(\"doxygen\", doxygen)\n            .finish()\n    }\n}\n\n#[cfg(not(doc))]\npub use self::r#impl::Cfg::CFG;\n\n#[cfg(not(doc))]\nmod r#impl {\n    use crate::intern::{intern, InternedString};\n    use crate::syntax::map::UnorderedMap as Map;\n    use crate::vec::{self, InternedVec as _};\n    use std::cell::RefCell;\n    use std::fmt::{self, Debug};\n    use std::marker::PhantomData;\n    use std::ops::{Deref, DerefMut};\n    use std::sync::{OnceLock, PoisonError, RwLock};\n\n    struct CurrentCfg {\n        include_prefix: InternedString,\n        exported_header_dirs: Vec<InternedString>,\n        exported_header_prefixes: Vec<InternedString>,\n        exported_header_links: Vec<InternedString>,\n        doxygen: bool,\n    }\n\n    impl CurrentCfg {\n        fn default() -> Self {\n            let include_prefix = crate::env_os(\"CARGO_PKG_NAME\")\n                .map(|pkg| intern(&pkg.to_string_lossy()))\n                .unwrap_or_default();\n            let exported_header_dirs = Vec::new();\n            let exported_header_prefixes = Vec::new();\n            let exported_header_links = Vec::new();\n            let doxygen = false;\n            CurrentCfg {\n                include_prefix,\n                exported_header_dirs,\n                exported_header_prefixes,\n                exported_header_links,\n                doxygen,\n            }\n        }\n    }\n\n    fn current() -> &'static RwLock<CurrentCfg> {\n        static CURRENT: OnceLock<RwLock<CurrentCfg>> = OnceLock::new();\n        CURRENT.get_or_init(|| RwLock::new(CurrentCfg::default()))\n    }\n\n    thread_local! {\n        // FIXME: If https://github.com/rust-lang/rust/issues/77425 is resolved,\n        // we can delete this thread local side table and instead make each CFG\n        // instance directly own the associated super::Cfg.\n        //\n        //     #[allow(const_item_mutation)]\n        //     pub const CFG: Cfg = Cfg {\n        //         cfg: AtomicPtr::new(ptr::null_mut()),\n        //     };\n        //     pub struct Cfg {\n        //         cfg: AtomicPtr<super::Cfg>,\n        //     }\n        //\n        static CONST_DEREFS: RefCell<Map<Handle, Box<super::Cfg<'static>>>> = RefCell::default();\n    }\n\n    #[derive(Eq, PartialEq, Hash)]\n    struct Handle(*const Cfg<'static>);\n\n    impl<'a> Cfg<'a> {\n        fn current() -> super::Cfg<'a> {\n            let current = current().read().unwrap_or_else(PoisonError::into_inner);\n            let include_prefix = current.include_prefix.str();\n            let exported_header_dirs = current.exported_header_dirs.vec();\n            let exported_header_prefixes = current.exported_header_prefixes.vec();\n            let exported_header_links = current.exported_header_links.vec();\n            let doxygen = current.doxygen;\n            super::Cfg {\n                include_prefix,\n                exported_header_dirs,\n                exported_header_prefixes,\n                exported_header_links,\n                doxygen,\n                marker: PhantomData,\n            }\n        }\n\n        const fn handle(self: &Cfg<'a>) -> Handle {\n            Handle(<*const Cfg>::cast(self))\n        }\n    }\n\n    // Since super::Cfg is !Send and !Sync, all Cfg are thread local and will\n    // drop on the same thread where they were created.\n    pub enum Cfg<'a> {\n        Mut(super::Cfg<'a>),\n        CFG,\n    }\n\n    impl<'a> Debug for Cfg<'a> {\n        fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n            if let Cfg::Mut(cfg) = self {\n                Debug::fmt(cfg, formatter)\n            } else {\n                Debug::fmt(&Cfg::current(), formatter)\n            }\n        }\n    }\n\n    impl<'a> Deref for Cfg<'a> {\n        type Target = super::Cfg<'a>;\n\n        fn deref(&self) -> &Self::Target {\n            if let Cfg::Mut(cfg) = self {\n                cfg\n            } else {\n                let cfg = CONST_DEREFS.with(|derefs| -> *mut super::Cfg {\n                    &raw mut **derefs\n                        .borrow_mut()\n                        .entry(self.handle())\n                        .or_insert_with(|| Box::new(Cfg::current()))\n                });\n                unsafe { &mut *cfg }\n            }\n        }\n    }\n\n    impl<'a> DerefMut for Cfg<'a> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            if let Cfg::CFG = self {\n                CONST_DEREFS.with(|derefs| derefs.borrow_mut().remove(&self.handle()));\n                *self = Cfg::Mut(Cfg::current());\n            }\n            match self {\n                Cfg::Mut(cfg) => cfg,\n                Cfg::CFG => unreachable!(),\n            }\n        }\n    }\n\n    impl<'a> Drop for Cfg<'a> {\n        fn drop(&mut self) {\n            if let Cfg::Mut(cfg) = self {\n                let super::Cfg {\n                    include_prefix,\n                    exported_header_dirs,\n                    exported_header_prefixes,\n                    exported_header_links,\n                    doxygen,\n                    marker: _,\n                } = cfg;\n                let mut current = current().write().unwrap_or_else(PoisonError::into_inner);\n                current.include_prefix = intern(include_prefix);\n                current.exported_header_dirs = vec::intern(exported_header_dirs);\n                current.exported_header_prefixes = vec::intern(exported_header_prefixes);\n                current.exported_header_links = vec::intern(exported_header_links);\n                current.doxygen = *doxygen;\n            } else {\n                CONST_DEREFS.with(|derefs| derefs.borrow_mut().remove(&self.handle()));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "gen/build/src/deps.rs",
    "content": "use std::collections::BTreeMap;\nuse std::env;\nuse std::ffi::OsString;\nuse std::path::PathBuf;\n\n#[derive(Default)]\npub(crate) struct Crate {\n    pub include_prefix: Option<PathBuf>,\n    pub links: Option<OsString>,\n    pub header_dirs: Vec<HeaderDir>,\n}\n\npub(crate) struct HeaderDir {\n    pub exported: bool,\n    pub path: PathBuf,\n}\n\nimpl Crate {\n    pub(crate) fn print_to_cargo(&self) {\n        if let Some(include_prefix) = &self.include_prefix {\n            println!(\n                \"cargo:CXXBRIDGE_PREFIX={}\",\n                include_prefix.to_string_lossy(),\n            );\n        }\n        if let Some(links) = &self.links {\n            println!(\"cargo:CXXBRIDGE_LINKS={}\", links.to_string_lossy());\n        }\n        for (i, header_dir) in self.header_dirs.iter().enumerate() {\n            if header_dir.exported {\n                println!(\n                    \"cargo:CXXBRIDGE_DIR{}={}\",\n                    i,\n                    header_dir.path.to_string_lossy(),\n                );\n            }\n        }\n    }\n}\n\npub(crate) fn direct_dependencies() -> Vec<Crate> {\n    let mut crates: BTreeMap<String, Crate> = BTreeMap::new();\n    let mut exported_header_dirs: BTreeMap<String, Vec<(usize, PathBuf)>> = BTreeMap::new();\n\n    // Only variables set from a build script of direct dependencies are\n    // observable. That's exactly what we want! Your crate needs to declare a\n    // direct dependency on the other crate in order to be able to #include its\n    // headers.\n    //\n    // Also, they're only observable if the dependency's manifest contains a\n    // `links` key. This is important because Cargo imposes no ordering on the\n    // execution of build scripts without a `links` key. When exposing a\n    // generated header for the current crate to #include, we need to be sure\n    // the dependency's build script has already executed and emitted that\n    // generated header.\n    //\n    // References:\n    //   - https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key\n    //   - https://doc.rust-lang.org/cargo/reference/build-script-examples.html#using-another-sys-crate\n    for (k, v) in env::vars_os() {\n        let mut k = k.to_string_lossy().into_owned();\n        if !k.starts_with(\"DEP_\") {\n            continue;\n        }\n\n        if k.ends_with(\"_CXXBRIDGE_PREFIX\") {\n            k.truncate(k.len() - \"_CXXBRIDGE_PREFIX\".len());\n            crates.entry(k).or_default().include_prefix = Some(PathBuf::from(v));\n            continue;\n        }\n\n        if k.ends_with(\"_CXXBRIDGE_LINKS\") {\n            k.truncate(k.len() - \"_CXXBRIDGE_LINKS\".len());\n            crates.entry(k).or_default().links = Some(v);\n            continue;\n        }\n\n        let without_counter = k.trim_end_matches(|ch: char| ch.is_ascii_digit());\n        let counter_len = k.len() - without_counter.len();\n        if counter_len == 0 || !without_counter.ends_with(\"_CXXBRIDGE_DIR\") {\n            continue;\n        }\n\n        let sort_key = k[k.len() - counter_len..]\n            .parse::<usize>()\n            .unwrap_or(usize::MAX);\n        k.truncate(k.len() - counter_len - \"_CXXBRIDGE_DIR\".len());\n        exported_header_dirs\n            .entry(k)\n            .or_default()\n            .push((sort_key, PathBuf::from(v)));\n    }\n\n    for (k, mut dirs) in exported_header_dirs {\n        dirs.sort_by_key(|(sort_key, _dir)| *sort_key);\n        crates\n            .entry(k)\n            .or_default()\n            .header_dirs\n            .extend(dirs.into_iter().map(|(_sort_key, dir)| HeaderDir {\n                exported: true,\n                path: dir,\n            }));\n    }\n\n    crates.into_iter().map(|entry| entry.1).collect()\n}\n"
  },
  {
    "path": "gen/build/src/error.rs",
    "content": "use crate::cfg::CFG;\nuse crate::gen::fs;\nuse std::error::Error as StdError;\nuse std::ffi::OsString;\nuse std::fmt::{self, Display};\nuse std::path::Path;\n\npub(super) type Result<T, E = Error> = std::result::Result<T, E>;\n\n#[derive(Debug)]\npub(super) enum Error {\n    NoEnv(OsString),\n    Fs(fs::Error),\n    ExportedDirNotAbsolute(&'static Path),\n    ExportedEmptyPrefix,\n    ExportedDirsWithoutLinks,\n    ExportedPrefixesWithoutLinks,\n    ExportedLinksWithoutLinks,\n    UnusedExportedPrefix(&'static str),\n    UnusedExportedLinks(&'static str),\n}\n\nmacro_rules! expr {\n    ($expr:expr) => {{\n        let _ = $expr; // ensure it doesn't fall out of sync with CFG definition\n        stringify!($expr)\n    }};\n}\n\nconst LINKS_DOCUMENTATION: &str =\n    \"https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key\";\n\nimpl Display for Error {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match self {\n            Error::NoEnv(var) => {\n                write!(f, \"missing {} environment variable\", var.to_string_lossy())\n            }\n            Error::Fs(err) => err.fmt(f),\n            Error::ExportedDirNotAbsolute(path) => write!(\n                f,\n                \"element of {} must be absolute path, but was: `{}`\",\n                expr!(CFG.exported_header_dirs),\n                path.display(),\n            ),\n            Error::ExportedEmptyPrefix => write!(\n                f,\n                \"element of {} must not be empty string\",\n                expr!(CFG.exported_header_prefixes),\n            ),\n            Error::ExportedDirsWithoutLinks => write!(\n                f,\n                \"if {} is nonempty then `links` needs to be set in Cargo.toml; see {}\",\n                expr!(CFG.exported_header_dirs),\n                LINKS_DOCUMENTATION,\n            ),\n            Error::ExportedPrefixesWithoutLinks => write!(\n                f,\n                \"if {} is nonempty then `links` needs to be set in Cargo.toml; see {}\",\n                expr!(CFG.exported_header_prefixes),\n                LINKS_DOCUMENTATION,\n            ),\n            Error::ExportedLinksWithoutLinks => write!(\n                f,\n                \"if {} is nonempty then `links` needs to be set in Cargo.toml; see {}\",\n                expr!(CFG.exported_header_links),\n                LINKS_DOCUMENTATION,\n            ),\n            Error::UnusedExportedPrefix(unused) => write!(\n                f,\n                \"unused element in {}: {:?} does not match the include prefix of any direct dependency\",\n                expr!(CFG.exported_header_prefixes),\n                unused,\n            ),\n            Error::UnusedExportedLinks(unused) => write!(\n                f,\n                \"unused element in {}: {:?} does not match the `links` attribute any direct dependency\",\n                expr!(CFG.exported_header_links),\n                unused,\n            ),\n        }\n    }\n}\n\nimpl StdError for Error {\n    fn source(&self) -> Option<&(dyn StdError + 'static)> {\n        match self {\n            Error::Fs(err) => err.source(),\n            _ => None,\n        }\n    }\n}\n\nimpl From<fs::Error> for Error {\n    fn from(err: fs::Error) -> Self {\n        Error::Fs(err)\n    }\n}\n"
  },
  {
    "path": "gen/build/src/intern.rs",
    "content": "use crate::syntax::set::UnorderedSet as Set;\nuse std::sync::{Mutex, OnceLock, PoisonError};\n\n#[derive(Copy, Clone, Default)]\npub(crate) struct InternedString(&'static str);\n\nimpl InternedString {\n    pub(crate) fn str(self) -> &'static str {\n        self.0\n    }\n}\n\npub(crate) fn intern(s: &str) -> InternedString {\n    static INTERN: OnceLock<Mutex<Set<&'static str>>> = OnceLock::new();\n\n    let mut set = INTERN\n        .get_or_init(|| Mutex::new(Set::new()))\n        .lock()\n        .unwrap_or_else(PoisonError::into_inner);\n\n    InternedString(match set.get(s) {\n        Some(interned) => *interned,\n        None => {\n            let interned = Box::leak(Box::from(s));\n            set.insert(interned);\n            interned\n        }\n    })\n}\n"
  },
  {
    "path": "gen/build/src/lib.rs",
    "content": "//! The CXX code generator for constructing and compiling C++ code.\n//!\n//! This is intended to be used from Cargo build scripts to execute CXX's\n//! C++ code generator, set up any additional compiler flags depending on\n//! the use case, and make the C++ compiler invocation.\n//!\n//! <br>\n//!\n//! # Example\n//!\n//! Example of a canonical Cargo build script that builds a CXX bridge:\n//!\n//! ```no_run\n//! // build.rs\n//!\n//! fn main() {\n//!     cxx_build::bridge(\"src/main.rs\")\n//!         .file(\"src/demo.cc\")\n//!         .std(\"c++11\")\n//!         .compile(\"cxxbridge-demo\");\n//!\n//!     println!(\"cargo:rerun-if-changed=src/demo.cc\");\n//!     println!(\"cargo:rerun-if-changed=include/demo.h\");\n//! }\n//! ```\n//!\n//! A runnable working setup with this build script is shown in the *demo*\n//! directory of [https://github.com/dtolnay/cxx].\n//!\n//! [https://github.com/dtolnay/cxx]: https://github.com/dtolnay/cxx\n//!\n//! <br>\n//!\n//! # Alternatives\n//!\n//! For use in non-Cargo builds like Bazel or Buck, CXX provides an\n//! alternate way of invoking the C++ code generator as a standalone command\n//! line tool. The tool is packaged as the `cxxbridge-cmd` crate.\n//!\n//! ```bash\n//! $ cargo install cxxbridge-cmd  # or build it from the repo\n//!\n//! $ cxxbridge src/main.rs --header > path/to/mybridge.h\n//! $ cxxbridge src/main.rs > path/to/mybridge.cc\n//! ```\n\n#![doc(html_root_url = \"https://docs.rs/cxx-build/1.0.194\")]\n#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]\n#![allow(\n    clippy::cast_sign_loss,\n    clippy::default_trait_access,\n    clippy::doc_markdown,\n    clippy::elidable_lifetime_names,\n    clippy::enum_glob_use,\n    clippy::expl_impl_clone_on_copy, // https://github.com/rust-lang/rust-clippy/issues/15842\n    clippy::explicit_auto_deref,\n    clippy::inherent_to_string,\n    clippy::items_after_statements,\n    clippy::match_bool,\n    clippy::match_like_matches_macro,\n    clippy::match_same_arms,\n    clippy::needless_continue,\n    clippy::needless_doctest_main,\n    clippy::needless_lifetimes,\n    clippy::needless_pass_by_value,\n    clippy::nonminimal_bool,\n    clippy::precedence,\n    clippy::redundant_else,\n    clippy::ref_option,\n    clippy::similar_names,\n    clippy::single_match_else,\n    clippy::struct_excessive_bools,\n    clippy::struct_field_names,\n    clippy::too_many_arguments,\n    clippy::too_many_lines,\n    clippy::toplevel_ref_arg,\n    clippy::uninlined_format_args,\n    clippy::upper_case_acronyms\n)]\n#![allow(unknown_lints, mismatched_lifetime_syntaxes)]\n\nmod cargo;\nmod cfg;\nmod deps;\nmod error;\nmod gen;\nmod intern;\nmod out;\nmod paths;\nmod syntax;\nmod target;\nmod vec;\n\nuse crate::cargo::CargoEnvCfgEvaluator;\nuse crate::deps::{Crate, HeaderDir};\nuse crate::error::{Error, Result};\nuse crate::gen::error::report;\nuse crate::gen::Opt;\nuse crate::paths::PathExt;\nuse crate::syntax::map::{Entry, UnorderedMap};\nuse crate::target::TargetDir;\nuse cc::Build;\nuse std::collections::BTreeSet;\nuse std::env;\nuse std::ffi::{OsStr, OsString};\nuse std::io::{self, Write};\nuse std::iter;\nuse std::path::{Path, PathBuf};\nuse std::process;\n\npub use crate::cfg::{Cfg, CFG};\n\n/// This returns a [`cc::Build`] on which you should continue to set up any\n/// additional source files or compiler flags, and lastly call its [`compile`]\n/// method to execute the C++ build.\n///\n/// [`compile`]: cc::Build::compile\n#[must_use]\npub fn bridge(rust_source_file: impl AsRef<Path>) -> Build {\n    bridges(iter::once(rust_source_file))\n}\n\n/// `cxx_build::bridge` but for when more than one file contains a\n/// #\\[cxx::bridge\\] module.\n///\n/// ```no_run\n/// let source_files = vec![\"src/main.rs\", \"src/path/to/other.rs\"];\n/// cxx_build::bridges(source_files)\n///     .file(\"src/demo.cc\")\n///     .std(\"c++11\")\n///     .compile(\"cxxbridge-demo\");\n/// ```\n#[must_use]\npub fn bridges(rust_source_files: impl IntoIterator<Item = impl AsRef<Path>>) -> Build {\n    let ref mut rust_source_files = rust_source_files.into_iter();\n    build(rust_source_files).unwrap_or_else(|err| {\n        let _ = writeln!(io::stderr(), \"\\n\\ncxxbridge error: {}\\n\\n\", report(err));\n        process::exit(1);\n    })\n}\n\nstruct Project {\n    include_prefix: PathBuf,\n    manifest_dir: PathBuf,\n    // The `links = \"...\"` value from Cargo.toml.\n    links_attribute: Option<OsString>,\n    // Output directory as received from Cargo.\n    out_dir: PathBuf,\n    // Directory into which to symlink all generated code.\n    //\n    // This is *not* used for an #include path, only as a debugging convenience.\n    // Normally available at target/cxxbridge/ if we are able to know where the\n    // target dir is, otherwise under a common scratch dir.\n    //\n    // The reason this isn't the #include dir is that we do not want builds to\n    // have access to headers from arbitrary other parts of the dependency\n    // graph. Using a global directory for all builds would be both a race\n    // condition depending on what order Cargo randomly executes the build\n    // scripts, as well as semantically undesirable for builds not to have to\n    // declare their real dependencies.\n    shared_dir: PathBuf,\n}\n\nimpl Project {\n    fn init() -> Result<Self> {\n        let include_prefix = Path::new(CFG.include_prefix);\n        assert!(include_prefix.is_relative());\n        let include_prefix = include_prefix.components().collect();\n\n        let links_attribute = env::var_os(\"CARGO_MANIFEST_LINKS\");\n\n        let manifest_dir = paths::manifest_dir()?;\n        let out_dir = paths::out_dir()?;\n\n        let shared_dir = match target::find_target_dir(&out_dir) {\n            TargetDir::Path(target_dir) => target_dir.join(\"cxxbridge\"),\n            TargetDir::Unknown => scratch::path(\"cxxbridge\"),\n        };\n\n        Ok(Project {\n            include_prefix,\n            manifest_dir,\n            links_attribute,\n            out_dir,\n            shared_dir,\n        })\n    }\n}\n\n// We lay out the OUT_DIR as follows. Everything is namespaced under a cxxbridge\n// subdirectory to avoid stomping on other things that the caller's build script\n// might be doing inside OUT_DIR.\n//\n//     $OUT_DIR/\n//        cxxbridge/\n//           crate/\n//              $CARGO_PKG_NAME -> $CARGO_MANIFEST_DIR\n//           include/\n//              rust/\n//                 cxx.h\n//              $CARGO_PKG_NAME/\n//                 .../\n//                    lib.rs.h\n//           sources/\n//              $CARGO_PKG_NAME/\n//                 .../\n//                    lib.rs.cc\n//\n// The crate/ and include/ directories are placed on the #include path for the\n// current build as well as for downstream builds that have a direct dependency\n// on the current crate.\nfn build(rust_source_files: &mut dyn Iterator<Item = impl AsRef<Path>>) -> Result<Build> {\n    let ref prj = Project::init()?;\n    validate_cfg(prj)?;\n    let this_crate = make_this_crate(prj)?;\n\n    let mut build = Build::new();\n    build.cpp(true);\n    build.cpp_link_stdlib(None); // linked via link-cplusplus crate\n\n    for path in rust_source_files {\n        generate_bridge(prj, &mut build, path.as_ref())?;\n    }\n\n    this_crate.print_to_cargo();\n    eprintln!(\"\\nCXX include path:\");\n    for header_dir in this_crate.header_dirs {\n        build.include(&header_dir.path);\n        if header_dir.exported {\n            eprintln!(\"  {}\", header_dir.path.display());\n        } else {\n            eprintln!(\"  {} (private)\", header_dir.path.display());\n        }\n    }\n\n    Ok(build)\n}\n\nfn validate_cfg(prj: &Project) -> Result<()> {\n    for exported_dir in &CFG.exported_header_dirs {\n        if !exported_dir.is_absolute() {\n            return Err(Error::ExportedDirNotAbsolute(exported_dir));\n        }\n    }\n\n    for prefix in &CFG.exported_header_prefixes {\n        if prefix.is_empty() {\n            return Err(Error::ExportedEmptyPrefix);\n        }\n    }\n\n    if prj.links_attribute.is_none() {\n        if !CFG.exported_header_dirs.is_empty() {\n            return Err(Error::ExportedDirsWithoutLinks);\n        }\n        if !CFG.exported_header_prefixes.is_empty() {\n            return Err(Error::ExportedPrefixesWithoutLinks);\n        }\n        if !CFG.exported_header_links.is_empty() {\n            return Err(Error::ExportedLinksWithoutLinks);\n        }\n    }\n\n    Ok(())\n}\n\nfn make_this_crate(prj: &Project) -> Result<Crate> {\n    let crate_dir = make_crate_dir(prj);\n    let include_dir = make_include_dir(prj)?;\n\n    let mut this_crate = Crate {\n        include_prefix: Some(prj.include_prefix.clone()),\n        links: prj.links_attribute.clone(),\n        header_dirs: Vec::new(),\n    };\n\n    // The generated code directory (include_dir) is placed in front of\n    // crate_dir on the include line so that `#include \"path/to/file.rs\"` from\n    // C++ \"magically\" works and refers to the API generated from that Rust\n    // source file.\n    this_crate.header_dirs.push(HeaderDir {\n        exported: true,\n        path: include_dir,\n    });\n\n    this_crate.header_dirs.push(HeaderDir {\n        exported: true,\n        path: crate_dir,\n    });\n\n    for exported_dir in &CFG.exported_header_dirs {\n        this_crate.header_dirs.push(HeaderDir {\n            exported: true,\n            path: PathBuf::from(exported_dir),\n        });\n    }\n\n    let mut header_dirs_index = UnorderedMap::new();\n    let mut used_header_links = BTreeSet::new();\n    let mut used_header_prefixes = BTreeSet::new();\n    for krate in deps::direct_dependencies() {\n        let mut is_link_exported = || match &krate.links {\n            None => false,\n            Some(links_attribute) => CFG.exported_header_links.iter().any(|&exported| {\n                let matches = links_attribute == exported;\n                if matches {\n                    used_header_links.insert(exported);\n                }\n                matches\n            }),\n        };\n\n        let mut is_prefix_exported = || match &krate.include_prefix {\n            None => false,\n            Some(include_prefix) => CFG.exported_header_prefixes.iter().any(|&exported| {\n                let matches = include_prefix.starts_with(exported);\n                if matches {\n                    used_header_prefixes.insert(exported);\n                }\n                matches\n            }),\n        };\n\n        let exported = is_link_exported() || is_prefix_exported();\n\n        for dir in krate.header_dirs {\n            // Deduplicate dirs reachable via multiple transitive dependencies.\n            match header_dirs_index.entry(dir.path.clone()) {\n                Entry::Vacant(entry) => {\n                    entry.insert(this_crate.header_dirs.len());\n                    this_crate.header_dirs.push(HeaderDir {\n                        exported,\n                        path: dir.path,\n                    });\n                }\n                Entry::Occupied(entry) => {\n                    let index = *entry.get();\n                    this_crate.header_dirs[index].exported |= exported;\n                }\n            }\n        }\n    }\n\n    if let Some(unused) = CFG\n        .exported_header_links\n        .iter()\n        .find(|&exported| !used_header_links.contains(exported))\n    {\n        return Err(Error::UnusedExportedLinks(unused));\n    }\n\n    if let Some(unused) = CFG\n        .exported_header_prefixes\n        .iter()\n        .find(|&exported| !used_header_prefixes.contains(exported))\n    {\n        return Err(Error::UnusedExportedPrefix(unused));\n    }\n\n    Ok(this_crate)\n}\n\nfn make_crate_dir(prj: &Project) -> PathBuf {\n    if prj.include_prefix.as_os_str().is_empty() {\n        return prj.manifest_dir.clone();\n    }\n    let crate_dir = prj.out_dir.join(\"cxxbridge\").join(\"crate\");\n    let ref link = crate_dir.join(&prj.include_prefix);\n    let ref manifest_dir = prj.manifest_dir;\n    if out::relative_symlink_dir(manifest_dir, link).is_err() && cfg!(not(unix)) {\n        let cachedir_tag = \"\\\n        Signature: 8a477f597d28d172789f06886806bc55\\n\\\n        # This file is a cache directory tag created by cxx.\\n\\\n        # For information about cache directory tags see https://bford.info/cachedir/\\n\";\n        let _ = out::write(crate_dir.join(\"CACHEDIR.TAG\"), cachedir_tag.as_bytes());\n        let max_depth = 6;\n        best_effort_copy_headers(manifest_dir, link, max_depth);\n    }\n    crate_dir\n}\n\nfn make_include_dir(prj: &Project) -> Result<PathBuf> {\n    let include_dir = prj.out_dir.join(\"cxxbridge\").join(\"include\");\n    let cxx_h = include_dir.join(\"rust\").join(\"cxx.h\");\n    let ref shared_cxx_h = prj.shared_dir.join(\"rust\").join(\"cxx.h\");\n    if let Some(ref original) = env::var_os(\"DEP_CXXBRIDGE1_HEADER\") {\n        out::absolute_symlink_file(original, cxx_h)?;\n        out::absolute_symlink_file(original, shared_cxx_h)?;\n    } else {\n        out::write(shared_cxx_h, gen::include::HEADER.as_bytes())?;\n        out::relative_symlink_file(shared_cxx_h, cxx_h)?;\n    }\n    Ok(include_dir)\n}\n\nfn generate_bridge(prj: &Project, build: &mut Build, rust_source_file: &Path) -> Result<()> {\n    let opt = Opt {\n        allow_dot_includes: false,\n        cfg_evaluator: Box::new(CargoEnvCfgEvaluator),\n        doxygen: CFG.doxygen,\n        ..Opt::default()\n    };\n    if !rust_source_file.starts_with(&prj.out_dir) {\n        println!(\"cargo:rerun-if-changed={}\", rust_source_file.display());\n    }\n    let generated = gen::generate_from_path(rust_source_file, &opt);\n    let ref rel_path = paths::local_relative_path(rust_source_file);\n\n    let cxxbridge = prj.out_dir.join(\"cxxbridge\");\n    let include_dir = cxxbridge.join(\"include\").join(&prj.include_prefix);\n    let sources_dir = cxxbridge.join(\"sources\").join(&prj.include_prefix);\n\n    let ref rel_path_h = rel_path.with_appended_extension(\".h\");\n    let ref header_path = include_dir.join(rel_path_h);\n    out::write(header_path, &generated.header)?;\n\n    let ref link_path = include_dir.join(rel_path);\n    let _ = out::relative_symlink_file(header_path, link_path);\n\n    let ref rel_path_cc = rel_path.with_appended_extension(\".cc\");\n    let ref implementation_path = sources_dir.join(rel_path_cc);\n    out::write(implementation_path, &generated.implementation)?;\n    build.file(implementation_path);\n\n    let shared_h = prj.shared_dir.join(&prj.include_prefix).join(rel_path_h);\n    let shared_cc = prj.shared_dir.join(&prj.include_prefix).join(rel_path_cc);\n    let _ = out::relative_symlink_file(header_path, shared_h);\n    let _ = out::relative_symlink_file(implementation_path, shared_cc);\n    Ok(())\n}\n\nfn best_effort_copy_headers(src: &Path, dst: &Path, max_depth: usize) {\n    // Not using crate::gen::fs because we aren't reporting the errors.\n    use std::fs;\n\n    let mut dst_created = false;\n    let Ok(mut entries) = fs::read_dir(src) else {\n        return;\n    };\n\n    while let Some(Ok(entry)) = entries.next() {\n        let file_name = entry.file_name();\n        if file_name.to_string_lossy().starts_with('.') {\n            continue;\n        }\n        match entry.file_type() {\n            Ok(file_type) if file_type.is_dir() && max_depth > 0 => {\n                let src = entry.path();\n                if src.join(\"Cargo.toml\").exists() || src.join(\"CACHEDIR.TAG\").exists() {\n                    continue;\n                }\n                let dst = dst.join(file_name);\n                best_effort_copy_headers(&src, &dst, max_depth - 1);\n            }\n            Ok(file_type) if file_type.is_file() => {\n                let src = entry.path();\n                match src.extension().and_then(OsStr::to_str) {\n                    Some(\"h\" | \"hh\" | \"hpp\") => {}\n                    _ => continue,\n                }\n                if !dst_created && fs::create_dir_all(dst).is_err() {\n                    return;\n                }\n                dst_created = true;\n                let dst = dst.join(file_name);\n                let _ = fs::remove_file(&dst);\n                let _ = fs::copy(src, dst);\n            }\n            _ => {}\n        }\n    }\n}\n\nfn env_os(key: impl AsRef<OsStr>) -> Result<OsString> {\n    let key = key.as_ref();\n    env::var_os(key).ok_or_else(|| Error::NoEnv(key.to_owned()))\n}\n"
  },
  {
    "path": "gen/build/src/out.rs",
    "content": "use crate::error::{Error, Result};\nuse crate::gen::fs;\nuse crate::paths;\nuse std::path::{Component, Path, PathBuf};\nuse std::{env, io};\n\npub(crate) fn write(path: impl AsRef<Path>, content: &[u8]) -> Result<()> {\n    let path = path.as_ref();\n\n    let mut create_dir_error = None;\n    if fs::exists(path) {\n        if let Ok(existing) = fs::read(path) {\n            if existing == content {\n                // Avoid bumping modified time with unchanged contents.\n                return Ok(());\n            }\n        }\n        best_effort_remove(path);\n    } else {\n        let parent = path.parent().unwrap();\n        create_dir_error = fs::create_dir_all(parent).err();\n    }\n\n    match fs::write(path, content) {\n        // As long as write succeeded, ignore any create_dir_all error.\n        Ok(()) => Ok(()),\n        // If create_dir_all and write both failed, prefer the first error.\n        Err(err) => Err(Error::Fs(create_dir_error.unwrap_or(err))),\n    }\n}\n\npub(crate) fn relative_symlink_file(\n    original: impl AsRef<Path>,\n    link: impl AsRef<Path>,\n) -> Result<()> {\n    let original = original.as_ref();\n    let link = link.as_ref();\n\n    let parent_directory_error = prepare_parent_directory_for_symlink(link).err();\n    let relativized = best_effort_relativize_symlink(original, link);\n\n    symlink_file(&relativized, original, link, parent_directory_error)\n}\n\npub(crate) fn absolute_symlink_file(\n    original: impl AsRef<Path>,\n    link: impl AsRef<Path>,\n) -> Result<()> {\n    let original = original.as_ref();\n    let link = link.as_ref();\n\n    let parent_directory_error = prepare_parent_directory_for_symlink(link).err();\n\n    symlink_file(original, original, link, parent_directory_error)\n}\n\npub(crate) fn relative_symlink_dir(\n    original: impl AsRef<Path>,\n    link: impl AsRef<Path>,\n) -> Result<()> {\n    let original = original.as_ref();\n    let link = link.as_ref();\n\n    let parent_directory_error = prepare_parent_directory_for_symlink(link).err();\n    let relativized = best_effort_relativize_symlink(original, link);\n\n    symlink_dir(&relativized, link, parent_directory_error)\n}\n\nfn prepare_parent_directory_for_symlink(link: &Path) -> fs::Result<()> {\n    if fs::exists(link) {\n        best_effort_remove(link);\n        Ok(())\n    } else {\n        let parent = link.parent().unwrap();\n        fs::create_dir_all(parent)\n    }\n}\n\nfn symlink_file(\n    path_for_symlink: &Path,\n    path_for_copy: &Path,\n    link: &Path,\n    parent_directory_error: Option<fs::Error>,\n) -> Result<()> {\n    match paths::symlink_or_copy(path_for_symlink, path_for_copy, link) {\n        // As long as symlink_or_copy succeeded, ignore any create_dir_all error.\n        Ok(()) => Ok(()),\n        Err(err) => {\n            if err.kind() == io::ErrorKind::AlreadyExists {\n                // This is fine, a different simultaneous build script already\n                // created the same link or copy. The cxx_build target directory\n                // is laid out such that the same path never refers to two\n                // different targets during the same multi-crate build, so if\n                // some other build script already created the same path then we\n                // know it refers to the identical target that the current build\n                // script was trying to create.\n                Ok(())\n            } else {\n                // If create_dir_all and symlink_or_copy both failed, prefer the\n                // first error.\n                Err(Error::Fs(parent_directory_error.unwrap_or(err)))\n            }\n        }\n    }\n}\n\nfn symlink_dir(\n    path_for_symlink: &Path,\n    link: &Path,\n    parent_directory_error: Option<fs::Error>,\n) -> Result<()> {\n    match fs::symlink_dir(path_for_symlink, link) {\n        // As long as symlink_dir succeeded, ignore any create_dir_all error.\n        Ok(()) => Ok(()),\n        // If create_dir_all and symlink_dir both failed, prefer the first error.\n        Err(err) => Err(Error::Fs(parent_directory_error.unwrap_or(err))),\n    }\n}\n\nfn best_effort_remove(path: &Path) {\n    use std::fs;\n\n    if cfg!(windows) {\n        // On Windows, the correct choice of remove_file vs remove_dir needs to\n        // be used according to what the symlink *points to*. Trying to use\n        // remove_file to remove a symlink which points to a directory fails\n        // with \"Access is denied\".\n        if let Ok(metadata) = fs::metadata(path) {\n            if metadata.is_dir() {\n                let _ = fs::remove_dir_all(path);\n            } else {\n                let _ = fs::remove_file(path);\n            }\n        } else if fs::symlink_metadata(path).is_ok() {\n            // The symlink might exist but be dangling, in which case there is\n            // no standard way to determine what \"kind\" of symlink it is. Try\n            // deleting both ways.\n            if fs::remove_dir_all(path).is_err() {\n                let _ = fs::remove_file(path);\n            }\n        }\n    } else {\n        // On non-Windows, we check metadata not following symlinks. All\n        // symlinks are removed using remove_file.\n        if let Ok(metadata) = fs::symlink_metadata(path) {\n            if metadata.is_dir() {\n                let _ = fs::remove_dir_all(path);\n            } else {\n                let _ = fs::remove_file(path);\n            }\n        }\n    }\n}\n\nfn best_effort_relativize_symlink(original: impl AsRef<Path>, link: impl AsRef<Path>) -> PathBuf {\n    let original = original.as_ref();\n    let link = link.as_ref();\n\n    let Some(relative_path) = abstractly_relativize_symlink(original, link) else {\n        return original.to_path_buf();\n    };\n\n    // Sometimes \"a/b/../c\" refers to a different canonical location than \"a/c\".\n    // This can happen if 'b' is a symlink. The '..' canonicalizes to the parent\n    // directory of the symlink's target, not back to 'a'. In cxx-build's case\n    // someone could be using `--target-dir` with a location containing such\n    // symlinks.\n    if let Ok(original_canonical) = original.canonicalize() {\n        if let Ok(relative_canonical) = link.parent().unwrap().join(&relative_path).canonicalize() {\n            if original_canonical == relative_canonical {\n                return relative_path;\n            }\n        }\n    }\n\n    original.to_path_buf()\n}\n\nfn abstractly_relativize_symlink(\n    original: impl AsRef<Path>,\n    link: impl AsRef<Path>,\n) -> Option<PathBuf> {\n    let original = original.as_ref();\n    let link = link.as_ref();\n\n    // Relativization only makes sense if there is a semantically meaningful\n    // base directory shared between the two paths.\n    //\n    // For example /Volumes/code/library/src/lib.rs\n    //         and /Volumes/code/library/target/path/to/something.a\n    // have a meaningful shared base of /Volumes/code/library. The target and\n    // source directory only likely ever get relocated as one unit.\n    //\n    // On the other hand, /Volumes/code/library/src/lib.rs\n    //                and /Volumes/shared_target\n    // do not, since upon moving library to a different location it should\n    // continue referring to the original location of that shared Cargo target\n    // directory.\n    let likely_no_semantic_prefix = env::var_os(\"CARGO_TARGET_DIR\").is_some();\n\n    if likely_no_semantic_prefix\n        || original.is_relative()\n        || link.is_relative()\n        || path_contains_intermediate_components(original)\n        || path_contains_intermediate_components(link)\n    {\n        return None;\n    }\n\n    let (common_prefix, rest_of_original, rest_of_link) = split_after_common_prefix(original, link);\n\n    if common_prefix == Path::new(\"\") {\n        return None;\n    }\n\n    let mut rest_of_link = rest_of_link.components();\n    rest_of_link\n        .next_back()\n        .expect(\"original can't be a subdirectory of link\");\n\n    let mut path_to_common_prefix = PathBuf::new();\n    while rest_of_link.next_back().is_some() {\n        path_to_common_prefix.push(Component::ParentDir);\n    }\n\n    Some(path_to_common_prefix.join(rest_of_original))\n}\n\nfn path_contains_intermediate_components(path: impl AsRef<Path>) -> bool {\n    path.as_ref()\n        .components()\n        .any(|component| component == Component::ParentDir)\n}\n\nfn split_after_common_prefix<'first, 'second>(\n    first: &'first Path,\n    second: &'second Path,\n) -> (&'first Path, &'first Path, &'second Path) {\n    let entire_first = first;\n    let mut first = first.components();\n    let mut second = second.components();\n    loop {\n        let rest_of_first = first.as_path();\n        let rest_of_second = second.as_path();\n        match (first.next(), second.next()) {\n            (Some(first_component), Some(second_component))\n                if first_component == second_component => {}\n            _ => {\n                let mut common_prefix = entire_first;\n                for _ in rest_of_first.components().rev() {\n                    if let Some(parent) = common_prefix.parent() {\n                        common_prefix = parent;\n                    } else {\n                        common_prefix = Path::new(\"\");\n                        break;\n                    }\n                }\n                return (common_prefix, rest_of_first, rest_of_second);\n            }\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::out::abstractly_relativize_symlink;\n    use std::path::Path;\n\n    #[cfg(not(windows))]\n    #[test]\n    fn test_relativize_symlink_unix() {\n        assert_eq!(\n            abstractly_relativize_symlink(\"/foo/bar/baz\", \"/foo/spam/eggs\").as_deref(),\n            Some(Path::new(\"../bar/baz\")),\n        );\n        assert_eq!(\n            abstractly_relativize_symlink(\"/foo/bar/../baz\", \"/foo/spam/eggs\"),\n            None,\n        );\n        assert_eq!(\n            abstractly_relativize_symlink(\"/foo/bar/baz\", \"/foo/spam/./eggs\").as_deref(),\n            Some(Path::new(\"../bar/baz\")),\n        );\n    }\n\n    #[cfg(windows)]\n    #[test]\n    fn test_relativize_symlink_windows() {\n        use std::path::PathBuf;\n\n        let windows_target = PathBuf::from_iter([\"c:\\\\\", \"windows\", \"foo\"]);\n        let windows_link = PathBuf::from_iter([\"c:\\\\\", \"users\", \"link\"]);\n        let windows_different_volume_link = PathBuf::from_iter([\"d:\\\\\", \"users\", \"link\"]);\n\n        assert_eq!(\n            abstractly_relativize_symlink(&windows_target, windows_link).as_deref(),\n            Some(Path::new(\"..\\\\windows\\\\foo\")),\n        );\n        assert_eq!(\n            abstractly_relativize_symlink(&windows_target, windows_different_volume_link),\n            None,\n        );\n    }\n}\n"
  },
  {
    "path": "gen/build/src/paths.rs",
    "content": "use crate::error::Result;\nuse crate::gen::fs;\nuse std::ffi::OsStr;\nuse std::path::{Component, Path, PathBuf};\n\npub(crate) fn manifest_dir() -> Result<PathBuf> {\n    crate::env_os(\"CARGO_MANIFEST_DIR\").map(PathBuf::from)\n}\n\npub(crate) fn out_dir() -> Result<PathBuf> {\n    crate::env_os(\"OUT_DIR\").map(PathBuf::from)\n}\n\n// Given a path provided by the user, determines where generated files related\n// to that path should go in our out dir. In particular we don't want to\n// accidentally write generated code upward of our out dir, even if the user\n// passed a path containing lots of `..` or an absolute path.\npub(crate) fn local_relative_path(path: &Path) -> PathBuf {\n    let mut rel_path = PathBuf::new();\n    for component in path.components() {\n        match component {\n            Component::Prefix(_) | Component::RootDir | Component::CurDir => {}\n            Component::ParentDir => drop(rel_path.pop()), // noop if empty\n            Component::Normal(name) => rel_path.push(name),\n        }\n    }\n    rel_path\n}\n\npub(crate) trait PathExt {\n    fn with_appended_extension(&self, suffix: impl AsRef<OsStr>) -> PathBuf;\n}\n\nimpl PathExt for Path {\n    fn with_appended_extension(&self, suffix: impl AsRef<OsStr>) -> PathBuf {\n        let mut file_name = self.file_name().unwrap().to_owned();\n        file_name.push(suffix);\n        self.with_file_name(file_name)\n    }\n}\n\n#[cfg(unix)]\npub(crate) fn symlink_or_copy(\n    path_for_symlink: impl AsRef<Path>,\n    _path_for_copy: impl AsRef<Path>,\n    link: impl AsRef<Path>,\n) -> fs::Result<()> {\n    fs::symlink_file(path_for_symlink, link)\n}\n\n#[cfg(windows)]\npub(crate) fn symlink_or_copy(\n    path_for_symlink: impl AsRef<Path>,\n    path_for_copy: impl AsRef<Path>,\n    link: impl AsRef<Path>,\n) -> fs::Result<()> {\n    // Pre-Windows 10, symlinks require admin privileges. Since Windows 10, they\n    // require Developer Mode. If it fails, fall back to copying the file.\n    let path_for_symlink = path_for_symlink.as_ref();\n    let link = link.as_ref();\n    if fs::symlink_file(path_for_symlink, link).is_err() {\n        let path_for_copy = path_for_copy.as_ref();\n        fs::copy(path_for_copy, link)?;\n    }\n    Ok(())\n}\n\n#[cfg(not(any(unix, windows)))]\npub(crate) fn symlink_or_copy(\n    _path_for_symlink: impl AsRef<Path>,\n    path_for_copy: impl AsRef<Path>,\n    copy: impl AsRef<Path>,\n) -> fs::Result<()> {\n    fs::copy(path_for_copy, copy)?;\n    Ok(())\n}\n"
  },
  {
    "path": "gen/build/src/target.rs",
    "content": "use std::env;\nuse std::ffi::OsStr;\nuse std::path::{Path, PathBuf};\n\npub(crate) enum TargetDir {\n    Path(PathBuf),\n    Unknown,\n}\n\npub(crate) fn find_target_dir(out_dir: &Path) -> TargetDir {\n    if let Some(target_dir) = env::var_os(\"CARGO_TARGET_DIR\") {\n        let target_dir = PathBuf::from(target_dir);\n        return if target_dir.is_absolute() {\n            TargetDir::Path(target_dir)\n        } else {\n            TargetDir::Unknown\n        };\n    }\n\n    // fs::canonicalize on Windows produces UNC paths which cl.exe is unable to\n    // handle in includes.\n    // https://github.com/rust-lang/rust/issues/42869\n    // https://github.com/alexcrichton/cc-rs/issues/169\n    let mut also_try_canonical = cfg!(not(windows));\n\n    let mut dir = out_dir.to_owned();\n    loop {\n        if dir.join(\".rustc_info.json\").exists()\n            || dir.join(\"CACHEDIR.TAG\").exists()\n            || dir.file_name() == Some(OsStr::new(\"target\"))\n                && dir\n                    .parent()\n                    .is_some_and(|parent| parent.join(\"Cargo.toml\").exists())\n        {\n            return TargetDir::Path(dir);\n        }\n        if dir.pop() {\n            continue;\n        }\n        if also_try_canonical {\n            if let Ok(canonical_dir) = out_dir.canonicalize() {\n                dir = canonical_dir;\n                also_try_canonical = false;\n                continue;\n            }\n        }\n        return TargetDir::Unknown;\n    }\n}\n"
  },
  {
    "path": "gen/build/src/vec.rs",
    "content": "use crate::intern::{self, InternedString};\nuse std::path::Path;\n\npub(crate) trait InternedVec<T>\nwhere\n    T: ?Sized,\n{\n    fn vec(&self) -> Vec<&'static T>;\n}\n\nimpl<T> InternedVec<T> for Vec<InternedString>\nwhere\n    T: ?Sized + Element,\n{\n    fn vec(&self) -> Vec<&'static T> {\n        self.iter().copied().map(Element::unintern).collect()\n    }\n}\n\npub(crate) fn intern<T>(elements: &[&T]) -> Vec<InternedString>\nwhere\n    T: ?Sized + Element,\n{\n    elements.iter().copied().map(Element::intern).collect()\n}\n\npub(crate) trait Element {\n    fn intern(&self) -> InternedString;\n    fn unintern(_: InternedString) -> &'static Self;\n}\n\nimpl Element for str {\n    fn intern(&self) -> InternedString {\n        intern::intern(self)\n    }\n\n    fn unintern(interned: InternedString) -> &'static Self {\n        interned.str()\n    }\n}\n\nimpl Element for Path {\n    fn intern(&self) -> InternedString {\n        intern::intern(&self.to_string_lossy())\n    }\n\n    fn unintern(interned: InternedString) -> &'static Self {\n        Path::new(interned.str())\n    }\n}\n"
  },
  {
    "path": "gen/cmd/Cargo.toml",
    "content": "[package]\nname = \"cxxbridge-cmd\"\nversion = \"1.0.194\"\nauthors = [\"David Tolnay <dtolnay@gmail.com>\"]\ncategories = [\"development-tools::build-utils\", \"development-tools::ffi\"]\ndescription = \"C++ code generator for integrating `cxx` crate into a non-Cargo build.\"\nedition = \"2021\"\nexclude = [\"build.rs\"]\nhomepage = \"https://cxx.rs\"\nkeywords = [\"ffi\"]\nlicense = \"MIT OR Apache-2.0\"\nrepository = \"https://github.com/dtolnay/cxx\"\nrust-version = \"1.85\"\n\n[[bin]]\nname = \"cxxbridge\"\npath = \"src/main.rs\"\n\n[dependencies]\nclap = { version = \"4.3.11\", default-features = false, features = [\"error-context\", \"help\", \"std\", \"suggestions\", \"usage\"] }\ncodespan-reporting = \"0.13.1\"\nindexmap = \"2.9.0\"\nproc-macro2 = { version = \"1.0.74\", default-features = false, features = [\"span-locations\"] }\nquote = { version = \"1.0.35\", default-features = false }\nsyn = { version = \"2.0.46\", default-features = false, features = [\"clone-impls\", \"full\", \"parsing\", \"printing\"] }\n\n[package.metadata.docs.rs]\ntargets = [\"x86_64-unknown-linux-gnu\"]\n"
  },
  {
    "path": "gen/cmd/build.rs",
    "content": "include!(\"../../tools/cargo/build.rs\");\n"
  },
  {
    "path": "gen/cmd/src/app.rs",
    "content": "#[cfg(test)]\n#[path = \"test.rs\"]\nmod test;\n\nuse super::{Opt, Output};\nuse crate::cfg::{self, CfgValue};\nuse crate::gen::include::Include;\nuse crate::syntax::IncludeKind;\nuse clap::builder::{ArgAction, ValueParser};\nuse clap::{Arg, Command};\nuse std::collections::{BTreeMap as Map, BTreeSet as Set};\nuse std::path::PathBuf;\nuse std::process;\nuse std::sync::{Arc, Mutex, PoisonError};\nuse syn::parse::Parser;\n\nconst USAGE: &str = \"\\\n    cxxbridge <input>.rs              Emit .cc file for bridge to stdout\n    cxxbridge <input>.rs --header     Emit .h file for bridge to stdout\n    cxxbridge --header                Emit \\\"rust/cxx.h\\\" header to stdout\\\n\";\n\nconst TEMPLATE: &str = \"\\\n{bin} {version}\nDavid Tolnay <dtolnay@gmail.com>\nhttps://github.com/dtolnay/cxx\n\n{usage-heading}\n    {usage}\n\n{all-args}\\\n\";\n\nfn app() -> Command {\n    let mut app = Command::new(\"cxxbridge\")\n        .override_usage(USAGE)\n        .help_template(TEMPLATE)\n        .next_line_help(true)\n        .disable_help_flag(true)\n        .disable_version_flag(true)\n        .arg(arg_input())\n        .arg(arg_cfg())\n        .arg(arg_cxx_impl_annotations())\n        .arg(arg_header())\n        .arg(arg_help())\n        .arg(arg_include())\n        .arg(arg_output());\n    if let Some(version) = option_env!(\"CARGO_PKG_VERSION\") {\n        app = app.arg(arg_version()).version(version);\n    }\n    app\n}\n\nconst INPUT: &str = \"input\";\nconst CFG: &str = \"cfg\";\nconst CXX_IMPL_ANNOTATIONS: &str = \"cxx-impl-annotations\";\nconst HELP: &str = \"help\";\nconst HEADER: &str = \"header\";\nconst INCLUDE: &str = \"include\";\nconst OUTPUT: &str = \"output\";\nconst VERSION: &str = \"version\";\n\npub(super) fn from_args() -> Opt {\n    let matches = app().get_matches();\n\n    if matches.get_flag(HELP) {\n        let _ = app().print_long_help();\n        process::exit(0);\n    }\n\n    let input = matches.get_one::<PathBuf>(INPUT).cloned();\n    let cxx_impl_annotations = matches\n        .get_one::<String>(CXX_IMPL_ANNOTATIONS)\n        .map(String::clone);\n    let header = matches.get_flag(HEADER);\n    let include = matches\n        .get_many::<String>(INCLUDE)\n        .unwrap_or_default()\n        .map(|include| {\n            if include.starts_with('<') && include.ends_with('>') {\n                Include {\n                    path: include[1..include.len() - 1].to_owned(),\n                    kind: IncludeKind::Bracketed,\n                }\n            } else {\n                Include {\n                    path: include.clone(),\n                    kind: IncludeKind::Quoted,\n                }\n            }\n        })\n        .collect();\n\n    let mut outputs = Vec::new();\n    for path in matches.get_many::<PathBuf>(OUTPUT).unwrap_or_default() {\n        outputs.push(if path.as_os_str() == \"-\" {\n            Output::Stdout\n        } else {\n            Output::File(path.clone())\n        });\n    }\n    if outputs.is_empty() {\n        outputs.push(Output::Stdout);\n    }\n\n    let mut cfg = Map::new();\n    for arg in matches.get_many::<String>(CFG).unwrap_or_default() {\n        let (name, value) = cfg::parse.parse_str(arg).unwrap();\n        cfg.entry(name).or_insert_with(Set::new).insert(value);\n    }\n\n    Opt {\n        input,\n        header,\n        cxx_impl_annotations,\n        include,\n        outputs,\n        cfg,\n    }\n}\n\nfn arg_input() -> Arg {\n    Arg::new(INPUT)\n        .help(\"Input Rust source file containing #[cxx::bridge].\")\n        .required_unless_present_any([HEADER, HELP])\n        .value_parser(ValueParser::path_buf())\n}\n\nfn arg_cfg() -> Arg {\n    const HELP: &str = \"\\\nCompilation configuration matching what will be used to build\nthe Rust side of the bridge.\";\n    let bool_cfgs = Arc::new(Mutex::new(Map::<String, bool>::new()));\n    Arg::new(CFG)\n        .long(CFG)\n        .num_args(1)\n        .value_name(\"name=\\\"value\\\" | name[=true] | name=false\")\n        .action(ArgAction::Append)\n        .value_parser(move |arg: &str| match cfg::parse.parse_str(arg) {\n            Ok((_, CfgValue::Str(_))) => Ok(arg.to_owned()),\n            Ok((name, CfgValue::Bool(value))) => {\n                let mut bool_cfgs = bool_cfgs.lock().unwrap_or_else(PoisonError::into_inner);\n                if let Some(&prev) = bool_cfgs.get(&name) {\n                    if prev != value {\n                        return Err(format!(\"cannot have both {0}=false and {0}=true\", name));\n                    }\n                }\n                bool_cfgs.insert(name, value);\n                Ok(arg.to_owned())\n            }\n            Err(_) => Err(\"expected name=\\\"value\\\", name=true, or name=false\".to_owned()),\n        })\n        .help(HELP)\n}\n\nfn arg_cxx_impl_annotations() -> Arg {\n    const HELP: &str = \"\\\nOptional annotation for implementations of C++ function wrappers\nthat may be exposed to Rust. You may for example need to provide\n__declspec(dllexport) or __attribute__((visibility(\\\"default\\\")))\nif Rust code from one shared object or executable depends on\nthese C++ functions in another.\";\n    Arg::new(CXX_IMPL_ANNOTATIONS)\n        .long(CXX_IMPL_ANNOTATIONS)\n        .num_args(1)\n        .value_name(\"annotation\")\n        .value_parser(ValueParser::string())\n        .help(HELP)\n}\n\nfn arg_header() -> Arg {\n    const HELP: &str = \"\\\nEmit header with declarations only. Optional if using `-o` with\na path ending in `.h`.\";\n    Arg::new(HEADER).long(HEADER).num_args(0).help(HELP)\n}\n\nfn arg_help() -> Arg {\n    Arg::new(HELP)\n        .long(HELP)\n        .help(\"Print help information.\")\n        .num_args(0)\n}\n\nfn arg_include() -> Arg {\n    const HELP: &str = \"\\\nAny additional headers to #include. The cxxbridge tool does not\nparse or even require the given paths to exist; they simply go\ninto the generated C++ code as #include lines.\";\n    Arg::new(INCLUDE)\n        .long(INCLUDE)\n        .short('i')\n        .num_args(1)\n        .action(ArgAction::Append)\n        .value_parser(ValueParser::string())\n        .help(HELP)\n}\n\nfn arg_output() -> Arg {\n    const HELP: &str = \"\\\nPath of file to write as output. Output goes to stdout if -o is\nnot specified.\";\n    Arg::new(OUTPUT)\n        .long(OUTPUT)\n        .short('o')\n        .num_args(1)\n        .action(ArgAction::Append)\n        .value_parser(ValueParser::path_buf())\n        .help(HELP)\n}\n\nfn arg_version() -> Arg {\n    Arg::new(VERSION)\n        .long(VERSION)\n        .help(\"Print version information.\")\n        .action(ArgAction::Version)\n}\n"
  },
  {
    "path": "gen/cmd/src/cfg.rs",
    "content": "use crate::gen::{CfgEvaluator, CfgResult};\nuse std::collections::{BTreeMap as Map, BTreeSet as Set};\nuse std::fmt::{self, Debug};\nuse syn::parse::ParseStream;\nuse syn::{Ident, LitBool, LitStr, Token};\n\n#[derive(Ord, PartialOrd, Eq, PartialEq)]\npub(crate) enum CfgValue {\n    Bool(bool),\n    Str(String),\n}\n\nimpl CfgValue {\n    const FALSE: Self = CfgValue::Bool(false);\n    const TRUE: Self = CfgValue::Bool(true);\n}\n\npub(crate) struct FlagsCfgEvaluator {\n    map: Map<String, Set<CfgValue>>,\n}\n\nimpl FlagsCfgEvaluator {\n    pub(crate) fn new(map: Map<String, Set<CfgValue>>) -> Self {\n        FlagsCfgEvaluator { map }\n    }\n}\n\nimpl CfgEvaluator for FlagsCfgEvaluator {\n    fn eval(&self, name: &str, value: Option<&str>) -> CfgResult {\n        let set = self.map.get(name);\n        if let Some(value) = value {\n            if let Some(set) = set {\n                CfgResult::from(set.contains(&CfgValue::Str(value.to_owned())))\n            } else if name == \"feature\" {\n                CfgResult::False\n            } else {\n                let msg = format!(\n                    \"pass `--cfg {}=\\\"...\\\"` to be able to use this attribute\",\n                    name,\n                );\n                CfgResult::Undetermined { msg }\n            }\n        } else {\n            let (mut is_false, mut is_true) = (false, false);\n            if let Some(set) = set {\n                is_false = set.contains(&CfgValue::FALSE);\n                is_true = set.contains(&CfgValue::TRUE);\n            }\n            if is_false && is_true {\n                let msg = format!(\"the cxxbridge flags say both {0}=false and {0}=true\", name);\n                CfgResult::Undetermined { msg }\n            } else if is_false {\n                CfgResult::False\n            } else if is_true {\n                CfgResult::True\n            } else {\n                let msg = format!(\n                    \"pass either `--cfg {0}=true` or `--cfg {0}=false` to be able to use this cfg attribute\",\n                    name,\n                );\n                CfgResult::Undetermined { msg }\n            }\n        }\n    }\n}\n\nimpl Debug for CfgValue {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        match self {\n            CfgValue::Bool(value) => Debug::fmt(value, formatter),\n            CfgValue::Str(value) => Debug::fmt(value, formatter),\n        }\n    }\n}\n\npub(crate) fn parse(input: ParseStream) -> syn::Result<(String, CfgValue)> {\n    let ident: Ident = input.parse()?;\n    let name = ident.to_string();\n    if input.is_empty() {\n        return Ok((name, CfgValue::TRUE));\n    }\n    input.parse::<Token![=]>()?;\n    let lookahead = input.lookahead1();\n    if lookahead.peek(LitBool) {\n        let lit: LitBool = input.parse()?;\n        Ok((name, CfgValue::Bool(lit.value)))\n    } else if lookahead.peek(LitStr) {\n        let lit: LitStr = input.parse()?;\n        Ok((name, CfgValue::Str(lit.value())))\n    } else {\n        Err(lookahead.error())\n    }\n}\n"
  },
  {
    "path": "gen/cmd/src/main.rs",
    "content": "#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]\n#![allow(\n    clippy::cast_sign_loss,\n    clippy::default_trait_access,\n    clippy::elidable_lifetime_names,\n    clippy::enum_glob_use,\n    clippy::expl_impl_clone_on_copy, // https://github.com/rust-lang/rust-clippy/issues/15842\n    clippy::inherent_to_string,\n    clippy::items_after_statements,\n    clippy::map_clone,\n    clippy::match_bool,\n    clippy::match_like_matches_macro,\n    clippy::match_same_arms,\n    clippy::needless_continue,\n    clippy::needless_lifetimes,\n    clippy::needless_pass_by_value,\n    clippy::nonminimal_bool,\n    clippy::precedence,\n    clippy::redundant_else,\n    clippy::ref_option,\n    clippy::similar_names,\n    clippy::single_match_else,\n    clippy::struct_excessive_bools,\n    clippy::struct_field_names,\n    clippy::too_many_arguments,\n    clippy::too_many_lines,\n    clippy::toplevel_ref_arg,\n    clippy::uninlined_format_args\n)]\n#![allow(unknown_lints, mismatched_lifetime_syntaxes)]\n\nmod app;\nmod cfg;\nmod gen;\nmod output;\nmod syntax;\n\nuse crate::cfg::{CfgValue, FlagsCfgEvaluator};\nuse crate::gen::error::{report, Result};\nuse crate::gen::fs;\nuse crate::gen::include::{self, Include};\nuse crate::output::Output;\nuse std::collections::{BTreeMap as Map, BTreeSet as Set};\nuse std::io::{self, Write};\nuse std::path::PathBuf;\nuse std::process;\n\n#[derive(Debug)]\nstruct Opt {\n    input: Option<PathBuf>,\n    header: bool,\n    cxx_impl_annotations: Option<String>,\n    include: Vec<Include>,\n    outputs: Vec<Output>,\n    cfg: Map<String, Set<CfgValue>>,\n}\n\nfn main() {\n    if let Err(err) = try_main() {\n        let _ = writeln!(io::stderr(), \"cxxbridge: {}\", report(err));\n        process::exit(1);\n    }\n}\n\nenum Kind {\n    GeneratedHeader,\n    GeneratedImplementation,\n    Header,\n}\n\nfn try_main() -> Result<()> {\n    let opt = app::from_args();\n\n    let mut outputs = Vec::new();\n    let mut gen_header = false;\n    let mut gen_implementation = false;\n    for output in opt.outputs {\n        let kind = if opt.input.is_none() {\n            Kind::Header\n        } else if opt.header\n            || output.ends_with(\".h\")\n            || output.ends_with(\".hh\")\n            || output.ends_with(\".hpp\")\n        {\n            gen_header = true;\n            Kind::GeneratedHeader\n        } else {\n            gen_implementation = true;\n            Kind::GeneratedImplementation\n        };\n        outputs.push((output, kind));\n    }\n\n    let gen = gen::Opt {\n        include: opt.include,\n        cxx_impl_annotations: opt.cxx_impl_annotations,\n        gen_header,\n        gen_implementation,\n        cfg_evaluator: Box::new(FlagsCfgEvaluator::new(opt.cfg)),\n        ..Default::default()\n    };\n\n    let generated_code = if let Some(input) = opt.input {\n        gen::generate_from_path(&input, &gen)\n    } else {\n        Default::default()\n    };\n\n    for (output, kind) in outputs {\n        let content = match kind {\n            Kind::GeneratedHeader => &generated_code.header,\n            Kind::GeneratedImplementation => &generated_code.implementation,\n            Kind::Header => include::HEADER.as_bytes(),\n        };\n        match output {\n            Output::Stdout => drop(io::stdout().write_all(content)),\n            Output::File(path) => fs::write(path, content)?,\n        }\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "gen/cmd/src/output.rs",
    "content": "use std::path::PathBuf;\n\n#[derive(Debug)]\npub(crate) enum Output {\n    Stdout,\n    File(PathBuf),\n}\n\nimpl Output {\n    pub(crate) fn ends_with(&self, suffix: &str) -> bool {\n        match self {\n            Output::Stdout => false,\n            Output::File(path) => path.to_string_lossy().ends_with(suffix),\n        }\n    }\n}\n"
  },
  {
    "path": "gen/cmd/src/test.rs",
    "content": "const EXPECTED: &str = \"\\\ncxxbridge $VERSION\nDavid Tolnay <dtolnay@gmail.com>\nhttps://github.com/dtolnay/cxx\n\nUsage:\n    cxxbridge <input>.rs              Emit .cc file for bridge to stdout\n    cxxbridge <input>.rs --header     Emit .h file for bridge to stdout\n    cxxbridge --header                Emit \\\"rust/cxx.h\\\" header to stdout\n\nArguments:\n  [input]\n          Input Rust source file containing #[cxx::bridge].\n\nOptions:\n      --cfg <name=\\\"value\\\" | name[=true] | name=false>\n          Compilation configuration matching what will be used to build\n          the Rust side of the bridge.\n\n      --cxx-impl-annotations <annotation>\n          Optional annotation for implementations of C++ function wrappers\n          that may be exposed to Rust. You may for example need to provide\n          __declspec(dllexport) or __attribute__((visibility(\\\"default\\\")))\n          if Rust code from one shared object or executable depends on\n          these C++ functions in another.\n\n      --header\n          Emit header with declarations only. Optional if using `-o` with\n          a path ending in `.h`.\n\n      --help\n          Print help information.\n\n  -i, --include <include>\n          Any additional headers to #include. The cxxbridge tool does not\n          parse or even require the given paths to exist; they simply go\n          into the generated C++ code as #include lines.\n\n  -o, --output <output>\n          Path of file to write as output. Output goes to stdout if -o is\n          not specified.\n\n      --version\n          Print version information.\n\";\n\n#[test]\nfn test_help() {\n    let mut app = super::app();\n    let mut out = Vec::new();\n    app.write_long_help(&mut out).unwrap();\n    let help = String::from_utf8(out).unwrap();\n    let version = option_env!(\"CARGO_PKG_VERSION\").unwrap_or_default();\n    let expected = EXPECTED.replace(\"$VERSION\", version);\n    assert_eq!(help, expected);\n}\n\n#[test]\nfn test_cli() {\n    let app = super::app();\n    app.debug_assert();\n}\n"
  },
  {
    "path": "gen/lib/Cargo.toml",
    "content": "[package]\nname = \"cxx-gen\"\nversion = \"0.7.194\"\nauthors = [\"Adrian Taylor <adetaylor@chromium.org>\"]\ncategories = [\"development-tools::ffi\"]\ndescription = \"C++ code generator for integrating `cxx` crate into higher level tools.\"\ndocumentation = \"https://docs.rs/cxx-gen\"\nedition = \"2021\"\nexclude = [\"build.rs\"]\nkeywords = [\"ffi\"]\nlicense = \"MIT OR Apache-2.0\"\nrepository = \"https://github.com/dtolnay/cxx\"\nrust-version = \"1.85\"\n\n[dependencies]\ncodespan-reporting = \"0.13.1\"\nindexmap = \"2.9.0\"\nproc-macro2 = { version = \"1.0.74\", default-features = false, features = [\"span-locations\"] }\nquote = { version = \"1.0.35\", default-features = false }\nsyn = { version = \"2.0.46\", default-features = false, features = [\"clone-impls\", \"full\", \"parsing\", \"printing\"] }\n\n[package.metadata.docs.rs]\ntargets = [\"x86_64-unknown-linux-gnu\"]\nrustdoc-args = [\n    \"--generate-link-to-definition\",\n    \"--generate-macro-expansion\",\n    \"--extern-html-root-url=core=https://doc.rust-lang.org\",\n    \"--extern-html-root-url=alloc=https://doc.rust-lang.org\",\n    \"--extern-html-root-url=std=https://doc.rust-lang.org\",\n]\n"
  },
  {
    "path": "gen/lib/build.rs",
    "content": "include!(\"../../tools/cargo/build.rs\");\n"
  },
  {
    "path": "gen/lib/src/error.rs",
    "content": "// We can expose more detail on the error as the need arises, but start with an\n// opaque error type for now.\n\nuse std::error::Error as StdError;\nuse std::fmt::{self, Debug, Display};\nuse std::iter;\n\n#[allow(missing_docs)]\npub struct Error {\n    pub(crate) err: crate::gen::Error,\n}\n\nimpl Error {\n    /// Returns the span of the error, if available.\n    pub fn span(&self) -> Option<proc_macro2::Span> {\n        match &self.err {\n            crate::gen::Error::Syn(err) => Some(err.span()),\n            _ => None,\n        }\n    }\n}\n\nimpl From<crate::gen::Error> for Error {\n    fn from(err: crate::gen::Error) -> Self {\n        Error { err }\n    }\n}\n\nimpl Display for Error {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        Display::fmt(&self.err, f)\n    }\n}\n\nimpl Debug for Error {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        Debug::fmt(&self.err, f)\n    }\n}\n\nimpl StdError for Error {\n    fn source(&self) -> Option<&(dyn StdError + 'static)> {\n        self.err.source()\n    }\n}\n\nimpl IntoIterator for Error {\n    type Item = Error;\n    type IntoIter = IntoIter;\n\n    fn into_iter(self) -> Self::IntoIter {\n        match self.err {\n            crate::gen::Error::Syn(err) => IntoIter::Syn(err.into_iter()),\n            _ => IntoIter::Other(iter::once(self)),\n        }\n    }\n}\n\npub enum IntoIter {\n    Syn(<syn::Error as IntoIterator>::IntoIter),\n    Other(iter::Once<Error>),\n}\n\nimpl Iterator for IntoIter {\n    type Item = Error;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        match self {\n            IntoIter::Syn(iter) => iter\n                .next()\n                .map(|syn_err| Error::from(crate::gen::Error::Syn(syn_err))),\n            IntoIter::Other(iter) => iter.next(),\n        }\n    }\n}\n"
  },
  {
    "path": "gen/lib/src/lib.rs",
    "content": "//! The CXX code generator for constructing and compiling C++ code.\n//!\n//! This is intended as a mechanism for embedding the `cxx` crate into\n//! higher-level code generators. See [dtolnay/cxx#235] and\n//! [https://github.com/google/autocxx].\n//!\n//! [dtolnay/cxx#235]: https://github.com/dtolnay/cxx/issues/235\n//! [https://github.com/google/autocxx]: https://github.com/google/autocxx\n\n#![doc(html_root_url = \"https://docs.rs/cxx-gen/0.7.194\")]\n#![deny(missing_docs)]\n#![expect(dead_code)]\n#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]\n#![allow(\n    clippy::cast_sign_loss,\n    clippy::default_trait_access,\n    clippy::elidable_lifetime_names,\n    clippy::enum_glob_use,\n    clippy::expl_impl_clone_on_copy, // https://github.com/rust-lang/rust-clippy/issues/15842\n    clippy::inherent_to_string,\n    clippy::items_after_statements,\n    clippy::match_bool,\n    clippy::match_like_matches_macro,\n    clippy::match_same_arms,\n    clippy::missing_errors_doc,\n    clippy::must_use_candidate,\n    clippy::needless_continue,\n    clippy::needless_lifetimes,\n    clippy::needless_pass_by_value,\n    clippy::nonminimal_bool,\n    clippy::precedence,\n    clippy::redundant_else,\n    clippy::ref_option,\n    clippy::similar_names,\n    clippy::single_match_else,\n    clippy::struct_excessive_bools,\n    clippy::struct_field_names,\n    clippy::too_many_arguments,\n    clippy::too_many_lines,\n    clippy::toplevel_ref_arg,\n    clippy::uninlined_format_args\n)]\n#![allow(unknown_lints, mismatched_lifetime_syntaxes)]\n\nmod error;\nmod gen;\nmod syntax;\n\npub use crate::error::Error;\npub use crate::gen::include::{Include, HEADER};\npub use crate::gen::{CfgEvaluator, CfgResult, GeneratedCode, Opt};\npub use crate::syntax::IncludeKind;\nuse proc_macro2::TokenStream;\n\n/// Generate C++ bindings code from a Rust token stream. This should be a Rust\n/// token stream which somewhere contains a `#[cxx::bridge] mod {}`.\npub fn generate_header_and_cc(rust_source: TokenStream, opt: &Opt) -> Result<GeneratedCode, Error> {\n    let syntax = syn::parse2(rust_source)\n        .map_err(crate::gen::Error::from)\n        .map_err(Error::from)?;\n    gen::generate(syntax, opt).map_err(Error::from)\n}\n"
  },
  {
    "path": "gen/lib/tests/test.rs",
    "content": "use cxx_gen::Opt;\nuse quote::quote;\n\n#[test]\nfn test_positive() {\n    let rs = quote! {\n        #[cxx::bridge]\n        mod ffi {\n            unsafe extern \"C++\" {\n                fn in_C();\n            }\n            extern \"Rust\" {\n                fn in_rs();\n            }\n        }\n    };\n    let opt = Opt::default();\n    let code = cxx_gen::generate_header_and_cc(rs, &opt).unwrap();\n    assert!(!code.header.is_empty());\n    assert!(!code.implementation.is_empty());\n}\n\n#[test]\nfn test_negative() {\n    let rs = quote! {};\n    let opt = Opt::default();\n    assert!(cxx_gen::generate_header_and_cc(rs, &opt).is_err());\n}\n"
  },
  {
    "path": "gen/src/block.rs",
    "content": "use proc_macro2::Ident;\n\n#[derive(Copy, Clone, PartialEq, Debug)]\npub(crate) enum Block<'a> {\n    AnonymousNamespace,\n    Namespace(&'a str),\n    UserDefinedNamespace(&'a Ident),\n    InlineNamespace(&'a str),\n    ExternC,\n}\n\nimpl<'a> Block<'a> {\n    pub(crate) fn write_begin(self, out: &mut String) {\n        if let Block::InlineNamespace(_) = self {\n            out.push_str(\"inline \");\n        }\n        self.write_common(out);\n        out.push_str(\" {\\n\");\n    }\n\n    pub(crate) fn write_end(self, out: &mut String) {\n        out.push_str(\"} // \");\n        self.write_common(out);\n        out.push('\\n');\n    }\n\n    fn write_common(self, out: &mut String) {\n        match self {\n            Block::AnonymousNamespace => out.push_str(\"namespace\"),\n            Block::Namespace(name) => {\n                out.push_str(\"namespace \");\n                out.push_str(name);\n            }\n            Block::UserDefinedNamespace(name) => {\n                out.push_str(\"namespace \");\n                out.push_str(&name.to_string());\n            }\n            Block::InlineNamespace(name) => {\n                out.push_str(\"namespace \");\n                out.push_str(name);\n            }\n            Block::ExternC => out.push_str(\"extern \\\"C\\\"\"),\n        }\n    }\n}\n"
  },
  {
    "path": "gen/src/builtin/alignmax.h",
    "content": "#pragma once\n#include <cstddef>\n\nnamespace rust {\ninline namespace cxxbridge1 {\nnamespace repr {\n#ifndef CXXBRIDGE_ALIGNMAX\n#define CXXBRIDGE_ALIGNMAX\n// This would be cleaner as the following, but GCC does not implement that\n// correctly. <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64236>\n//\n//     template <::std::size_t... N>\n//     class alignas(N...) alignmax {};\n//\n// Next, it could be this, but MSVC does not implement this correctly.\n//\n//     template <::std::size_t... N>\n//     class alignmax { alignas(N...) union {} members; };\n//\ntemplate <::std::size_t N>\nclass alignas(N) aligned {};\n//\ntemplate <typename... T>\nclass alignmax_t { alignas(T...) union {} members; };\n//\ntemplate <::std::size_t... N>\nusing alignmax = alignmax_t<aligned<N>...>;\n#endif // CXXBRIDGE_ALIGNMAX\n} // namespace repr\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/deleter_if.h",
    "content": "#pragma once\n\nnamespace rust {\ninline namespace cxxbridge1 {\nnamespace {\ntemplate <bool> struct deleter_if {\n  template <typename T> void operator()(T *) {}\n};\n//\ntemplate <> struct deleter_if<true> {\n  template <typename T> void operator()(T *ptr) { ptr->~T(); }\n};\n} // namespace\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/destroy.h",
    "content": "#pragma once\n\nnamespace rust {\ninline namespace cxxbridge1 {\nnamespace {\ntemplate <typename T>\nvoid destroy(T *ptr) {\n  ptr->~T();\n}\n} // namespace\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/friend_impl.h",
    "content": "#pragma once\n\nnamespace rust {\ninline namespace cxxbridge1 {\nnamespace {\ntemplate <typename T>\nclass impl;\n} // namespace\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/manually_drop.h",
    "content": "#pragma once\n#include <utility>\n\n#pragma GCC diagnostic ignored \"-Wshadow\"\n\nnamespace rust {\ninline namespace cxxbridge1 {\ntemplate <typename T>\nunion ManuallyDrop {\n  T value;\n  ManuallyDrop(T &&value) : value(::std::move(value)) {}\n  ~ManuallyDrop() {}\n};\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/maybe_uninit.h",
    "content": "#pragma once\n#include \"./maybe_uninit_detail.h\"\n#include <cstddef>\n\nnamespace rust {\ninline namespace cxxbridge1 {\ntemplate <typename T>\nunion MaybeUninit {\n  T value;\n  void *operator new(::std::size_t sz) { return detail::operator_new<T>{}(sz); }\n  MaybeUninit() {}\n  ~MaybeUninit() {}\n};\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/maybe_uninit_detail.h",
    "content": "#pragma once\n#include <cstddef>\n#include <new>\n\nnamespace rust {\ninline namespace cxxbridge1 {\nnamespace detail {\ntemplate <typename T, typename = void *>\nstruct operator_new {\n  void *operator()(::std::size_t sz) { return ::operator new(sz); }\n};\n\ntemplate <typename T>\nstruct operator_new<T, decltype(T::operator new(sizeof(T)))> {\n  void *operator()(::std::size_t sz) { return T::operator new(sz); }\n};\n} // namespace detail\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/ptr_len.h",
    "content": "#pragma once\n#include <cstddef>\n\nnamespace rust {\ninline namespace cxxbridge1 {\nnamespace repr {\nstruct PtrLen final {\n  void *ptr;\n  ::std::size_t len;\n};\n} // namespace repr\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/relocatable_or_array.h",
    "content": "#pragma once\n#include \"../../../include/cxx.h\"\n#include <cstdint>\n\nnamespace rust {\ninline namespace cxxbridge1 {\nnamespace {\ntemplate <typename T>\nstruct IsRelocatableOrArray : IsRelocatable<T> {};\n//\ntemplate <typename T, ::std::size_t N>\nstruct IsRelocatableOrArray<T[N]> : IsRelocatableOrArray<T> {};\n} // namespace\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/repr_fat.h",
    "content": "#pragma once\n#include <array>\n#include <cstdint>\n\nnamespace rust {\ninline namespace cxxbridge1 {\nnamespace repr {\nusing Fat = ::std::array<::std::uintptr_t, 2>;\n} // namespace repr\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/rust_error.h",
    "content": "#pragma once\n#include \"../../../include/cxx.h\"\n#include \"./friend_impl.h\"\n#include \"./ptr_len.h\"\n\nnamespace rust {\ninline namespace cxxbridge1 {\nnamespace {\ntemplate <>\nclass impl<Error> final {\npublic:\n  static Error error(repr::PtrLen repr) noexcept {\n    Error error;\n    error.msg = static_cast<char const *>(repr.ptr);\n    error.len = repr.len;\n    return error;\n  }\n};\n} // namespace\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/rust_slice_uninit.h",
    "content": "#pragma once\n#include \"../../../include/cxx.h\"\n\nnamespace rust {\ninline namespace cxxbridge1 {\ntemplate <typename T>\nclass Slice<T>::uninit {};\n//\ntemplate <typename T>\ninline Slice<T>::Slice(uninit) noexcept {}\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/rust_str_uninit.h",
    "content": "#pragma once\n#include \"../../../include/cxx.h\"\n\nnamespace rust {\ninline namespace cxxbridge1 {\nclass Str::uninit {};\n//\ninline Str::Str(uninit) noexcept {}\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/shared_ptr.h",
    "content": "#pragma once\n#include \"../../../include/cxx.h\"\n#include <memory>\n\nnamespace rust {\ninline namespace cxxbridge1 {\nnamespace {\ntemplate <typename T, bool = ::rust::detail::is_complete<T>::value>\nstruct is_destructible : ::std::false_type {};\n//\ntemplate <typename T>\nstruct is_destructible<T, true> : ::std::is_destructible<T> {};\n//\ntemplate <typename T>\nstruct is_destructible<T[], false> : is_destructible<T> {};\n//\ntemplate <typename T, bool = ::rust::is_destructible<T>::value>\nstruct shared_ptr_if_destructible {\n  explicit shared_ptr_if_destructible(typename ::std::shared_ptr<T>::element_type *) {}\n};\n//\ntemplate <typename T>\nstruct shared_ptr_if_destructible<T, true> : ::std::shared_ptr<T> {\n  using ::std::shared_ptr<T>::shared_ptr;\n};\n} // namespace\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/trycatch.h",
    "content": "#pragma once\n#include \"./trycatch_detail.h\"\n#include <exception>\n#include <type_traits>\n#include <utility>\n\nnamespace rust {\nnamespace behavior {\nclass missing {};\nmissing trycatch(...);\n\ntemplate <typename Try, typename Fail>\nstatic typename ::std::enable_if<::std::is_same<\n    decltype(trycatch(::std::declval<Try>(), ::std::declval<Fail>())),\n    missing>::value>::type\ntrycatch(Try &&func, Fail &&fail) noexcept try {\n  func();\n} catch (::std::exception const &e) {\n  fail(e.what());\n}\n} // namespace behavior\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/trycatch_detail.h",
    "content": "#pragma once\n#include \"./ptr_len.h\"\n#include <string>\n\n#pragma GCC diagnostic ignored \"-Wshadow\"\n#pragma clang diagnostic ignored \"-Wdollar-in-identifier-extension\"\n\nnamespace rust {\ninline namespace cxxbridge1 {\nnamespace detail {\nclass Fail final {\n  ::rust::repr::PtrLen &throw$;\n  //\npublic:\n  Fail(::rust::repr::PtrLen &throw$) noexcept : throw$(throw$) {}\n  void operator()(char const *) noexcept;\n  void operator()(std::string const &) noexcept;\n};\n} // namespace detail\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin/vector.h",
    "content": "#pragma once\n#include \"../../../include/cxx.h\"\n#include <type_traits>\n#include <vector>\n\nnamespace rust {\ninline namespace cxxbridge1 {\nnamespace {\ntemplate <typename T, bool = ::std::is_move_constructible<T>::value>\nstruct if_move_constructible {\n  static bool reserve(::std::vector<T> &, ::std::size_t) noexcept {\n    return false;\n  }\n};\n//\ntemplate <typename T>\nstruct if_move_constructible<T, true> {\n  static bool reserve(::std::vector<T> &vec, ::std::size_t new_cap) {\n    vec.reserve(new_cap);\n    return true;\n  }\n};\n} // namespace\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "gen/src/builtin.rs",
    "content": "use crate::gen::block::Block;\nuse crate::gen::ifndef;\nuse crate::gen::include::Includes;\nuse crate::gen::out::{Content, OutFile};\nuse crate::gen::pragma::Pragma;\n\n#[derive(Default, PartialEq)]\npub(crate) struct Builtins<'a> {\n    pub panic: bool,\n    pub rust_string: bool,\n    pub rust_str: bool,\n    pub rust_slice: bool,\n    pub rust_box: bool,\n    pub rust_vec: bool,\n    pub rust_fn: bool,\n    pub rust_isize: bool,\n    pub opaque: bool,\n    pub layout: bool,\n    pub unsafe_bitcopy: bool,\n    pub unsafe_bitcopy_t: bool,\n    pub rust_error: bool,\n    pub manually_drop: bool,\n    pub maybe_uninit: bool,\n    pub trycatch: bool,\n    pub ptr_len: bool,\n    pub repr_fat: bool,\n    pub rust_str_new_unchecked: bool,\n    pub rust_str_repr: bool,\n    pub rust_slice_new: bool,\n    pub rust_slice_repr: bool,\n    pub relocatable: bool,\n    pub relocatable_or_array: bool,\n    pub friend_impl: bool,\n    pub is_complete: bool,\n    pub destroy: bool,\n    pub deleter_if: bool,\n    pub shared_ptr: bool,\n    pub vector: bool,\n    pub alignmax: bool,\n    pub content: Content<'a>,\n}\n\nimpl<'a> Builtins<'a> {\n    pub(crate) fn new() -> Self {\n        Builtins::default()\n    }\n}\n\npub(super) fn write(out: &mut OutFile) {\n    if out.builtin == Default::default() {\n        return;\n    }\n\n    let include = &mut out.include;\n    let pragma = &mut out.pragma;\n    let builtin = &mut out.builtin;\n    let out = &mut builtin.content;\n\n    if builtin.rust_string {\n        include.array = true;\n        include.cstdint = true;\n        include.string = true;\n    }\n\n    if builtin.rust_str {\n        include.array = true;\n        include.cstdint = true;\n        include.string = true;\n        include.string_view = true;\n        builtin.friend_impl = true;\n    }\n\n    if builtin.rust_vec {\n        include.algorithm = true;\n        include.array = true;\n        include.cassert = true;\n        include.cstddef = true;\n        include.cstdint = true;\n        include.initializer_list = true;\n        include.iterator = true;\n        include.new = true;\n        include.stdexcept = true;\n        include.type_traits = true;\n        include.utility = true;\n        builtin.panic = true;\n        builtin.rust_slice = true;\n        builtin.unsafe_bitcopy_t = true;\n    }\n\n    if builtin.rust_slice {\n        include.array = true;\n        include.cassert = true;\n        include.cstddef = true;\n        include.cstdint = true;\n        include.iterator = true;\n        include.ranges = true;\n        include.stdexcept = true;\n        include.type_traits = true;\n        builtin.friend_impl = true;\n        builtin.layout = true;\n        builtin.panic = true;\n    }\n\n    if builtin.rust_box {\n        include.new = true;\n        include.type_traits = true;\n        include.utility = true;\n    }\n\n    if builtin.rust_fn {\n        include.utility = true;\n    }\n\n    if builtin.rust_error {\n        include.exception = true;\n        builtin.friend_impl = true;\n    }\n\n    if builtin.rust_isize {\n        include.basetsd = true;\n        include.sys_types = true;\n    }\n\n    if builtin.relocatable_or_array {\n        include.cstddef = true;\n        builtin.relocatable = true;\n    }\n\n    if builtin.relocatable {\n        include.type_traits = true;\n    }\n\n    if builtin.layout {\n        include.type_traits = true;\n        include.cstddef = true;\n        builtin.is_complete = true;\n    }\n\n    if builtin.shared_ptr {\n        include.memory = true;\n        include.type_traits = true;\n        builtin.is_complete = true;\n    }\n\n    if builtin.is_complete {\n        include.cstddef = true;\n        include.type_traits = true;\n    }\n\n    if builtin.unsafe_bitcopy {\n        builtin.unsafe_bitcopy_t = true;\n    }\n\n    if builtin.trycatch {\n        builtin.ptr_len = true;\n    }\n\n    out.begin_block(Block::Namespace(\"rust\"));\n    out.begin_block(Block::InlineNamespace(\"cxxbridge1\"));\n\n    let cxx_header = include.has_cxx_header();\n    if !cxx_header {\n        writeln!(out, \"// #include \\\"rust/cxx.h\\\"\");\n\n        ifndef::write(out, builtin.panic, \"CXXBRIDGE1_PANIC\");\n\n        if builtin.rust_string {\n            out.next_section();\n            writeln!(out, \"struct unsafe_bitcopy_t;\");\n        }\n\n        if builtin.friend_impl {\n            out.begin_block(Block::AnonymousNamespace);\n            writeln!(out, \"template <typename T>\");\n            writeln!(out, \"class impl;\");\n            out.end_block(Block::AnonymousNamespace);\n        }\n\n        out.next_section();\n        if builtin.rust_str && !builtin.rust_string {\n            writeln!(out, \"class String;\");\n        }\n        if builtin.layout && !builtin.opaque {\n            writeln!(out, \"class Opaque;\");\n        }\n\n        if builtin.rust_slice {\n            out.next_section();\n            writeln!(out, \"template <typename T>\");\n            writeln!(out, \"::std::size_t size_of();\");\n            writeln!(out, \"template <typename T>\");\n            writeln!(out, \"::std::size_t align_of();\");\n        }\n\n        ifndef::write(out, builtin.rust_string, \"CXXBRIDGE1_RUST_STRING\");\n        ifndef::write(out, builtin.rust_str, \"CXXBRIDGE1_RUST_STR\");\n        ifndef::write(out, builtin.rust_slice, \"CXXBRIDGE1_RUST_SLICE\");\n        ifndef::write(out, builtin.rust_box, \"CXXBRIDGE1_RUST_BOX\");\n        ifndef::write(out, builtin.unsafe_bitcopy_t, \"CXXBRIDGE1_RUST_BITCOPY_T\");\n        ifndef::write(out, builtin.unsafe_bitcopy, \"CXXBRIDGE1_RUST_BITCOPY\");\n        ifndef::write(out, builtin.rust_vec, \"CXXBRIDGE1_RUST_VEC\");\n        ifndef::write(out, builtin.rust_fn, \"CXXBRIDGE1_RUST_FN\");\n        ifndef::write(out, builtin.rust_error, \"CXXBRIDGE1_RUST_ERROR\");\n        ifndef::write(out, builtin.rust_isize, \"CXXBRIDGE1_RUST_ISIZE\");\n        ifndef::write(out, builtin.opaque, \"CXXBRIDGE1_RUST_OPAQUE\");\n        ifndef::write(out, builtin.is_complete, \"CXXBRIDGE1_IS_COMPLETE\");\n        ifndef::write(out, builtin.layout, \"CXXBRIDGE1_LAYOUT\");\n        ifndef::write(out, builtin.relocatable, \"CXXBRIDGE1_RELOCATABLE\");\n    }\n\n    out.end_block(Block::InlineNamespace(\"cxxbridge1\"));\n    out.end_block(Block::Namespace(\"rust\"));\n\n    macro_rules! write_builtin {\n        ($path:literal) => {\n            write_builtin(out, include, pragma, include_str!($path));\n        };\n    }\n\n    // namespace rust::cxxbridge1\n\n    if builtin.rust_str_new_unchecked {\n        write_builtin!(\"builtin/rust_str_uninit.h\");\n    }\n\n    if builtin.rust_slice_new {\n        write_builtin!(\"builtin/rust_slice_uninit.h\");\n    }\n\n    // namespace rust::cxxbridge1::repr\n\n    if builtin.repr_fat {\n        write_builtin!(\"builtin/repr_fat.h\");\n    }\n\n    if builtin.ptr_len {\n        write_builtin!(\"builtin/ptr_len.h\");\n    }\n\n    if builtin.alignmax {\n        write_builtin!(\"builtin/alignmax.h\");\n    }\n\n    // namespace rust::cxxbridge1::detail\n\n    if builtin.maybe_uninit {\n        write_builtin!(\"builtin/maybe_uninit_detail.h\");\n    }\n\n    if builtin.trycatch {\n        write_builtin!(\"builtin/trycatch_detail.h\");\n    }\n\n    // namespace rust::cxxbridge1\n\n    if builtin.manually_drop {\n        write_builtin!(\"builtin/manually_drop.h\");\n    }\n\n    if builtin.maybe_uninit {\n        write_builtin!(\"builtin/maybe_uninit.h\");\n    }\n\n    out.begin_block(Block::Namespace(\"rust\"));\n    out.begin_block(Block::InlineNamespace(\"cxxbridge1\"));\n    out.begin_block(Block::AnonymousNamespace);\n\n    if builtin.rust_str_new_unchecked || builtin.rust_str_repr {\n        out.next_section();\n        writeln!(out, \"template <>\");\n        writeln!(out, \"class impl<Str> final {{\");\n        writeln!(out, \"public:\");\n        if builtin.rust_str_new_unchecked {\n            writeln!(\n                out,\n                \"  static Str new_unchecked(repr::Fat repr) noexcept {{\",\n            );\n            writeln!(out, \"    Str str = Str::uninit{{}};\");\n            writeln!(out, \"    str.repr = repr;\");\n            writeln!(out, \"    return str;\");\n            writeln!(out, \"  }}\");\n        }\n        if builtin.rust_str_repr {\n            writeln!(out, \"  static repr::Fat repr(Str str) noexcept {{\");\n            writeln!(out, \"    return str.repr;\");\n            writeln!(out, \"  }}\");\n        }\n        writeln!(out, \"}};\");\n    }\n\n    if builtin.rust_slice_new || builtin.rust_slice_repr {\n        out.next_section();\n        writeln!(out, \"template <typename T>\");\n        writeln!(out, \"class impl<Slice<T>> final {{\");\n        writeln!(out, \"public:\");\n        if builtin.rust_slice_new {\n            writeln!(out, \"  static Slice<T> slice(repr::Fat repr) noexcept {{\");\n            writeln!(out, \"    Slice<T> slice = typename Slice<T>::uninit{{}};\");\n            writeln!(out, \"    slice.repr = repr;\");\n            writeln!(out, \"    return slice;\");\n            writeln!(out, \"  }}\");\n        }\n        if builtin.rust_slice_repr {\n            writeln!(out, \"  static repr::Fat repr(Slice<T> slice) noexcept {{\");\n            writeln!(out, \"    return slice.repr;\");\n            writeln!(out, \"  }}\");\n        }\n        writeln!(out, \"}};\");\n    }\n\n    out.end_block(Block::AnonymousNamespace);\n    out.end_block(Block::InlineNamespace(\"cxxbridge1\"));\n    out.end_block(Block::Namespace(\"rust\"));\n\n    // namespace rust::cxxbridge1::(anonymous)\n\n    if builtin.rust_error {\n        write_builtin!(\"builtin/rust_error.h\");\n    }\n\n    if builtin.destroy {\n        write_builtin!(\"builtin/destroy.h\");\n    }\n\n    if builtin.deleter_if {\n        write_builtin!(\"builtin/deleter_if.h\");\n    }\n\n    if builtin.shared_ptr {\n        write_builtin!(\"builtin/shared_ptr.h\");\n    }\n\n    if builtin.vector {\n        write_builtin!(\"builtin/vector.h\");\n    }\n\n    if builtin.relocatable_or_array {\n        write_builtin!(\"builtin/relocatable_or_array.h\");\n    }\n\n    // namespace rust::behavior\n\n    if builtin.trycatch {\n        write_builtin!(\"builtin/trycatch.h\");\n    }\n}\n\nfn write_builtin<'a>(\n    out: &mut Content<'a>,\n    include: &mut Includes,\n    pragma: &mut Pragma<'a>,\n    src: &'a str,\n) {\n    let mut namespace = Vec::new();\n    let mut ready = false;\n\n    for line in src.lines() {\n        if line == \"#pragma once\" || line.starts_with(\"#include \\\".\") {\n            continue;\n        } else if let Some(rest) = line.strip_prefix(\"#include <\") {\n            let Includes {\n                custom: _,\n                algorithm,\n                array,\n                cassert,\n                cstddef,\n                cstdint,\n                cstring,\n                exception,\n                functional,\n                initializer_list,\n                iterator,\n                limits,\n                memory,\n                new,\n                ranges,\n                stdexcept,\n                string,\n                string_view,\n                type_traits,\n                utility,\n                vector,\n                basetsd: _,\n                sys_types: _,\n                content: _,\n            } = include;\n            match rest.strip_suffix(\">\").unwrap() {\n                \"algorithm\" => *algorithm = true,\n                \"array\" => *array = true,\n                \"cassert\" => *cassert = true,\n                \"cstddef\" => *cstddef = true,\n                \"cstdint\" => *cstdint = true,\n                \"cstring\" => *cstring = true,\n                \"exception\" => *exception = true,\n                \"functional\" => *functional = true,\n                \"initializer_list\" => *initializer_list = true,\n                \"iterator\" => *iterator = true,\n                \"limits\" => *limits = true,\n                \"memory\" => *memory = true,\n                \"new\" => *new = true,\n                \"ranges\" => *ranges = true,\n                \"stdexcept\" => *stdexcept = true,\n                \"string\" => *string = true,\n                \"string_view\" => *string_view = true,\n                \"type_traits\" => *type_traits = true,\n                \"utility\" => *utility = true,\n                \"vector\" => *vector = true,\n                _ => unimplemented!(\"{}\", line),\n            }\n        } else if let Some(rest) = line.strip_prefix(\"#pragma GCC diagnostic ignored \\\"\") {\n            let diagnostic = rest.strip_suffix('\"').unwrap();\n            pragma.gnu_diagnostic_ignore.insert(diagnostic);\n            ready = false;\n        } else if let Some(rest) = line.strip_prefix(\"#pragma clang diagnostic ignored \\\"\") {\n            let diagnostic = rest.strip_suffix('\"').unwrap();\n            pragma.clang_diagnostic_ignore.insert(diagnostic);\n            ready = false;\n        } else if line == \"namespace {\" {\n            namespace.push(Block::AnonymousNamespace);\n            out.begin_block(Block::AnonymousNamespace);\n        } else if let Some(rest) = line.strip_prefix(\"namespace \") {\n            let name = rest.strip_suffix(\" {\").unwrap();\n            namespace.push(Block::Namespace(name));\n            out.begin_block(Block::Namespace(name));\n        } else if let Some(rest) = line.strip_prefix(\"inline namespace \") {\n            let name = rest.strip_suffix(\" {\").unwrap();\n            namespace.push(Block::InlineNamespace(name));\n            out.begin_block(Block::InlineNamespace(name));\n        } else if line.starts_with(\"} // namespace\") {\n            out.end_block(namespace.pop().unwrap());\n        } else if line.is_empty() && !ready {\n            out.next_section();\n            ready = true;\n        } else if !line.trim_start_matches(' ').starts_with(\"//\") {\n            assert!(ready);\n            writeln!(out, \"{}\", line);\n        }\n    }\n\n    assert!(namespace.is_empty());\n    assert!(ready);\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::gen::include::Includes;\n    use crate::gen::out::Content;\n    use crate::gen::pragma::Pragma;\n    use std::fs;\n\n    #[test]\n    fn test_write_builtin() {\n        let mut builtin_src = Vec::new();\n\n        for entry in fs::read_dir(\"src/gen/builtin\").unwrap() {\n            let path = entry.unwrap().path();\n            let src = fs::read_to_string(path).unwrap();\n            builtin_src.push(src);\n        }\n\n        assert_ne!(builtin_src.len(), 0);\n        builtin_src.sort();\n\n        let mut content = Content::new();\n        let mut include = Includes::new();\n        let mut pragma = Pragma::new();\n        for src in &builtin_src {\n            super::write_builtin(&mut content, &mut include, &mut pragma, src);\n        }\n    }\n}\n"
  },
  {
    "path": "gen/src/cfg.rs",
    "content": "use crate::gen::{CfgEvaluator, CfgResult};\nuse crate::syntax::cfg::CfgExpr;\nuse crate::syntax::report::Errors;\nuse crate::syntax::Api;\nuse quote::quote;\nuse std::collections::BTreeSet as Set;\nuse std::mem;\nuse syn::{Error, LitStr};\n\npub(super) struct UnsupportedCfgEvaluator;\n\nimpl CfgEvaluator for UnsupportedCfgEvaluator {\n    fn eval(&self, name: &str, value: Option<&str>) -> CfgResult {\n        let _ = name;\n        let _ = value;\n        let msg = \"cfg attribute is not supported\".to_owned();\n        CfgResult::Undetermined { msg }\n    }\n}\n\npub(super) fn strip(\n    cx: &mut Errors,\n    cfg_errors: &mut Set<String>,\n    cfg_evaluator: &dyn CfgEvaluator,\n    apis: &mut Vec<Api>,\n) {\n    let mut eval = |cfg: &mut CfgExpr| {\n        let cfg = mem::replace(cfg, CfgExpr::Unconditional);\n        self::eval(cx, cfg_errors, cfg_evaluator, &cfg)\n    };\n    apis.retain_mut(|api| {\n        eval(match api {\n            Api::Include(include) => &mut include.cfg,\n            Api::Struct(strct) => &mut strct.cfg,\n            Api::Enum(enm) => &mut enm.cfg,\n            Api::CxxType(ety) | Api::RustType(ety) => &mut ety.cfg,\n            Api::CxxFunction(efn) | Api::RustFunction(efn) => &mut efn.cfg,\n            Api::TypeAlias(alias) => &mut alias.cfg,\n            Api::Impl(imp) => &mut imp.cfg,\n        })\n    });\n    for api in apis {\n        match api {\n            Api::Struct(strct) => strct.fields.retain_mut(|field| eval(&mut field.cfg)),\n            Api::Enum(enm) => enm.variants.retain_mut(|variant| eval(&mut variant.cfg)),\n            _ => {}\n        }\n    }\n}\n\npub(super) fn eval(\n    cx: &mut Errors,\n    cfg_errors: &mut Set<String>,\n    cfg_evaluator: &dyn CfgEvaluator,\n    expr: &CfgExpr,\n) -> bool {\n    match try_eval(cfg_evaluator, expr) {\n        Ok(value) => value,\n        Err(errors) => {\n            for error in errors {\n                if cfg_errors.insert(error.to_string()) {\n                    cx.push(error);\n                }\n            }\n            false\n        }\n    }\n}\n\nfn try_eval(cfg_evaluator: &dyn CfgEvaluator, expr: &CfgExpr) -> Result<bool, Vec<Error>> {\n    match expr {\n        CfgExpr::Unconditional => Ok(true),\n        CfgExpr::Eq(ident, string) => {\n            let key = ident.to_string();\n            let value = string.as_ref().map(LitStr::value);\n            match cfg_evaluator.eval(&key, value.as_deref()) {\n                CfgResult::True => Ok(true),\n                CfgResult::False => Ok(false),\n                CfgResult::Undetermined { msg } => {\n                    let span = quote!(#ident #string);\n                    Err(vec![Error::new_spanned(span, msg)])\n                }\n            }\n        }\n        CfgExpr::All(list) => {\n            let mut all_errors = Vec::new();\n            for subexpr in list {\n                match try_eval(cfg_evaluator, subexpr) {\n                    Ok(true) => {}\n                    Ok(false) => return Ok(false),\n                    Err(errors) => all_errors.extend(errors),\n                }\n            }\n            if all_errors.is_empty() {\n                Ok(true)\n            } else {\n                Err(all_errors)\n            }\n        }\n        CfgExpr::Any(list) => {\n            let mut all_errors = Vec::new();\n            for subexpr in list {\n                match try_eval(cfg_evaluator, subexpr) {\n                    Ok(true) => return Ok(true),\n                    Ok(false) => {}\n                    Err(errors) => all_errors.extend(errors),\n                }\n            }\n            if all_errors.is_empty() {\n                Ok(false)\n            } else {\n                Err(all_errors)\n            }\n        }\n        CfgExpr::Not(subexpr) => match try_eval(cfg_evaluator, subexpr) {\n            Ok(value) => Ok(!value),\n            Err(errors) => Err(errors),\n        },\n    }\n}\n\nimpl From<bool> for CfgResult {\n    fn from(value: bool) -> Self {\n        if value {\n            CfgResult::True\n        } else {\n            CfgResult::False\n        }\n    }\n}\n"
  },
  {
    "path": "gen/src/check.rs",
    "content": "use crate::gen::Opt;\nuse crate::syntax::report::Errors;\nuse crate::syntax::{error, Api};\nuse quote::{quote, quote_spanned};\nuse std::path::{Component, Path};\n\npub(super) use crate::syntax::check::{typecheck, Generator};\n\npub(super) fn precheck(cx: &mut Errors, apis: &[Api], opt: &Opt) {\n    if !opt.allow_dot_includes {\n        check_dot_includes(cx, apis);\n    }\n}\n\nfn check_dot_includes(cx: &mut Errors, apis: &[Api]) {\n    for api in apis {\n        if let Api::Include(include) = api {\n            let first_component = Path::new(&include.path).components().next();\n            if let Some(Component::CurDir | Component::ParentDir) = first_component {\n                let begin = quote_spanned!(include.begin_span=> .);\n                let end = quote_spanned!(include.end_span=> .);\n                let span = quote!(#begin #end);\n                cx.error(span, error::DOT_INCLUDE.msg);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "gen/src/error.rs",
    "content": "use crate::gen::fs;\nuse crate::syntax;\nuse codespan_reporting::diagnostic::{Diagnostic, Label};\nuse codespan_reporting::files::SimpleFiles;\nuse codespan_reporting::term::termcolor::{ColorChoice, StandardStream};\nuse codespan_reporting::term::{self, Config, WriteStyle};\nuse std::borrow::Cow;\nuse std::error::Error as StdError;\nuse std::fmt::{self, Display};\nuse std::io::{self, Write};\nuse std::ops::Range;\nuse std::path::{Path, PathBuf};\nuse std::process;\nuse std::str::Utf8Error;\n\npub(crate) type Result<T, E = Error> = std::result::Result<T, E>;\n\n#[derive(Debug)]\npub(crate) enum Error {\n    NoBridgeMod,\n    Fs(fs::Error),\n    Utf8(PathBuf, Utf8Error),\n    Syn(syn::Error),\n}\n\nimpl Display for Error {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match self {\n            Error::NoBridgeMod => write!(f, \"no #[cxx::bridge] module found\"),\n            Error::Fs(err) => err.fmt(f),\n            Error::Utf8(path, _) => write!(f, \"Failed to read file `{}`\", path.display()),\n            Error::Syn(err) => err.fmt(f),\n        }\n    }\n}\n\nimpl StdError for Error {\n    fn source(&self) -> Option<&(dyn StdError + 'static)> {\n        match self {\n            Error::Fs(err) => err.source(),\n            Error::Utf8(_, err) => Some(err),\n            Error::Syn(err) => err.source(),\n            Error::NoBridgeMod => None,\n        }\n    }\n}\n\nimpl From<fs::Error> for Error {\n    fn from(err: fs::Error) -> Self {\n        Error::Fs(err)\n    }\n}\n\nimpl From<syn::Error> for Error {\n    fn from(err: syn::Error) -> Self {\n        Error::Syn(err)\n    }\n}\n\npub(super) fn format_err(path: &Path, source: &str, error: Error) -> ! {\n    match error {\n        Error::Syn(syn_error) => {\n            let syn_error = sort_syn_errors(syn_error);\n            let writer = StandardStream::stderr(ColorChoice::Auto);\n            let ref mut stderr = writer.lock();\n            for error in syn_error {\n                let _ = writeln!(stderr);\n                display_syn_error(stderr, path, source, error);\n            }\n        }\n        Error::NoBridgeMod => {\n            let _ = writeln!(\n                io::stderr(),\n                \"cxxbridge: no #[cxx::bridge] module found in {}\",\n                path.display(),\n            );\n        }\n        _ => {\n            let _ = writeln!(io::stderr(), \"cxxbridge: {}\", report(error));\n        }\n    }\n    process::exit(1);\n}\n\npub(crate) fn report(error: impl StdError) -> impl Display {\n    struct Report<E>(E);\n\n    impl<E: StdError> Display for Report<E> {\n        fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n            write!(formatter, \"{}\", self.0)?;\n            let mut error: &dyn StdError = &self.0;\n\n            while let Some(cause) = error.source() {\n                write!(formatter, \"\\n\\nCaused by:\\n    {}\", cause)?;\n                error = cause;\n            }\n\n            Ok(())\n        }\n    }\n\n    Report(error)\n}\n\nfn sort_syn_errors(error: syn::Error) -> Vec<syn::Error> {\n    let mut errors: Vec<_> = error.into_iter().collect();\n    errors.sort_by_key(|e| {\n        let start = e.span().start();\n        (start.line, start.column)\n    });\n    errors\n}\n\nfn display_syn_error(stderr: &mut dyn WriteStyle, path: &Path, source: &str, error: syn::Error) {\n    let span = error.span();\n    let start = span.start();\n    let end = span.end();\n\n    let mut start_offset = 0;\n    for _ in 1..start.line {\n        start_offset += source[start_offset..].find('\\n').unwrap() + 1;\n    }\n    let start_column = source[start_offset..]\n        .chars()\n        .take(start.column)\n        .map(char::len_utf8)\n        .sum::<usize>();\n    start_offset += start_column;\n\n    let mut end_offset = start_offset;\n    if start.line == end.line {\n        end_offset -= start_column;\n    } else {\n        for _ in 0..end.line - start.line {\n            end_offset += source[end_offset..].find('\\n').unwrap() + 1;\n        }\n    }\n    end_offset += source[end_offset..]\n        .chars()\n        .take(end.column)\n        .map(char::len_utf8)\n        .sum::<usize>();\n\n    let mut path = path.to_string_lossy();\n    if path == \"-\" {\n        path = Cow::Borrowed(if cfg!(unix) { \"/dev/stdin\" } else { \"stdin\" });\n    }\n\n    let mut files = SimpleFiles::new();\n    let file = files.add(path, source);\n\n    let diagnostic = diagnose(file, start_offset..end_offset, error);\n\n    let config = Config::default();\n    let _ = term::emit_to_write_style(stderr, &config, &files, &diagnostic);\n}\n\nfn diagnose(file: usize, range: Range<usize>, error: syn::Error) -> Diagnostic<usize> {\n    let message = error.to_string();\n    let info = syntax::error::ERRORS\n        .iter()\n        .find(|e| message.contains(e.msg));\n    let mut diagnostic = Diagnostic::error().with_message(&message);\n    let mut label = Label::primary(file, range);\n    if let Some(info) = info {\n        label.message = info.label.map_or(message, str::to_owned);\n        diagnostic.labels.push(label);\n        diagnostic.notes.extend(info.note.map(str::to_owned));\n    } else {\n        label.message = message;\n        diagnostic.labels.push(label);\n    }\n    diagnostic.code = Some(\"cxxbridge\".to_owned());\n    diagnostic\n}\n"
  },
  {
    "path": "gen/src/file.rs",
    "content": "use crate::syntax::file::Module;\nuse crate::syntax::namespace::Namespace;\nuse syn::parse::discouraged::Speculative;\nuse syn::parse::{Error, Parse, ParseStream, Result};\nuse syn::{braced, Attribute, Ident, Item, Meta, Token, Visibility};\n\npub(crate) struct File {\n    pub modules: Vec<Module>,\n}\n\nimpl Parse for File {\n    fn parse(input: ParseStream) -> Result<Self> {\n        let mut modules = Vec::new();\n        parse(input, &mut modules)?;\n        Ok(File { modules })\n    }\n}\n\nfn parse(input: ParseStream, modules: &mut Vec<Module>) -> Result<()> {\n    input.call(Attribute::parse_inner)?;\n\n    while !input.is_empty() {\n        let mut cxx_bridge = false;\n        let mut namespace = Namespace::ROOT;\n        let mut attrs = input.call(Attribute::parse_outer)?;\n        for attr in &attrs {\n            let path = &attr.path().segments;\n            if path.len() == 2 && path[0].ident == \"cxx\" && path[1].ident == \"bridge\" {\n                cxx_bridge = true;\n                namespace = parse_args(attr)?;\n                break;\n            }\n        }\n\n        let ahead = input.fork();\n        ahead.parse::<Visibility>()?;\n        ahead.parse::<Option<Token![unsafe]>>()?;\n        if !ahead.peek(Token![mod]) {\n            let item: Item = input.parse()?;\n            if cxx_bridge {\n                return Err(Error::new_spanned(item, \"expected a module\"));\n            }\n            continue;\n        }\n\n        if cxx_bridge {\n            let mut module: Module = input.parse()?;\n            module.namespace = namespace;\n            attrs.extend(module.attrs);\n            module.attrs = attrs;\n            modules.push(module);\n        } else {\n            input.advance_to(&ahead);\n            input.parse::<Token![mod]>()?;\n            input.parse::<Ident>()?;\n            let semi: Option<Token![;]> = input.parse()?;\n            if semi.is_none() {\n                let content;\n                braced!(content in input);\n                parse(&content, modules)?;\n            }\n        }\n    }\n\n    Ok(())\n}\n\nfn parse_args(attr: &Attribute) -> Result<Namespace> {\n    if let Meta::Path(_) = attr.meta {\n        Ok(Namespace::ROOT)\n    } else {\n        attr.parse_args_with(Namespace::parse_bridge_attr_namespace)\n    }\n}\n"
  },
  {
    "path": "gen/src/fs.rs",
    "content": "#![allow(dead_code)]\n\nuse std::error::Error as StdError;\nuse std::fmt::{self, Display};\nuse std::io::{self, Read};\nuse std::path::{Path, PathBuf};\n\npub(crate) type Result<T> = std::result::Result<T, Error>;\n\n#[derive(Debug)]\npub(crate) struct Error {\n    source: Option<io::Error>,\n    message: String,\n}\n\nimpl Error {\n    pub(crate) fn kind(&self) -> io::ErrorKind {\n        match &self.source {\n            Some(io_error) => io_error.kind(),\n            None => io::ErrorKind::Other,\n        }\n    }\n}\n\nimpl Display for Error {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        formatter.write_str(&self.message)\n    }\n}\n\nimpl StdError for Error {\n    fn source(&self) -> Option<&(dyn StdError + 'static)> {\n        let source = self.source.as_ref()?;\n        Some(source)\n    }\n}\n\nmacro_rules! err {\n    ($io_error:expr, $fmt:expr $(, $path:expr)* $(,)?) => {\n        Err(Error {\n            source: Option::from($io_error),\n            message: format!($fmt $(, $path.display())*),\n        })\n    }\n}\n\npub(crate) fn copy(from: impl AsRef<Path>, to: impl AsRef<Path>) -> Result<u64> {\n    let from = from.as_ref();\n    let to = to.as_ref();\n    match std::fs::copy(from, to) {\n        Ok(n) => Ok(n),\n        Err(e) => err!(e, \"Failed to copy `{}` -> `{}`\", from, to),\n    }\n}\n\npub(crate) fn create_dir_all(path: impl AsRef<Path>) -> Result<()> {\n    let path = path.as_ref();\n    match std::fs::create_dir_all(path) {\n        Ok(()) => Ok(()),\n        Err(e) => err!(e, \"Failed to create directory `{}`\", path),\n    }\n}\n\npub(crate) fn current_dir() -> Result<PathBuf> {\n    match std::env::current_dir() {\n        Ok(dir) => Ok(dir),\n        Err(e) => err!(e, \"Failed to determine current directory\"),\n    }\n}\n\npub(crate) fn exists(path: impl AsRef<Path>) -> bool {\n    let path = path.as_ref();\n    // If path is a symlink, this returns true, regardless of whether the\n    // symlink points to a path that exists.\n    std::fs::symlink_metadata(path).is_ok()\n}\n\npub(crate) fn read(path: impl AsRef<Path>) -> Result<Vec<u8>> {\n    let path = path.as_ref();\n    match std::fs::read(path) {\n        Ok(string) => Ok(string),\n        Err(e) => err!(e, \"Failed to read file `{}`\", path),\n    }\n}\n\npub(crate) fn read_stdin() -> Result<Vec<u8>> {\n    let mut bytes = Vec::new();\n    match io::stdin().read_to_end(&mut bytes) {\n        Ok(_len) => Ok(bytes),\n        Err(e) => err!(e, \"Failed to read input from stdin\"),\n    }\n}\n\npub(crate) fn remove_file(path: impl AsRef<Path>) -> Result<()> {\n    let path = path.as_ref();\n    match std::fs::remove_file(path) {\n        Ok(()) => Ok(()),\n        Err(e) => err!(e, \"Failed to remove file `{}`\", path),\n    }\n}\n\npub(crate) fn remove_dir(path: impl AsRef<Path>) -> Result<()> {\n    let path = path.as_ref();\n    match std::fs::remove_dir(path) {\n        Ok(()) => Ok(()),\n        Err(e) => err!(e, \"Failed to remove directory `{}`\", path),\n    }\n}\n\nfn symlink<'a>(\n    original: &'a Path,\n    link: &'a Path,\n    fun: fn(&'a Path, &'a Path) -> io::Result<()>,\n) -> Result<()> {\n    match fun(original, link) {\n        Ok(()) => Ok(()),\n        Err(e) => err!(\n            e,\n            \"Failed to create symlink `{}` pointing to `{}`\",\n            link,\n            original,\n        ),\n    }\n}\n\npub(crate) fn symlink_fail(original: impl AsRef<Path>, link: impl AsRef<Path>) -> Result<()> {\n    err!(\n        None,\n        \"Failed to create symlink `{}` pointing to `{}`\",\n        link.as_ref(),\n        original.as_ref(),\n    )\n}\n\n#[cfg(unix)]\n#[allow(unused_imports)]\npub(crate) use self::symlink_file as symlink_dir;\n\n#[cfg(not(any(unix, windows)))]\n#[allow(unused_imports)]\npub(crate) use self::symlink_fail as symlink_dir;\n\n#[cfg(unix)]\npub(crate) fn symlink_file(original: impl AsRef<Path>, link: impl AsRef<Path>) -> Result<()> {\n    symlink(original.as_ref(), link.as_ref(), std::os::unix::fs::symlink)\n}\n\n#[cfg(windows)]\npub(crate) fn symlink_file(original: impl AsRef<Path>, link: impl AsRef<Path>) -> Result<()> {\n    symlink(\n        original.as_ref(),\n        link.as_ref(),\n        std::os::windows::fs::symlink_file,\n    )\n}\n\n#[cfg(windows)]\npub(crate) fn symlink_dir(original: impl AsRef<Path>, link: impl AsRef<Path>) -> Result<()> {\n    symlink(\n        original.as_ref(),\n        link.as_ref(),\n        std::os::windows::fs::symlink_dir,\n    )\n}\n\npub(crate) fn write(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> Result<()> {\n    let path = path.as_ref();\n    match std::fs::write(path, contents) {\n        Ok(()) => Ok(()),\n        Err(e) => err!(e, \"Failed to write file `{}`\", path),\n    }\n}\n"
  },
  {
    "path": "gen/src/guard.rs",
    "content": "use crate::gen::out::OutFile;\nuse crate::syntax::symbol::Symbol;\nuse crate::syntax::Pair;\nuse std::fmt::{self, Display};\n\npub(crate) struct Guard {\n    kind: &'static str,\n    symbol: Symbol,\n}\n\nimpl Guard {\n    pub fn new(out: &mut OutFile, kind: &'static str, name: &Pair) -> Self {\n        let symbol = name.to_symbol();\n        out.pragma.dollar_in_identifier |= symbol.contains('$');\n        Guard { kind, symbol }\n    }\n}\n\nimpl Display for Guard {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        write!(formatter, \"{}_{}\", self.kind, self.symbol)\n    }\n}\n"
  },
  {
    "path": "gen/src/ifndef.rs",
    "content": "use crate::gen::include::HEADER;\nuse crate::gen::out::Content;\n\npub(super) fn write(out: &mut Content, needed: bool, guard: &str) {\n    let ifndef = format!(\"#ifndef {}\", guard);\n    let define = format!(\"#define {}\", guard);\n    let endif = format!(\"#endif // {}\", guard);\n\n    let mut offset = 0;\n    loop {\n        let begin = find_line(offset, &ifndef);\n        let end = find_line(offset, &endif);\n        if let (Some(begin), Some(end)) = (begin, end) {\n            if !needed {\n                return;\n            }\n            out.next_section();\n            if offset == 0 {\n                writeln!(out, \"{}\", ifndef);\n                writeln!(out, \"{}\", define);\n            }\n            for line in HEADER[begin + ifndef.len()..end].trim().lines() {\n                if line != define && !line.trim_start().starts_with(\"//\") {\n                    writeln!(out, \"{}\", line);\n                }\n            }\n            offset = end + endif.len();\n        } else if offset == 0 {\n            panic!(\"not found in cxx.h header: {}\", guard)\n        } else {\n            writeln!(out, \"{}\", endif);\n            return;\n        }\n    }\n}\n\nfn find_line(mut offset: usize, line: &str) -> Option<usize> {\n    loop {\n        offset += HEADER[offset..].find(line)?;\n        let rest = &HEADER[offset + line.len()..];\n        if rest.starts_with('\\n') || rest.starts_with('\\r') {\n            return Some(offset);\n        }\n        offset += line.len();\n    }\n}\n"
  },
  {
    "path": "gen/src/include.rs",
    "content": "use crate::gen::out::{Content, OutFile};\nuse crate::syntax::{self, IncludeKind};\nuse std::ops::{Deref, DerefMut};\n\n/// The complete contents of the \"rust/cxx.h\" header.\npub static HEADER: &str = include_str!(\"include/cxx.h\");\n\n/// A header to #include.\n///\n/// The cxxbridge tool does not parse or even require the given paths to exist;\n/// they simply go into the generated C++ code as #include lines.\n#[derive(Clone, PartialEq, Debug)]\npub struct Include {\n    /// The header's path, not including the enclosing quotation marks or angle\n    /// brackets.\n    pub path: String,\n    /// Whether to emit `#include \"path\"` or `#include <path>`.\n    pub kind: IncludeKind,\n}\n\n#[derive(Default, PartialEq)]\npub(crate) struct Includes<'a> {\n    pub custom: Vec<Include>,\n    pub algorithm: bool,\n    pub array: bool,\n    pub cassert: bool,\n    pub cstddef: bool,\n    pub cstdint: bool,\n    pub cstring: bool,\n    pub exception: bool,\n    pub functional: bool,\n    pub initializer_list: bool,\n    pub iterator: bool,\n    pub limits: bool,\n    pub memory: bool,\n    pub new: bool,\n    pub ranges: bool,\n    pub stdexcept: bool,\n    pub string: bool,\n    pub string_view: bool,\n    pub type_traits: bool,\n    pub utility: bool,\n    pub vector: bool,\n    pub basetsd: bool,\n    pub sys_types: bool,\n    pub content: Content<'a>,\n}\n\nimpl<'a> Includes<'a> {\n    pub(crate) fn new() -> Self {\n        Includes::default()\n    }\n\n    pub(crate) fn insert(&mut self, include: impl Into<Include>) {\n        self.custom.push(include.into());\n    }\n\n    pub(crate) fn has_cxx_header(&self) -> bool {\n        self.custom\n            .iter()\n            .any(|header| header.path == \"rust/cxx.h\" || header.path == \"rust\\\\cxx.h\")\n    }\n}\n\npub(super) fn write(out: &mut OutFile) {\n    let header = out.header;\n    let include = &mut out.include;\n    let cxx_header = include.has_cxx_header();\n    let out = &mut include.content;\n\n    if header {\n        writeln!(out, \"#pragma once\");\n    }\n\n    for include in &include.custom {\n        match include.kind {\n            IncludeKind::Quoted => {\n                writeln!(out, \"#include \\\"{}\\\"\", include.path.escape_default());\n            }\n            IncludeKind::Bracketed => {\n                writeln!(out, \"#include <{}>\", include.path);\n            }\n        }\n    }\n\n    let Includes {\n        custom: _,\n        algorithm,\n        array,\n        cassert,\n        cstddef,\n        cstdint,\n        cstring,\n        exception,\n        functional,\n        initializer_list,\n        iterator,\n        limits,\n        memory,\n        new,\n        ranges,\n        stdexcept,\n        string,\n        string_view,\n        type_traits,\n        utility,\n        vector,\n        basetsd,\n        sys_types,\n        content: _,\n    } = *include;\n\n    if algorithm && !cxx_header {\n        writeln!(out, \"#include <algorithm>\");\n    }\n    if array && !cxx_header {\n        writeln!(out, \"#include <array>\");\n    }\n    if cassert && !cxx_header {\n        writeln!(out, \"#include <cassert>\");\n    }\n    if cstddef && !cxx_header {\n        writeln!(out, \"#include <cstddef>\");\n    }\n    if cstdint && !cxx_header {\n        writeln!(out, \"#include <cstdint>\");\n    }\n    if cstring {\n        writeln!(out, \"#include <cstring>\");\n    }\n    if exception && !cxx_header {\n        writeln!(out, \"#include <exception>\");\n    }\n    if functional {\n        writeln!(out, \"#include <functional>\");\n    }\n    if initializer_list && !cxx_header {\n        writeln!(out, \"#include <initializer_list>\");\n    }\n    if iterator && !cxx_header {\n        writeln!(out, \"#include <iterator>\");\n    }\n    if limits {\n        writeln!(out, \"#include <limits>\");\n    }\n    if memory {\n        writeln!(out, \"#include <memory>\");\n    }\n    if new && !cxx_header {\n        writeln!(out, \"#include <new>\");\n    }\n    if stdexcept && !cxx_header {\n        writeln!(out, \"#include <stdexcept>\");\n    }\n    if string && !cxx_header {\n        writeln!(out, \"#include <string>\");\n    }\n    if type_traits && !cxx_header {\n        writeln!(out, \"#include <type_traits>\");\n    }\n    if utility && !cxx_header {\n        writeln!(out, \"#include <utility>\");\n    }\n    if vector && !cxx_header {\n        writeln!(out, \"#include <vector>\");\n    }\n    if basetsd && !cxx_header {\n        writeln!(out, \"#if defined(_WIN32)\");\n        writeln!(out, \"#include <basetsd.h>\");\n    }\n    if sys_types && !cxx_header {\n        if basetsd {\n            writeln!(out, \"#else\");\n        } else {\n            writeln!(out, \"#if not defined(_WIN32)\");\n        }\n    }\n    if sys_types && !cxx_header {\n        writeln!(out, \"#include <sys/types.h>\");\n    }\n    if (basetsd || sys_types) && !cxx_header {\n        writeln!(out, \"#endif\");\n    }\n    if string_view && !cxx_header {\n        writeln!(out, \"#if __cplusplus >= 201703L\");\n        writeln!(out, \"#include <string_view>\");\n        writeln!(out, \"#endif\");\n    }\n    if ranges && !cxx_header {\n        writeln!(out, \"#if __cplusplus >= 202002L\");\n        writeln!(out, \"#include <ranges>\");\n        writeln!(out, \"#endif\");\n    }\n}\n\nimpl<'i, 'a> Extend<&'i Include> for Includes<'a> {\n    fn extend<I: IntoIterator<Item = &'i Include>>(&mut self, iter: I) {\n        self.custom.extend(iter.into_iter().cloned());\n    }\n}\n\nimpl From<&syntax::Include> for Include {\n    fn from(include: &syntax::Include) -> Self {\n        Include {\n            path: include.path.clone(),\n            kind: include.kind,\n        }\n    }\n}\n\nimpl<'a> Deref for Includes<'a> {\n    type Target = Content<'a>;\n\n    fn deref(&self) -> &Self::Target {\n        &self.content\n    }\n}\n\nimpl<'a> DerefMut for Includes<'a> {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.content\n    }\n}\n"
  },
  {
    "path": "gen/src/mod.rs",
    "content": "// Functionality that is shared between the cxx_build::bridge entry point and\n// the cxxbridge CLI command.\n\nmod block;\nmod builtin;\nmod cfg;\nmod check;\npub(super) mod error;\nmod file;\npub(super) mod fs;\nmod guard;\nmod ifndef;\npub(super) mod include;\nmod names;\nmod namespace;\nmod nested;\npub(super) mod out;\nmod pragma;\nmod write;\n\nuse self::cfg::UnsupportedCfgEvaluator;\nuse self::error::{format_err, Result};\nuse self::file::File;\nuse self::include::Include;\nuse crate::syntax::cfg::CfgExpr;\nuse crate::syntax::report::Errors;\nuse crate::syntax::{self, attrs, Types};\nuse std::collections::BTreeSet as Set;\nuse std::path::Path;\n\npub(super) use self::error::Error;\n\n/// Options for C++ code generation.\n///\n/// We expect options to be added over time, so this is a non-exhaustive struct.\n/// To instantiate one you need to crate a default value and mutate those fields\n/// that you want to modify.\n///\n/// ```\n/// # use cxx_gen::Opt;\n/// #\n/// let impl_annotations = r#\"__attribute__((visibility(\"default\")))\"#.to_owned();\n///\n/// let mut opt = Opt::default();\n/// opt.cxx_impl_annotations = Some(impl_annotations);\n/// ```\n#[non_exhaustive]\npub struct Opt {\n    /// Any additional headers to #include. The cxxbridge tool does not parse or\n    /// even require the given paths to exist; they simply go into the generated\n    /// C++ code as #include lines.\n    pub include: Vec<Include>,\n    /// Optional annotation for implementations of C++ function wrappers that\n    /// may be exposed to Rust. You may for example need to provide\n    /// `__declspec(dllexport)` or `__attribute__((visibility(\"default\")))` if\n    /// Rust code from one shared object or executable depends on these C++\n    /// functions in another.\n    pub cxx_impl_annotations: Option<String>,\n    /// Impl for handling conditional compilation attributes.\n    pub cfg_evaluator: Box<dyn CfgEvaluator>,\n\n    pub(super) gen_header: bool,\n    pub(super) gen_implementation: bool,\n    pub(super) allow_dot_includes: bool,\n    pub(super) doxygen: bool,\n}\n\n/// Logic to decide whether a conditional compilation attribute is enabled or\n/// disabled.\npub trait CfgEvaluator {\n    /// A name-only attribute such as `cfg(ident)` is passed with a `value` of\n    /// None, while `cfg(key = \"value\")` is passed with the \"value\" in `value`.\n    fn eval(&self, name: &str, value: Option<&str>) -> CfgResult;\n}\n\n/// Result of a [`CfgEvaluator`] evaluation.\npub enum CfgResult {\n    /// Cfg option is enabled.\n    True,\n    /// Cfg option is disabled.\n    False,\n    /// Cfg option is neither enabled nor disabled.\n    Undetermined {\n        /// Message explaining why the cfg option is undetermined.\n        msg: String,\n    },\n}\n\n/// Results of code generation.\n#[derive(Default)]\npub struct GeneratedCode {\n    /// The bytes of a C++ header file.\n    pub header: Vec<u8>,\n    /// The bytes of a C++ implementation file (e.g. .cc, cpp etc.)\n    pub implementation: Vec<u8>,\n}\n\nimpl Default for Opt {\n    fn default() -> Self {\n        Opt {\n            include: Vec::new(),\n            cxx_impl_annotations: None,\n            gen_header: true,\n            gen_implementation: true,\n            allow_dot_includes: true,\n            cfg_evaluator: Box::new(UnsupportedCfgEvaluator),\n            doxygen: false,\n        }\n    }\n}\n\npub(super) fn generate_from_path(path: &Path, opt: &Opt) -> GeneratedCode {\n    let source = match read_to_string(path) {\n        Ok(source) => source,\n        Err(err) => format_err(path, \"\", err),\n    };\n    match generate_from_string(&source, opt) {\n        Ok(out) => out,\n        Err(err) => format_err(path, &source, err),\n    }\n}\n\nfn read_to_string(path: &Path) -> Result<String> {\n    let bytes = if path == Path::new(\"-\") {\n        fs::read_stdin()\n    } else {\n        fs::read(path)\n    }?;\n    match String::from_utf8(bytes) {\n        Ok(string) => Ok(string),\n        Err(err) => Err(Error::Utf8(path.to_owned(), err.utf8_error())),\n    }\n}\n\nfn generate_from_string(source: &str, opt: &Opt) -> Result<GeneratedCode> {\n    let mut source = source;\n    if source.starts_with(\"#!\") && !source.starts_with(\"#![\") {\n        let shebang_end = source.find('\\n').unwrap_or(source.len());\n        source = &source[shebang_end..];\n    }\n    let syntax: File = syn::parse_str(source)?;\n    generate(syntax, opt)\n}\n\npub(super) fn generate(syntax: File, opt: &Opt) -> Result<GeneratedCode> {\n    if syntax.modules.is_empty() {\n        return Err(Error::NoBridgeMod);\n    }\n\n    let ref mut apis = Vec::new();\n    let ref mut errors = Errors::new();\n    let ref mut cfg_errors = Set::new();\n    for bridge in syntax.modules {\n        let mut cfg = CfgExpr::Unconditional;\n        let _ = attrs::parse(\n            errors,\n            bridge.attrs,\n            attrs::Parser {\n                cfg: Some(&mut cfg),\n                ignore_unrecognized: true,\n                ..Default::default()\n            },\n        );\n        if cfg::eval(errors, cfg_errors, opt.cfg_evaluator.as_ref(), &cfg) {\n            let ref namespace = bridge.namespace;\n            let trusted = bridge.unsafety.is_some();\n            apis.extend(syntax::parse_items(\n                errors,\n                bridge.content,\n                trusted,\n                namespace,\n            ));\n        }\n    }\n\n    cfg::strip(errors, cfg_errors, opt.cfg_evaluator.as_ref(), apis);\n    errors.propagate()?;\n\n    let ref types = Types::collect(errors, apis);\n    check::precheck(errors, apis, opt);\n    errors.propagate()?;\n\n    let generator = check::Generator::Build;\n    check::typecheck(errors, apis, types, generator);\n    errors.propagate()?;\n\n    // Some callers may wish to generate both header and implementation from the\n    // same token stream to avoid parsing twice. Others only need to generate\n    // one or the other.\n    let (mut header, mut implementation) = Default::default();\n    if opt.gen_header {\n        header = write::gen(apis, types, opt, true);\n    }\n    if opt.gen_implementation {\n        implementation = write::gen(apis, types, opt, false);\n    }\n    Ok(GeneratedCode {\n        header,\n        implementation,\n    })\n}\n"
  },
  {
    "path": "gen/src/names.rs",
    "content": "use crate::syntax::Pair;\n\nimpl Pair {\n    pub(crate) fn to_fully_qualified(&self) -> String {\n        let mut fully_qualified = String::new();\n        for segment in &self.namespace {\n            fully_qualified += \"::\";\n            fully_qualified += &segment.to_string();\n        }\n        fully_qualified += \"::\";\n        fully_qualified += &self.cxx.to_string();\n        fully_qualified\n    }\n}\n"
  },
  {
    "path": "gen/src/namespace.rs",
    "content": "use crate::syntax::namespace::Namespace;\nuse crate::syntax::Api;\n\nimpl Api {\n    pub(crate) fn namespace(&self) -> &Namespace {\n        match self {\n            Api::CxxFunction(efn) | Api::RustFunction(efn) => &efn.name.namespace,\n            Api::CxxType(ety) | Api::RustType(ety) => &ety.name.namespace,\n            Api::Enum(enm) => &enm.name.namespace,\n            Api::Struct(strct) => &strct.name.namespace,\n            Api::Impl(_) | Api::Include(_) | Api::TypeAlias(_) => Default::default(),\n        }\n    }\n}\n"
  },
  {
    "path": "gen/src/nested.rs",
    "content": "use crate::syntax::map::UnorderedMap as Map;\nuse crate::syntax::Api;\nuse proc_macro2::Ident;\n\npub(crate) struct NamespaceEntries<'a> {\n    direct: Vec<&'a Api>,\n    nested: Vec<(&'a Ident, NamespaceEntries<'a>)>,\n}\n\nimpl<'a> NamespaceEntries<'a> {\n    pub(crate) fn new(apis: Vec<&'a Api>) -> Self {\n        sort_by_inner_namespace(apis, 0)\n    }\n\n    pub(crate) fn direct_content(&self) -> &[&'a Api] {\n        &self.direct\n    }\n\n    pub(crate) fn nested_content(\n        &self,\n    ) -> impl Iterator<Item = (&'a Ident, &NamespaceEntries<'a>)> {\n        self.nested.iter().map(|(k, entries)| (*k, entries))\n    }\n}\n\nfn sort_by_inner_namespace(apis: Vec<&Api>, depth: usize) -> NamespaceEntries {\n    let mut direct = Vec::new();\n    let mut nested_namespaces = Vec::new();\n    let mut index_of_namespace = Map::new();\n\n    for api in &apis {\n        if let Some(first_ns_elem) = api.namespace().iter().nth(depth) {\n            match index_of_namespace.get(first_ns_elem) {\n                None => {\n                    index_of_namespace.insert(first_ns_elem, nested_namespaces.len());\n                    nested_namespaces.push((first_ns_elem, vec![*api]));\n                }\n                Some(&index) => nested_namespaces[index].1.push(*api),\n            }\n            continue;\n        }\n        direct.push(*api);\n    }\n\n    let nested = nested_namespaces\n        .into_iter()\n        .map(|(k, apis)| (k, sort_by_inner_namespace(apis, depth + 1)))\n        .collect();\n\n    NamespaceEntries { direct, nested }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::NamespaceEntries;\n    use crate::syntax::attrs::OtherAttrs;\n    use crate::syntax::cfg::CfgExpr;\n    use crate::syntax::namespace::Namespace;\n    use crate::syntax::{Api, Doc, ExternType, ForeignName, Lang, Lifetimes, Pair};\n    use proc_macro2::{Ident, Span};\n    use syn::punctuated::Punctuated;\n    use syn::Token;\n\n    #[test]\n    fn test_ns_entries_sort() {\n        let apis = &[\n            make_api(None, \"C\"),\n            make_api(None, \"A\"),\n            make_api(Some(\"G\"), \"E\"),\n            make_api(Some(\"D\"), \"F\"),\n            make_api(Some(\"G\"), \"H\"),\n            make_api(Some(\"D::K\"), \"L\"),\n            make_api(Some(\"D::K\"), \"M\"),\n            make_api(None, \"B\"),\n            make_api(Some(\"D\"), \"I\"),\n            make_api(Some(\"D\"), \"J\"),\n        ];\n\n        let root = NamespaceEntries::new(Vec::from_iter(apis));\n\n        // ::\n        let root_direct = root.direct_content();\n        assert_eq!(root_direct.len(), 3);\n        assert_ident(root_direct[0], \"C\");\n        assert_ident(root_direct[1], \"A\");\n        assert_ident(root_direct[2], \"B\");\n\n        let mut root_nested = root.nested_content();\n        let (id, g) = root_nested.next().unwrap();\n        assert_eq!(id, \"G\");\n        let (id, d) = root_nested.next().unwrap();\n        assert_eq!(id, \"D\");\n        assert!(root_nested.next().is_none());\n\n        // ::G\n        let g_direct = g.direct_content();\n        assert_eq!(g_direct.len(), 2);\n        assert_ident(g_direct[0], \"E\");\n        assert_ident(g_direct[1], \"H\");\n\n        let mut g_nested = g.nested_content();\n        assert!(g_nested.next().is_none());\n\n        // ::D\n        let d_direct = d.direct_content();\n        assert_eq!(d_direct.len(), 3);\n        assert_ident(d_direct[0], \"F\");\n        assert_ident(d_direct[1], \"I\");\n        assert_ident(d_direct[2], \"J\");\n\n        let mut d_nested = d.nested_content();\n        let (id, k) = d_nested.next().unwrap();\n        assert_eq!(id, \"K\");\n\n        // ::D::K\n        let k_direct = k.direct_content();\n        assert_eq!(k_direct.len(), 2);\n        assert_ident(k_direct[0], \"L\");\n        assert_ident(k_direct[1], \"M\");\n    }\n\n    fn assert_ident(api: &Api, expected: &str) {\n        if let Api::CxxType(cxx_type) = api {\n            assert_eq!(cxx_type.name.cxx.to_string(), expected);\n        } else {\n            unreachable!()\n        }\n    }\n\n    fn make_api(ns: Option<&str>, ident: &str) -> Api {\n        let ns = ns.map_or(Namespace::ROOT, |ns| syn::parse_str(ns).unwrap());\n        Api::CxxType(ExternType {\n            cfg: CfgExpr::Unconditional,\n            lang: Lang::Rust,\n            doc: Doc::new(),\n            derives: Vec::new(),\n            attrs: OtherAttrs::new(),\n            visibility: Token![pub](Span::call_site()),\n            type_token: Token![type](Span::call_site()),\n            name: Pair {\n                namespace: ns,\n                cxx: ForeignName::parse(ident, Span::call_site()).unwrap(),\n                rust: Ident::new(ident, Span::call_site()),\n            },\n            generics: Lifetimes {\n                lt_token: None,\n                lifetimes: Punctuated::new(),\n                gt_token: None,\n            },\n            colon_token: None,\n            bounds: Vec::new(),\n            semi_token: Token![;](Span::call_site()),\n            trusted: false,\n        })\n    }\n}\n"
  },
  {
    "path": "gen/src/out.rs",
    "content": "use crate::gen::block::Block;\nuse crate::gen::builtin::Builtins;\nuse crate::gen::include::Includes;\nuse crate::gen::pragma::Pragma;\nuse crate::gen::Opt;\nuse crate::syntax::namespace::Namespace;\nuse crate::syntax::Types;\nuse std::cell::RefCell;\nuse std::fmt::{self, Arguments, Write};\n\npub(crate) struct OutFile<'a> {\n    pub header: bool,\n    pub opt: &'a Opt,\n    pub types: &'a Types<'a>,\n    pub include: Includes<'a>,\n    pub pragma: Pragma<'a>,\n    pub builtin: Builtins<'a>,\n    content: RefCell<Content<'a>>,\n}\n\n#[derive(Default)]\npub(crate) struct Content<'a> {\n    bytes: String,\n    namespace: &'a Namespace,\n    blocks: Vec<BlockBoundary<'a>>,\n    suppress_next_section: bool,\n    section_pending: bool,\n    blocks_pending: usize,\n}\n\n#[derive(Copy, Clone, PartialEq, Debug)]\nenum BlockBoundary<'a> {\n    Begin(Block<'a>),\n    End(Block<'a>),\n}\n\nimpl<'a> OutFile<'a> {\n    pub(crate) fn new(header: bool, opt: &'a Opt, types: &'a Types) -> Self {\n        OutFile {\n            header,\n            opt,\n            types,\n            include: Includes::new(),\n            pragma: Pragma::new(),\n            builtin: Builtins::new(),\n            content: RefCell::new(Content::new()),\n        }\n    }\n\n    // Write a blank line if the preceding section had any contents.\n    pub(crate) fn next_section(&mut self) {\n        self.content.get_mut().next_section();\n    }\n\n    pub(crate) fn suppress_next_section(&mut self) {\n        self.content.get_mut().suppress_next_section();\n    }\n\n    pub(crate) fn begin_block(&mut self, block: Block<'a>) {\n        self.content.get_mut().begin_block(block);\n    }\n\n    pub(crate) fn end_block(&mut self, block: Block<'a>) {\n        self.content.get_mut().end_block(block);\n    }\n\n    pub(crate) fn set_namespace(&mut self, namespace: &'a Namespace) {\n        self.content.get_mut().set_namespace(namespace);\n    }\n\n    pub(crate) fn content(&mut self) -> Vec<u8> {\n        self.flush();\n\n        let include = &self.include.content.bytes;\n        let pragma_begin = &self.pragma.begin.bytes;\n        let builtin = &self.builtin.content.bytes;\n        let content = &self.content.get_mut().bytes;\n        let pragma_end = &self.pragma.end.bytes;\n\n        let mut out = String::new();\n        out.push_str(include);\n        if !out.is_empty() && !pragma_begin.is_empty() {\n            out.push('\\n');\n        }\n        out.push_str(pragma_begin);\n        if !out.is_empty() && !builtin.is_empty() {\n            out.push('\\n');\n        }\n        out.push_str(builtin);\n        if !out.is_empty() && !content.is_empty() {\n            out.push('\\n');\n        }\n        out.push_str(content);\n        if !out.is_empty() && !pragma_end.is_empty() {\n            out.push('\\n');\n        }\n        out.push_str(pragma_end);\n        if out.is_empty() {\n            out.push_str(\"// empty\\n\");\n        }\n        out.into_bytes()\n    }\n\n    fn flush(&mut self) {\n        self.include.content.flush();\n        self.pragma.begin.flush();\n        self.builtin.content.flush();\n        self.content.get_mut().flush();\n        self.pragma.end.flush();\n    }\n}\n\nimpl<'a> Write for Content<'a> {\n    fn write_str(&mut self, s: &str) -> fmt::Result {\n        self.write(s);\n        Ok(())\n    }\n}\n\nimpl<'a> PartialEq for Content<'a> {\n    fn eq(&self, _other: &Self) -> bool {\n        true\n    }\n}\n\nimpl<'a> Content<'a> {\n    pub(crate) fn new() -> Self {\n        Content::default()\n    }\n\n    pub(crate) fn next_section(&mut self) {\n        self.section_pending = !self.suppress_next_section;\n    }\n\n    pub(crate) fn suppress_next_section(&mut self) {\n        self.suppress_next_section = true;\n    }\n\n    pub(crate) fn begin_block(&mut self, block: Block<'a>) {\n        self.push_block_boundary(BlockBoundary::Begin(block));\n    }\n\n    pub(crate) fn end_block(&mut self, block: Block<'a>) {\n        self.push_block_boundary(BlockBoundary::End(block));\n    }\n\n    pub(crate) fn set_namespace(&mut self, namespace: &'a Namespace) {\n        for name in self.namespace.iter().rev() {\n            self.end_block(Block::UserDefinedNamespace(name));\n        }\n        for name in namespace {\n            self.begin_block(Block::UserDefinedNamespace(name));\n        }\n        self.namespace = namespace;\n    }\n\n    pub(crate) fn write_fmt(&mut self, args: Arguments) {\n        Write::write_fmt(self, args).unwrap();\n    }\n\n    fn write(&mut self, b: &str) {\n        if !b.is_empty() {\n            if self.blocks_pending > 0 {\n                self.flush_blocks();\n            }\n            if self.section_pending && !self.bytes.is_empty() {\n                self.bytes.push('\\n');\n            }\n            self.bytes.push_str(b);\n            self.suppress_next_section = false;\n            self.section_pending = false;\n            self.blocks_pending = 0;\n        }\n    }\n\n    fn push_block_boundary(&mut self, boundary: BlockBoundary<'a>) {\n        if self.blocks_pending > 0 && boundary == self.blocks.last().unwrap().rev() {\n            self.blocks.pop();\n            self.blocks_pending -= 1;\n        } else {\n            self.blocks.push(boundary);\n            self.blocks_pending += 1;\n        }\n    }\n\n    fn flush(&mut self) {\n        self.set_namespace(Default::default());\n        if self.blocks_pending > 0 {\n            self.flush_blocks();\n        }\n    }\n\n    fn flush_blocks(&mut self) {\n        self.section_pending = !self.bytes.is_empty();\n        let mut read = self.blocks.len() - self.blocks_pending;\n        let mut write = read;\n\n        while read < self.blocks.len() {\n            match self.blocks[read] {\n                BlockBoundary::Begin(begin_block) => {\n                    if self.section_pending {\n                        self.bytes.push('\\n');\n                        self.section_pending = false;\n                    }\n                    Block::write_begin(begin_block, &mut self.bytes);\n                    self.blocks[write] = BlockBoundary::Begin(begin_block);\n                    write += 1;\n                }\n                BlockBoundary::End(end_block) => {\n                    write = write.checked_sub(1).unwrap();\n                    let begin_block = self.blocks[write];\n                    assert_eq!(begin_block, BlockBoundary::Begin(end_block));\n                    Block::write_end(end_block, &mut self.bytes);\n                    self.section_pending = true;\n                }\n            }\n            read += 1;\n        }\n\n        self.blocks.truncate(write);\n    }\n}\n\nimpl<'a> BlockBoundary<'a> {\n    fn rev(self) -> BlockBoundary<'a> {\n        match self {\n            BlockBoundary::Begin(block) => BlockBoundary::End(block),\n            BlockBoundary::End(block) => BlockBoundary::Begin(block),\n        }\n    }\n}\n\npub(crate) trait InfallibleWrite {\n    fn write_fmt(&mut self, args: Arguments);\n}\n\nimpl InfallibleWrite for String {\n    fn write_fmt(&mut self, args: Arguments) {\n        Write::write_fmt(self, args).unwrap();\n    }\n}\n\nimpl<'a> InfallibleWrite for Content<'a> {\n    fn write_fmt(&mut self, args: Arguments) {\n        Write::write_fmt(self, args).unwrap();\n    }\n}\n\nimpl<'a> InfallibleWrite for OutFile<'a> {\n    fn write_fmt(&mut self, args: Arguments) {\n        InfallibleWrite::write_fmt(self.content.get_mut(), args);\n    }\n}\n"
  },
  {
    "path": "gen/src/pragma.rs",
    "content": "use crate::gen::out::{Content, OutFile};\nuse std::collections::BTreeSet;\n\n#[derive(Default)]\npub(crate) struct Pragma<'a> {\n    pub gnu_diagnostic_ignore: BTreeSet<&'a str>,\n    pub clang_diagnostic_ignore: BTreeSet<&'a str>,\n    pub dollar_in_identifier: bool,\n    pub mismatched_new_delete: bool,\n    pub missing_declarations: bool,\n    pub return_type_c_linkage: bool,\n    pub begin: Content<'a>,\n    pub end: Content<'a>,\n}\n\nimpl<'a> Pragma<'a> {\n    pub fn new() -> Self {\n        Pragma::default()\n    }\n}\n\npub(super) fn write(out: &mut OutFile) {\n    let Pragma {\n        ref mut gnu_diagnostic_ignore,\n        ref mut clang_diagnostic_ignore,\n        dollar_in_identifier,\n        mismatched_new_delete,\n        missing_declarations,\n        return_type_c_linkage,\n        ref mut begin,\n        ref mut end,\n    } = out.pragma;\n\n    if dollar_in_identifier {\n        clang_diagnostic_ignore.insert(\"-Wdollar-in-identifier-extension\");\n    }\n    if mismatched_new_delete {\n        gnu_diagnostic_ignore.insert(\"-Wmismatched-new-delete\");\n    }\n    if missing_declarations {\n        gnu_diagnostic_ignore.insert(\"-Wmissing-declarations\");\n    }\n    if return_type_c_linkage {\n        clang_diagnostic_ignore.insert(\"-Wreturn-type-c-linkage\");\n    }\n    let gnu_diagnostic_ignore = &*gnu_diagnostic_ignore;\n    let clang_diagnostic_ignore = &*clang_diagnostic_ignore;\n\n    if !gnu_diagnostic_ignore.is_empty() {\n        writeln!(begin, \"#ifdef __GNUC__\");\n        if out.header {\n            writeln!(begin, \"#pragma GCC diagnostic push\");\n        }\n        for diag in gnu_diagnostic_ignore {\n            writeln!(begin, \"#pragma GCC diagnostic ignored \\\"{diag}\\\"\");\n        }\n    }\n    if !clang_diagnostic_ignore.is_empty() {\n        writeln!(begin, \"#ifdef __clang__\");\n        if out.header && gnu_diagnostic_ignore.is_empty() {\n            writeln!(begin, \"#pragma clang diagnostic push\");\n        }\n        for diag in clang_diagnostic_ignore {\n            writeln!(begin, \"#pragma clang diagnostic ignored \\\"{diag}\\\"\");\n        }\n        writeln!(begin, \"#endif // __clang__\");\n    }\n    if !gnu_diagnostic_ignore.is_empty() {\n        writeln!(begin, \"#endif // __GNUC__\");\n    }\n\n    if out.header {\n        if !gnu_diagnostic_ignore.is_empty() {\n            writeln!(end, \"#ifdef __GNUC__\");\n            writeln!(end, \"#pragma GCC diagnostic pop\");\n            writeln!(end, \"#endif // __GNUC__\");\n        } else if !clang_diagnostic_ignore.is_empty() {\n            writeln!(end, \"#ifdef __clang__\");\n            writeln!(end, \"#pragma clang diagnostic pop\");\n            writeln!(end, \"#endif // __clang__\");\n        }\n    }\n}\n"
  },
  {
    "path": "gen/src/write.rs",
    "content": "use crate::gen::block::Block;\nuse crate::gen::guard::Guard;\nuse crate::gen::nested::NamespaceEntries;\nuse crate::gen::out::{InfallibleWrite, OutFile};\nuse crate::gen::{builtin, include, pragma, Opt};\nuse crate::syntax::atom::Atom::{self, *};\nuse crate::syntax::discriminant::{Discriminant, Limits};\nuse crate::syntax::instantiate::{ImplKey, NamedImplKey};\nuse crate::syntax::map::UnorderedMap as Map;\nuse crate::syntax::namespace::Namespace;\nuse crate::syntax::primitive::{self, PrimitiveKind};\nuse crate::syntax::set::UnorderedSet;\nuse crate::syntax::symbol::Symbol;\nuse crate::syntax::trivial::{self, TrivialReason};\nuse crate::syntax::{\n    derive, mangle, Api, Doc, Enum, ExternFn, ExternType, FnKind, Lang, Pair, Signature, Struct,\n    Trait, Type, TypeAlias, Types, Var,\n};\n\npub(super) fn gen(apis: &[Api], types: &Types, opt: &Opt, header: bool) -> Vec<u8> {\n    let mut out_file = OutFile::new(header, opt, types);\n    let out = &mut out_file;\n\n    pick_includes_and_builtins(out, apis);\n    out.include.extend(&opt.include);\n\n    write_macros(out, apis);\n    write_forward_declarations(out, apis);\n    write_data_structures(out, apis);\n    write_functions(out, apis);\n    write_generic_instantiations(out);\n\n    builtin::write(out);\n    pragma::write(out);\n    include::write(out);\n\n    out_file.content()\n}\n\nfn write_macros(out: &mut OutFile, apis: &[Api]) {\n    let mut needs_default_value = false;\n    for api in apis {\n        if let Api::Struct(strct) = api {\n            if !out.types.cxx.contains(&strct.name.rust) {\n                for field in &strct.fields {\n                    needs_default_value |= primitive::kind(&field.ty).is_some();\n                }\n            }\n        }\n    }\n\n    if needs_default_value {\n        out.next_section();\n        writeln!(out, \"#if __cplusplus >= 201402L\");\n        writeln!(out, \"#define CXX_DEFAULT_VALUE(value) = value\");\n        writeln!(out, \"#else\");\n        writeln!(out, \"#define CXX_DEFAULT_VALUE(value)\");\n        writeln!(out, \"#endif\");\n    }\n}\n\nfn write_forward_declarations(out: &mut OutFile, apis: &[Api]) {\n    let needs_forward_declaration = |api: &&Api| match api {\n        Api::Struct(_) | Api::CxxType(_) | Api::RustType(_) => true,\n        Api::Enum(enm) => !out.types.cxx.contains(&enm.name.rust),\n        _ => false,\n    };\n\n    let apis_by_namespace =\n        NamespaceEntries::new(apis.iter().filter(needs_forward_declaration).collect());\n\n    out.next_section();\n    write(out, &apis_by_namespace, 0);\n\n    fn write(out: &mut OutFile, ns_entries: &NamespaceEntries, indent: usize) {\n        let apis = ns_entries.direct_content();\n\n        for api in apis {\n            write!(out, \"{:1$}\", \"\", indent);\n            match api {\n                Api::Struct(strct) => write_struct_decl(out, &strct.name),\n                Api::Enum(enm) => write_enum_decl(out, enm),\n                Api::CxxType(ety) => write_struct_using(out, &ety.name),\n                Api::RustType(ety) => write_struct_decl(out, &ety.name),\n                _ => unreachable!(),\n            }\n        }\n\n        for (namespace, nested_ns_entries) in ns_entries.nested_content() {\n            writeln!(out, \"{:2$}namespace {} {{\", \"\", namespace, indent);\n            write(out, nested_ns_entries, indent + 2);\n            writeln!(out, \"{:1$}}}\", \"\", indent);\n        }\n    }\n}\n\nfn write_data_structures<'a>(out: &mut OutFile<'a>, apis: &'a [Api]) {\n    let mut methods_for_type = Map::new();\n    for api in apis {\n        if let Api::CxxFunction(efn) | Api::RustFunction(efn) = api {\n            if let Some(self_type) = efn.self_type() {\n                methods_for_type\n                    .entry(self_type)\n                    .or_insert_with(Vec::new)\n                    .push(efn);\n            }\n        }\n    }\n\n    let mut structs_written = UnorderedSet::new();\n    let mut toposorted_structs = out.types.toposorted_structs.iter();\n    for api in apis {\n        match api {\n            Api::Struct(strct) if !structs_written.contains(&strct.name.rust) => {\n                for next in &mut toposorted_structs {\n                    if !out.types.cxx.contains(&next.name.rust) {\n                        out.next_section();\n                        let methods = methods_for_type\n                            .get(&next.name.rust)\n                            .map(Vec::as_slice)\n                            .unwrap_or_default();\n                        write_struct(out, next, methods);\n                    }\n                    structs_written.insert(&next.name.rust);\n                    if next.name.rust == strct.name.rust {\n                        break;\n                    }\n                }\n            }\n            Api::Enum(enm) => {\n                out.next_section();\n                if out.types.cxx.contains(&enm.name.rust) {\n                    check_enum(out, enm);\n                } else {\n                    write_enum(out, enm);\n                }\n            }\n            Api::RustType(ety) => {\n                out.next_section();\n                let methods = methods_for_type\n                    .get(&ety.name.rust)\n                    .map(Vec::as_slice)\n                    .unwrap_or_default();\n                write_opaque_type(out, ety, methods);\n            }\n            _ => {}\n        }\n    }\n\n    if out.header {\n        return;\n    }\n\n    out.set_namespace(Default::default());\n\n    out.next_section();\n    for api in apis {\n        if let Api::TypeAlias(ety) = api {\n            if let Some(reasons) = out.types.required_trivial.get(&ety.name.rust) {\n                check_trivial_extern_type(out, ety, reasons);\n            }\n        }\n    }\n}\n\nfn write_functions<'a>(out: &mut OutFile<'a>, apis: &'a [Api]) {\n    if !out.header {\n        for api in apis {\n            match api {\n                Api::Struct(strct) => write_struct_operator_decls(out, strct),\n                Api::RustType(ety) => write_opaque_type_layout_decls(out, ety),\n                Api::CxxFunction(efn) => write_cxx_function_shim(out, efn),\n                Api::RustFunction(efn) => write_rust_function_decl(out, efn),\n                _ => {}\n            }\n        }\n\n        write_std_specializations(out, apis);\n    }\n\n    for api in apis {\n        match api {\n            Api::Struct(strct) => write_struct_operators(out, strct),\n            Api::RustType(ety) => write_opaque_type_layout(out, ety),\n            Api::RustFunction(efn) => {\n                out.next_section();\n                write_rust_function_shim(out, efn);\n            }\n            _ => {}\n        }\n    }\n}\n\nfn write_std_specializations(out: &mut OutFile, apis: &[Api]) {\n    out.set_namespace(Default::default());\n    out.begin_block(Block::Namespace(\"std\"));\n\n    for api in apis {\n        if let Api::Struct(strct) = api {\n            if derive::contains(&strct.derives, Trait::Hash) {\n                out.next_section();\n                out.include.cstddef = true;\n                out.include.functional = true;\n                out.pragma.dollar_in_identifier = true;\n                let qualified = strct.name.to_fully_qualified();\n                writeln!(out, \"template <> struct hash<{}> {{\", qualified);\n                writeln!(\n                    out,\n                    \"  ::std::size_t operator()({} const &self) const noexcept {{\",\n                    qualified,\n                );\n                let link_name = mangle::operator(&strct.name, \"hash\");\n                write!(out, \"    return ::\");\n                for name in &strct.name.namespace {\n                    write!(out, \"{}::\", name);\n                }\n                writeln!(out, \"{}(self);\", link_name);\n                writeln!(out, \"  }}\");\n                writeln!(out, \"}};\");\n            }\n        }\n    }\n\n    out.end_block(Block::Namespace(\"std\"));\n}\n\nfn pick_includes_and_builtins(out: &mut OutFile, apis: &[Api]) {\n    for api in apis {\n        if let Api::Include(include) = api {\n            out.include.insert(include);\n        }\n    }\n\n    for ty in out.types {\n        match ty {\n            Type::Ident(ident) => match Atom::from(&ident.rust) {\n                Some(U8 | U16 | U32 | U64 | I8 | I16 | I32 | I64) => out.include.cstdint = true,\n                Some(Usize) => out.include.cstddef = true,\n                Some(Isize) => out.builtin.rust_isize = true,\n                Some(CxxString) => out.include.string = true,\n                Some(RustString) => out.builtin.rust_string = true,\n                Some(Bool | Char | F32 | F64) | None => {}\n            },\n            Type::RustBox(_) => out.builtin.rust_box = true,\n            Type::RustVec(_) => out.builtin.rust_vec = true,\n            Type::UniquePtr(_) => out.include.memory = true,\n            Type::SharedPtr(_) | Type::WeakPtr(_) => out.include.memory = true,\n            Type::Str(_) => out.builtin.rust_str = true,\n            Type::CxxVector(_) => out.include.vector = true,\n            Type::Fn(_) => out.builtin.rust_fn = true,\n            Type::SliceRef(_) => out.builtin.rust_slice = true,\n            Type::Array(_) => out.include.array = true,\n            Type::Ref(_) | Type::Void(_) | Type::Ptr(_) => {}\n        }\n    }\n}\n\nfn write_doc(out: &mut OutFile, indent: &str, doc: &Doc) {\n    let mut lines = 0;\n    for line in doc.to_string().lines() {\n        if out.opt.doxygen {\n            writeln!(out, \"{}///{}\", indent, line);\n        } else {\n            writeln!(out, \"{}//{}\", indent, line);\n        }\n        lines += 1;\n    }\n    // According to https://www.doxygen.nl/manual/docblocks.html, Doxygen only\n    // interprets `///` as a Doxygen comment block if there are at least 2 of\n    // them. In Rust, a single `///` is definitely still documentation so we\n    // make sure to propagate that as a Doxygen comment.\n    if out.opt.doxygen && lines == 1 {\n        writeln!(out, \"{}///\", indent);\n    }\n}\n\nfn write_struct<'a>(out: &mut OutFile<'a>, strct: &'a Struct, methods: &[&ExternFn]) {\n    let operator_eq = derive::contains(&strct.derives, Trait::PartialEq);\n    let operator_ord = derive::contains(&strct.derives, Trait::PartialOrd);\n\n    out.set_namespace(&strct.name.namespace);\n    let guard = Guard::new(out, \"CXXBRIDGE1_STRUCT\", &strct.name);\n    writeln!(out, \"#ifndef {}\", guard);\n    writeln!(out, \"#define {}\", guard);\n    write_doc(out, \"\", &strct.doc);\n    write!(out, \"struct\");\n    if let Some(align) = &strct.align {\n        out.builtin.alignmax = true;\n        writeln!(out, \" alignas(::rust::repr::alignmax<\");\n        writeln!(out, \"  {},\", align.base10_parse::<u32>().unwrap());\n        for (i, field) in strct.fields.iter().enumerate() {\n            write!(out, \"  alignof(\");\n            write_type(out, &field.ty);\n            write!(out, \")\");\n            if i + 1 != strct.fields.len() {\n                write!(out, \",\");\n            }\n            writeln!(out);\n        }\n        write!(out, \">)\");\n    }\n    writeln!(out, \" {} final {{\", strct.name.cxx);\n\n    for field in &strct.fields {\n        write_doc(out, \"  \", &field.doc);\n        write!(out, \"  \");\n        write_type_space(out, &field.ty);\n        write!(out, \"{}\", field.name.cxx);\n        if let Some(primitive) = primitive::kind(&field.ty) {\n            let default_value = match primitive {\n                PrimitiveKind::Boolean => \"false\",\n                PrimitiveKind::Number => \"0\",\n                PrimitiveKind::Pointer => \"nullptr\",\n            };\n            write!(out, \" CXX_DEFAULT_VALUE({})\", default_value);\n        }\n        writeln!(out, \";\");\n    }\n\n    out.next_section();\n\n    for method in methods {\n        if !method.doc.is_empty() {\n            out.next_section();\n        }\n        write_doc(out, \"  \", &method.doc);\n        write!(out, \"  \");\n        let local_name = method.name.cxx.to_string();\n        let sig = &method.sig;\n        let in_class = true;\n        let indirect_call = false;\n        let main = false;\n        write_rust_function_shim_decl(out, &local_name, sig, in_class, indirect_call, main);\n        writeln!(out, \";\");\n        if !method.doc.is_empty() {\n            out.next_section();\n        }\n    }\n\n    if operator_eq {\n        writeln!(\n            out,\n            \"  bool operator==({} const &) const noexcept;\",\n            strct.name.cxx,\n        );\n        writeln!(\n            out,\n            \"  bool operator!=({} const &) const noexcept;\",\n            strct.name.cxx,\n        );\n    }\n\n    if operator_ord {\n        writeln!(\n            out,\n            \"  bool operator<({} const &) const noexcept;\",\n            strct.name.cxx,\n        );\n        writeln!(\n            out,\n            \"  bool operator<=({} const &) const noexcept;\",\n            strct.name.cxx,\n        );\n        writeln!(\n            out,\n            \"  bool operator>({} const &) const noexcept;\",\n            strct.name.cxx,\n        );\n        writeln!(\n            out,\n            \"  bool operator>=({} const &) const noexcept;\",\n            strct.name.cxx,\n        );\n    }\n\n    out.include.type_traits = true;\n    writeln!(out, \"  using IsRelocatable = ::std::true_type;\");\n\n    writeln!(out, \"}};\");\n    writeln!(out, \"#endif // {}\", guard);\n}\n\nfn write_struct_decl(out: &mut OutFile, ident: &Pair) {\n    writeln!(out, \"struct {};\", ident.cxx);\n}\n\nfn write_enum_decl(out: &mut OutFile, enm: &Enum) {\n    write!(out, \"enum class {} : \", enm.name.cxx);\n    write_atom(out, enm.repr.atom);\n    writeln!(out, \";\");\n}\n\nfn write_struct_using(out: &mut OutFile, ident: &Pair) {\n    writeln!(out, \"using {} = {};\", ident.cxx, ident.to_fully_qualified());\n}\n\nfn write_opaque_type<'a>(out: &mut OutFile<'a>, ety: &'a ExternType, methods: &[&ExternFn]) {\n    out.set_namespace(&ety.name.namespace);\n    let guard = Guard::new(out, \"CXXBRIDGE1_STRUCT\", &ety.name);\n    writeln!(out, \"#ifndef {}\", guard);\n    writeln!(out, \"#define {}\", guard);\n    write_doc(out, \"\", &ety.doc);\n\n    out.builtin.opaque = true;\n    writeln!(\n        out,\n        \"struct {} final : public ::rust::Opaque {{\",\n        ety.name.cxx,\n    );\n\n    for (i, method) in methods.iter().enumerate() {\n        if i > 0 && !method.doc.is_empty() {\n            out.next_section();\n        }\n        write_doc(out, \"  \", &method.doc);\n        write!(out, \"  \");\n        let local_name = method.name.cxx.to_string();\n        let sig = &method.sig;\n        let in_class = true;\n        let indirect_call = false;\n        let main = false;\n        write_rust_function_shim_decl(out, &local_name, sig, in_class, indirect_call, main);\n        writeln!(out, \";\");\n        if !method.doc.is_empty() {\n            out.next_section();\n        }\n    }\n\n    writeln!(out, \"  ~{}() = delete;\", ety.name.cxx);\n    writeln!(out);\n\n    out.builtin.layout = true;\n    out.include.cstddef = true;\n    writeln!(out, \"private:\");\n    writeln!(out, \"  friend ::rust::layout;\");\n    writeln!(out, \"  struct layout {{\");\n    writeln!(out, \"    static ::std::size_t size() noexcept;\");\n    writeln!(out, \"    static ::std::size_t align() noexcept;\");\n    writeln!(out, \"  }};\");\n    writeln!(out, \"}};\");\n    writeln!(out, \"#endif // {}\", guard);\n}\n\nfn write_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {\n    out.set_namespace(&enm.name.namespace);\n    let guard = Guard::new(out, \"CXXBRIDGE1_ENUM\", &enm.name);\n    writeln!(out, \"#ifndef {}\", guard);\n    writeln!(out, \"#define {}\", guard);\n\n    write_doc(out, \"\", &enm.doc);\n    write!(out, \"enum class {} : \", enm.name.cxx);\n    write_atom(out, enm.repr.atom);\n    writeln!(out, \" {{\");\n    for variant in &enm.variants {\n        write_doc(out, \"  \", &variant.doc);\n        write!(out, \"  {} = \", variant.name.cxx);\n        write_discriminant(out, enm.repr.atom, variant.discriminant);\n        writeln!(out, \",\");\n    }\n    writeln!(out, \"}};\");\n\n    if out.header {\n        write_enum_operators(out, enm);\n    }\n\n    writeln!(out, \"#endif // {}\", guard);\n}\n\nfn check_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {\n    out.set_namespace(&enm.name.namespace);\n    out.include.type_traits = true;\n    writeln!(\n        out,\n        \"static_assert(::std::is_enum<{}>::value, \\\"expected enum\\\");\",\n        enm.name.cxx,\n    );\n    write!(out, \"static_assert(sizeof({}) == sizeof(\", enm.name.cxx);\n    write_atom(out, enm.repr.atom);\n    writeln!(out, \"), \\\"incorrect size\\\");\");\n    for variant in &enm.variants {\n        write!(out, \"static_assert(static_cast<\");\n        write_atom(out, enm.repr.atom);\n        write!(out, \">({}::{}) == \", enm.name.cxx, variant.name.cxx);\n        write_discriminant(out, enm.repr.atom, variant.discriminant);\n        writeln!(out, \", \\\"disagrees with the value in #[cxx::bridge]\\\");\");\n    }\n\n    if out.header\n        && (derive::contains(&enm.derives, Trait::BitAnd)\n            || derive::contains(&enm.derives, Trait::BitOr)\n            || derive::contains(&enm.derives, Trait::BitXor))\n    {\n        out.next_section();\n        let guard = Guard::new(out, \"CXXBRIDGE1_ENUM\", &enm.name);\n        writeln!(out, \"#ifndef {}\", guard);\n        writeln!(out, \"#define {}\", guard);\n        out.suppress_next_section();\n        write_enum_operators(out, enm);\n        writeln!(out, \"#endif // {}\", guard);\n    }\n}\n\nfn write_discriminant(out: &mut OutFile, repr: Atom, discriminant: Discriminant) {\n    let limits = Limits::of(repr).unwrap();\n    if discriminant == limits.min && limits.min < Discriminant::zero() {\n        out.include.limits = true;\n        write!(out, \"::std::numeric_limits<\");\n        write_atom(out, repr);\n        write!(out, \">::min()\");\n    } else {\n        write!(out, \"{}\", discriminant);\n    }\n}\n\nfn write_binary_bitwise_op(out: &mut OutFile, op: &str, enm: &Enum) {\n    let enum_name = &enm.name.cxx;\n    writeln!(\n        out,\n        \"inline {enum_name} operator{op}({enum_name} lhs, {enum_name} rhs) {{\",\n    );\n    write!(out, \"  return static_cast<{enum_name}>(static_cast<\");\n    write_atom(out, enm.repr.atom);\n    write!(out, \">(lhs) {op} static_cast<\");\n    write_atom(out, enm.repr.atom);\n    writeln!(out, \">(rhs));\");\n    writeln!(out, \"}}\");\n}\n\nfn write_enum_operators(out: &mut OutFile, enm: &Enum) {\n    if derive::contains(&enm.derives, Trait::BitAnd) {\n        out.next_section();\n        write_binary_bitwise_op(out, \"&\", enm);\n    }\n\n    if derive::contains(&enm.derives, Trait::BitOr) {\n        out.next_section();\n        write_binary_bitwise_op(out, \"|\", enm);\n    }\n\n    if derive::contains(&enm.derives, Trait::BitXor) {\n        out.next_section();\n        write_binary_bitwise_op(out, \"^\", enm);\n    }\n}\n\nfn check_trivial_extern_type(out: &mut OutFile, alias: &TypeAlias, reasons: &[TrivialReason]) {\n    // NOTE: The following static assertion is just nice-to-have and not\n    // necessary for soundness. That's because triviality is always declared by\n    // the user in the form of an unsafe impl of cxx::ExternType:\n    //\n    //     unsafe impl ExternType for MyType {\n    //         type Id = cxx::type_id!(\"...\");\n    //         type Kind = cxx::kind::Trivial;\n    //     }\n    //\n    // Since the user went on the record with their unsafe impl to unsafely\n    // claim they KNOW that the type is trivial, it's fine for that to be on\n    // them if that were wrong. However, in practice correctly reasoning about\n    // the relocatability of C++ types is challenging, particularly if the type\n    // definition were to change over time, so for now we add this check.\n    //\n    // There may be legitimate reasons to opt out of this assertion for support\n    // of types that the programmer knows are soundly Rust-movable despite not\n    // being recognized as such by the C++ type system due to a move constructor\n    // or destructor. To opt out of the relocatability check, they need to do\n    // one of the following things in any header used by `include!` in their\n    // bridge.\n    //\n    //      --- if they define the type:\n    //      struct MyType {\n    //        ...\n    //    +   using IsRelocatable = std::true_type;\n    //      };\n    //\n    //      --- otherwise:\n    //    + template <>\n    //    + struct rust::IsRelocatable<MyType> : std::true_type {};\n    //\n\n    let id = alias.name.to_fully_qualified();\n    out.builtin.relocatable = true;\n\n    let mut rust_type_ok = true;\n    let mut array_ok = true;\n    for reason in reasons {\n        // Allow extern type that inherits from ::rust::Opaque in positions\n        // where an opaque Rust type would be allowed.\n        rust_type_ok &= match reason {\n            TrivialReason::BoxTarget { .. }\n            | TrivialReason::VecElement { .. }\n            | TrivialReason::SliceElement { .. } => true,\n            TrivialReason::StructField(_)\n            | TrivialReason::FunctionArgument(_)\n            | TrivialReason::FunctionReturn(_) => false,\n        };\n        // If the type is only used as a struct field or Vec element, not as\n        // by-value function argument or return value, then C array of trivially\n        // relocatable type is also permissible.\n        //\n        //     --- means something sane:\n        //     struct T { char buf[N]; };\n        //\n        //     --- means something totally different:\n        //     void f(char buf[N]);\n        //\n        array_ok &= match reason {\n            TrivialReason::StructField(_) | TrivialReason::VecElement { .. } => true,\n            TrivialReason::FunctionArgument(_)\n            | TrivialReason::FunctionReturn(_)\n            | TrivialReason::BoxTarget { .. }\n            | TrivialReason::SliceElement { .. } => false,\n        };\n    }\n\n    writeln!(out, \"static_assert(\");\n    write!(out, \"    \");\n    if rust_type_ok {\n        out.include.type_traits = true;\n        out.builtin.opaque = true;\n        write!(out, \"::std::is_base_of<::rust::Opaque, {}>::value || \", id);\n    }\n    if array_ok {\n        out.builtin.relocatable_or_array = true;\n        writeln!(out, \"::rust::IsRelocatableOrArray<{}>::value,\", id);\n    } else {\n        writeln!(out, \"::rust::IsRelocatable<{}>::value,\", id);\n    }\n    writeln!(\n        out,\n        \"    \\\"type {} should be trivially move constructible and trivially destructible in C++ to be used as {} in Rust\\\");\",\n        id.trim_start_matches(\"::\"),\n        trivial::as_what(&alias.name, reasons),\n    );\n}\n\nfn write_struct_operator_decls<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {\n    out.set_namespace(&strct.name.namespace);\n    out.begin_block(Block::ExternC);\n\n    if derive::contains(&strct.derives, Trait::PartialEq) {\n        out.pragma.dollar_in_identifier = true;\n        out.pragma.missing_declarations = true;\n        let link_name = mangle::operator(&strct.name, \"eq\");\n        writeln!(\n            out,\n            \"bool {}({1} const &, {1} const &) noexcept;\",\n            link_name, strct.name.cxx,\n        );\n\n        if !derive::contains(&strct.derives, Trait::Eq) {\n            let link_name = mangle::operator(&strct.name, \"ne\");\n            writeln!(\n                out,\n                \"bool {}({1} const &, {1} const &) noexcept;\",\n                link_name, strct.name.cxx,\n            );\n        }\n    }\n\n    if derive::contains(&strct.derives, Trait::PartialOrd) {\n        out.pragma.dollar_in_identifier = true;\n        out.pragma.missing_declarations = true;\n        let link_name = mangle::operator(&strct.name, \"lt\");\n        writeln!(\n            out,\n            \"bool {}({1} const &, {1} const &) noexcept;\",\n            link_name, strct.name.cxx,\n        );\n\n        let link_name = mangle::operator(&strct.name, \"le\");\n        writeln!(\n            out,\n            \"bool {}({1} const &, {1} const &) noexcept;\",\n            link_name, strct.name.cxx,\n        );\n\n        if !derive::contains(&strct.derives, Trait::Ord) {\n            let link_name = mangle::operator(&strct.name, \"gt\");\n            writeln!(\n                out,\n                \"bool {}({1} const &, {1} const &) noexcept;\",\n                link_name, strct.name.cxx,\n            );\n\n            let link_name = mangle::operator(&strct.name, \"ge\");\n            writeln!(\n                out,\n                \"bool {}({1} const &, {1} const &) noexcept;\",\n                link_name, strct.name.cxx,\n            );\n        }\n    }\n\n    if derive::contains(&strct.derives, Trait::Hash) {\n        out.include.cstddef = true;\n        out.pragma.dollar_in_identifier = true;\n        out.pragma.missing_declarations = true;\n        let link_name = mangle::operator(&strct.name, \"hash\");\n        writeln!(\n            out,\n            \"::std::size_t {}({} const &) noexcept;\",\n            link_name, strct.name.cxx,\n        );\n    }\n\n    out.end_block(Block::ExternC);\n}\n\nfn write_struct_operators<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {\n    if out.header {\n        return;\n    }\n\n    out.set_namespace(&strct.name.namespace);\n\n    if derive::contains(&strct.derives, Trait::PartialEq) {\n        out.pragma.dollar_in_identifier = true;\n\n        out.next_section();\n        writeln!(\n            out,\n            \"bool {0}::operator==({0} const &rhs) const noexcept {{\",\n            strct.name.cxx,\n        );\n        let link_name = mangle::operator(&strct.name, \"eq\");\n        writeln!(out, \"  return {}(*this, rhs);\", link_name);\n        writeln!(out, \"}}\");\n\n        out.next_section();\n        writeln!(\n            out,\n            \"bool {0}::operator!=({0} const &rhs) const noexcept {{\",\n            strct.name.cxx,\n        );\n        if derive::contains(&strct.derives, Trait::Eq) {\n            writeln!(out, \"  return !(*this == rhs);\");\n        } else {\n            let link_name = mangle::operator(&strct.name, \"ne\");\n            writeln!(out, \"  return {}(*this, rhs);\", link_name);\n        }\n        writeln!(out, \"}}\");\n    }\n\n    if derive::contains(&strct.derives, Trait::PartialOrd) {\n        out.pragma.dollar_in_identifier = true;\n\n        out.next_section();\n        writeln!(\n            out,\n            \"bool {0}::operator<({0} const &rhs) const noexcept {{\",\n            strct.name.cxx,\n        );\n        let link_name = mangle::operator(&strct.name, \"lt\");\n        writeln!(out, \"  return {}(*this, rhs);\", link_name);\n        writeln!(out, \"}}\");\n\n        out.next_section();\n        writeln!(\n            out,\n            \"bool {0}::operator<=({0} const &rhs) const noexcept {{\",\n            strct.name.cxx,\n        );\n        let link_name = mangle::operator(&strct.name, \"le\");\n        writeln!(out, \"  return {}(*this, rhs);\", link_name);\n        writeln!(out, \"}}\");\n\n        out.next_section();\n        writeln!(\n            out,\n            \"bool {0}::operator>({0} const &rhs) const noexcept {{\",\n            strct.name.cxx,\n        );\n        if derive::contains(&strct.derives, Trait::Ord) {\n            writeln!(out, \"  return !(*this <= rhs);\");\n        } else {\n            let link_name = mangle::operator(&strct.name, \"gt\");\n            writeln!(out, \"  return {}(*this, rhs);\", link_name);\n        }\n        writeln!(out, \"}}\");\n\n        out.next_section();\n        writeln!(\n            out,\n            \"bool {0}::operator>=({0} const &rhs) const noexcept {{\",\n            strct.name.cxx,\n        );\n        if derive::contains(&strct.derives, Trait::Ord) {\n            writeln!(out, \"  return !(*this < rhs);\");\n        } else {\n            let link_name = mangle::operator(&strct.name, \"ge\");\n            writeln!(out, \"  return {}(*this, rhs);\", link_name);\n        }\n        writeln!(out, \"}}\");\n    }\n}\n\nfn write_opaque_type_layout_decls<'a>(out: &mut OutFile<'a>, ety: &'a ExternType) {\n    out.set_namespace(&ety.name.namespace);\n    out.begin_block(Block::ExternC);\n    out.pragma.dollar_in_identifier = true;\n    out.pragma.missing_declarations = true;\n\n    let link_name = mangle::operator(&ety.name, \"sizeof\");\n    writeln!(out, \"::std::size_t {}() noexcept;\", link_name);\n\n    let link_name = mangle::operator(&ety.name, \"alignof\");\n    writeln!(out, \"::std::size_t {}() noexcept;\", link_name);\n\n    out.end_block(Block::ExternC);\n}\n\nfn write_opaque_type_layout<'a>(out: &mut OutFile<'a>, ety: &'a ExternType) {\n    if out.header {\n        return;\n    }\n\n    out.set_namespace(&ety.name.namespace);\n    out.pragma.dollar_in_identifier = true;\n\n    out.next_section();\n    let link_name = mangle::operator(&ety.name, \"sizeof\");\n    writeln!(\n        out,\n        \"::std::size_t {}::layout::size() noexcept {{\",\n        ety.name.cxx,\n    );\n    writeln!(out, \"  return {}();\", link_name);\n    writeln!(out, \"}}\");\n\n    out.next_section();\n    let link_name = mangle::operator(&ety.name, \"alignof\");\n    writeln!(\n        out,\n        \"::std::size_t {}::layout::align() noexcept {{\",\n        ety.name.cxx,\n    );\n    writeln!(out, \"  return {}();\", link_name);\n    writeln!(out, \"}}\");\n}\n\nfn begin_function_definition(out: &mut OutFile) {\n    if let Some(annotation) = &out.opt.cxx_impl_annotations {\n        write!(out, \"{} \", annotation);\n    }\n}\n\nfn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {\n    out.pragma.dollar_in_identifier = true;\n    out.pragma.missing_declarations = true;\n    out.next_section();\n    out.set_namespace(&efn.name.namespace);\n    out.begin_block(Block::ExternC);\n    begin_function_definition(out);\n    if efn.throws {\n        out.builtin.ptr_len = true;\n        write!(out, \"::rust::repr::PtrLen \");\n    } else {\n        write_extern_return_type_space(out, efn, efn.lang);\n    }\n    let mangled = mangle::extern_fn(efn, out.types);\n    write!(out, \"{}(\", mangled);\n    if let FnKind::Method(receiver) = &efn.kind {\n        write!(\n            out,\n            \"{}\",\n            out.types.resolve(&receiver.ty).name.to_fully_qualified(),\n        );\n        if !receiver.mutable {\n            write!(out, \" const\");\n        }\n        write!(out, \" &self\");\n    }\n    for (i, arg) in efn.args.iter().enumerate() {\n        if i > 0 || matches!(efn.kind, FnKind::Method(_)) {\n            write!(out, \", \");\n        }\n        if arg.ty == RustString {\n            write_type_space(out, &arg.ty);\n            write!(out, \"const *{}\", arg.name.cxx);\n        } else if let Type::RustVec(_) = arg.ty {\n            write_type_space(out, &arg.ty);\n            write!(out, \"const *{}\", arg.name.cxx);\n        } else {\n            write_extern_arg(out, arg);\n        }\n    }\n    let indirect_return = indirect_return(efn, out.types, efn.lang);\n    if indirect_return {\n        if !efn.args.is_empty() || matches!(efn.kind, FnKind::Method(_)) {\n            write!(out, \", \");\n        }\n        write_indirect_return_type_space(out, efn.ret.as_ref().unwrap());\n        write!(out, \"*return$\");\n    }\n    write!(out, \")\");\n    match efn.lang {\n        Lang::Cxx => write!(out, \" noexcept\"),\n        Lang::CxxUnwind => {}\n        Lang::Rust => unreachable!(),\n    }\n    writeln!(out, \" {{\");\n    write!(out, \"  \");\n    write_return_type(out, &efn.ret);\n    match efn.receiver() {\n        None => write!(out, \"(*{}$)(\", efn.name.rust),\n        Some(receiver) => write!(\n            out,\n            \"({}::*{}$)(\",\n            out.types.resolve(&receiver.ty).name.to_fully_qualified(),\n            efn.name.rust,\n        ),\n    }\n    for (i, arg) in efn.args.iter().enumerate() {\n        if i > 0 {\n            write!(out, \", \");\n        }\n        write_type(out, &arg.ty);\n    }\n    write!(out, \")\");\n    if let Some(receiver) = efn.receiver() {\n        if !receiver.mutable {\n            write!(out, \" const\");\n        }\n    }\n    write!(out, \" = \");\n    match efn.self_type() {\n        None => write!(out, \"{}\", efn.name.to_fully_qualified()),\n        Some(self_type) => write!(\n            out,\n            \"&{}::{}\",\n            out.types.resolve(self_type).name.to_fully_qualified(),\n            efn.name.cxx,\n        ),\n    }\n    writeln!(out, \";\");\n    write!(out, \"  \");\n    if efn.throws {\n        out.builtin.ptr_len = true;\n        out.builtin.trycatch = true;\n        writeln!(out, \"::rust::repr::PtrLen throw$;\");\n        writeln!(out, \"  ::rust::behavior::trycatch(\");\n        writeln!(out, \"      [&] {{\");\n        write!(out, \"        \");\n    }\n    if indirect_return {\n        out.include.new = true;\n        write!(out, \"new (return$) \");\n        write_indirect_return_type(out, efn.ret.as_ref().unwrap());\n        write!(out, \"(\");\n    } else if efn.ret.is_some() {\n        write!(out, \"return \");\n    }\n    match &efn.ret {\n        Some(Type::Ref(_)) => write!(out, \"&\"),\n        Some(Type::Str(_)) if !indirect_return => {\n            out.builtin.rust_str_repr = true;\n            write!(out, \"::rust::impl<::rust::Str>::repr(\");\n        }\n        Some(ty @ Type::SliceRef(_)) if !indirect_return => {\n            out.builtin.rust_slice_repr = true;\n            write!(out, \"::rust::impl<\");\n            write_type(out, ty);\n            write!(out, \">::repr(\");\n        }\n        _ => {}\n    }\n    match efn.receiver() {\n        None => write!(out, \"{}$(\", efn.name.rust),\n        Some(_) => write!(out, \"(self.*{}$)(\", efn.name.rust),\n    }\n    for (i, arg) in efn.args.iter().enumerate() {\n        if i > 0 {\n            write!(out, \", \");\n        }\n        if let Type::RustBox(_) = &arg.ty {\n            write_type(out, &arg.ty);\n            write!(out, \"::from_raw({})\", arg.name.cxx);\n        } else if let Type::UniquePtr(_) = &arg.ty {\n            write_type(out, &arg.ty);\n            write!(out, \"({})\", arg.name.cxx);\n        } else if arg.ty == RustString {\n            out.builtin.unsafe_bitcopy = true;\n            write!(\n                out,\n                \"::rust::String(::rust::unsafe_bitcopy, *{})\",\n                arg.name.cxx,\n            );\n        } else if let Type::RustVec(_) = arg.ty {\n            out.builtin.unsafe_bitcopy = true;\n            write_type(out, &arg.ty);\n            write!(out, \"(::rust::unsafe_bitcopy, *{})\", arg.name.cxx);\n        } else if out.types.needs_indirect_abi(&arg.ty) {\n            out.include.utility = true;\n            write!(out, \"::std::move(*{})\", arg.name.cxx);\n        } else {\n            write!(out, \"{}\", arg.name.cxx);\n        }\n    }\n    write!(out, \")\");\n    match &efn.ret {\n        Some(Type::RustBox(_)) => write!(out, \".into_raw()\"),\n        Some(Type::UniquePtr(_)) => write!(out, \".release()\"),\n        Some(Type::Str(_) | Type::SliceRef(_)) if !indirect_return => write!(out, \")\"),\n        _ => {}\n    }\n    if indirect_return {\n        write!(out, \")\");\n    }\n    writeln!(out, \";\");\n    if efn.throws {\n        writeln!(out, \"        throw$.ptr = nullptr;\");\n        writeln!(out, \"      }},\");\n        writeln!(out, \"      ::rust::detail::Fail(throw$));\");\n        writeln!(out, \"  return throw$;\");\n    }\n    writeln!(out, \"}}\");\n    for arg in &efn.args {\n        if let Type::Fn(f) = &arg.ty {\n            let var = &arg.name;\n            write_function_pointer_trampoline(out, efn, var, f);\n        }\n    }\n    out.end_block(Block::ExternC);\n}\n\nfn write_function_pointer_trampoline(out: &mut OutFile, efn: &ExternFn, var: &Pair, f: &Signature) {\n    out.pragma.return_type_c_linkage = true;\n\n    let r_trampoline = mangle::r_trampoline(efn, var, out.types);\n    let indirect_call = true;\n    write_rust_function_decl_impl(out, &r_trampoline, f, indirect_call);\n\n    out.next_section();\n    let c_trampoline = mangle::c_trampoline(efn, var, out.types).to_string();\n    let doc = Doc::new();\n    let main = false;\n    write_rust_function_shim_impl(\n        out,\n        &c_trampoline,\n        f,\n        &doc,\n        &r_trampoline,\n        indirect_call,\n        main,\n    );\n}\n\nfn write_rust_function_decl<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {\n    out.set_namespace(&efn.name.namespace);\n    out.begin_block(Block::ExternC);\n    let link_name = mangle::extern_fn(efn, out.types);\n    let indirect_call = false;\n    write_rust_function_decl_impl(out, &link_name, efn, indirect_call);\n    out.end_block(Block::ExternC);\n}\n\nfn write_rust_function_decl_impl(\n    out: &mut OutFile,\n    link_name: &Symbol,\n    sig: &Signature,\n    indirect_call: bool,\n) {\n    out.next_section();\n    out.pragma.dollar_in_identifier = true;\n    if sig.throws {\n        out.builtin.ptr_len = true;\n        write!(out, \"::rust::repr::PtrLen \");\n    } else {\n        write_extern_return_type_space(out, sig, Lang::Rust);\n    }\n    write!(out, \"{}(\", link_name);\n    let mut needs_comma = false;\n    if let FnKind::Method(receiver) = &sig.kind {\n        write!(\n            out,\n            \"{}\",\n            out.types.resolve(&receiver.ty).name.to_fully_qualified(),\n        );\n        if !receiver.mutable {\n            write!(out, \" const\");\n        }\n        write!(out, \" &self\");\n        needs_comma = true;\n    }\n    for arg in &sig.args {\n        if needs_comma {\n            write!(out, \", \");\n        }\n        write_extern_arg(out, arg);\n        needs_comma = true;\n    }\n    if indirect_return(sig, out.types, Lang::Rust) {\n        if needs_comma {\n            write!(out, \", \");\n        }\n        match sig.ret.as_ref().unwrap() {\n            Type::Ref(ret) => {\n                write_type_space(out, &ret.inner);\n                if !ret.mutable {\n                    write!(out, \"const \");\n                }\n                write!(out, \"*\");\n            }\n            ret => write_type_space(out, ret),\n        }\n        write!(out, \"*return$\");\n        needs_comma = true;\n    }\n    if indirect_call {\n        if needs_comma {\n            write!(out, \", \");\n        }\n        write!(out, \"void *\");\n    }\n    writeln!(out, \") noexcept;\");\n}\n\nfn write_rust_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {\n    out.set_namespace(&efn.name.namespace);\n    let local_name = match efn.self_type() {\n        None => efn.name.cxx.to_string(),\n        Some(self_type) => format!(\n            \"{}::{}\",\n            out.types.resolve(self_type).name.cxx,\n            efn.name.cxx,\n        ),\n    };\n    let doc = &efn.doc;\n    let invoke = mangle::extern_fn(efn, out.types);\n    let indirect_call = false;\n    let main = efn.name.cxx == *\"main\"\n        && efn.name.namespace == Namespace::ROOT\n        && efn.sig.asyncness.is_none()\n        && matches!(efn.kind, FnKind::Free)\n        && efn.sig.args.is_empty()\n        && efn.sig.ret.is_none()\n        && !efn.sig.throws;\n    write_rust_function_shim_impl(out, &local_name, efn, doc, &invoke, indirect_call, main);\n}\n\nfn write_rust_function_shim_decl(\n    out: &mut OutFile,\n    local_name: &str,\n    sig: &Signature,\n    in_class: bool,\n    indirect_call: bool,\n    main: bool,\n) {\n    begin_function_definition(out);\n    if matches!(sig.kind, FnKind::Assoc(_)) && in_class {\n        write!(out, \"static \");\n    }\n    if main {\n        write!(out, \"int \");\n    } else {\n        write_return_type(out, &sig.ret);\n    }\n    write!(out, \"{}(\", local_name);\n    for (i, arg) in sig.args.iter().enumerate() {\n        if i > 0 {\n            write!(out, \", \");\n        }\n        write_type_space(out, &arg.ty);\n        write!(out, \"{}\", arg.name.cxx);\n    }\n    if indirect_call {\n        if !sig.args.is_empty() {\n            write!(out, \", \");\n        }\n        write!(out, \"void *extern$\");\n    }\n    write!(out, \")\");\n    if let FnKind::Method(receiver) = &sig.kind {\n        if !receiver.mutable {\n            write!(out, \" const\");\n        }\n    }\n    if !sig.throws {\n        write!(out, \" noexcept\");\n    }\n}\n\nfn write_rust_function_shim_impl(\n    out: &mut OutFile,\n    local_name: &str,\n    sig: &Signature,\n    doc: &Doc,\n    invoke: &Symbol,\n    indirect_call: bool,\n    main: bool,\n) {\n    if match sig.kind {\n        FnKind::Free => false,\n        FnKind::Method(_) | FnKind::Assoc(_) => out.header,\n    } {\n        // We've already defined this inside the struct.\n        return;\n    }\n    out.pragma.dollar_in_identifier = true;\n    if matches!(sig.kind, FnKind::Free) {\n        // Member functions already documented at their declaration.\n        write_doc(out, \"\", doc);\n    }\n    let in_class = false;\n    write_rust_function_shim_decl(out, local_name, sig, in_class, indirect_call, main);\n    if out.header {\n        writeln!(out, \";\");\n        return;\n    }\n    writeln!(out, \" {{\");\n    for arg in &sig.args {\n        if arg.ty != RustString && out.types.needs_indirect_abi(&arg.ty) {\n            out.include.utility = true;\n            out.builtin.manually_drop = true;\n            write!(out, \"  ::rust::ManuallyDrop<\");\n            write_type(out, &arg.ty);\n            writeln!(out, \"> {}$(::std::move({0}));\", arg.name.cxx);\n        }\n    }\n    write!(out, \"  \");\n    let indirect_return = indirect_return(sig, out.types, Lang::Rust);\n    if indirect_return {\n        out.builtin.maybe_uninit = true;\n        write!(out, \"::rust::MaybeUninit<\");\n        match sig.ret.as_ref().unwrap() {\n            Type::Ref(ret) => {\n                write_type_space(out, &ret.inner);\n                if !ret.mutable {\n                    write!(out, \"const \");\n                }\n                write!(out, \"*\");\n            }\n            ret => write_type(out, ret),\n        }\n        writeln!(out, \"> return$;\");\n        write!(out, \"  \");\n    } else if let Some(ret) = &sig.ret {\n        write!(out, \"return \");\n        match ret {\n            Type::RustBox(_) => {\n                write_type(out, ret);\n                write!(out, \"::from_raw(\");\n            }\n            Type::UniquePtr(_) => {\n                write_type(out, ret);\n                write!(out, \"(\");\n            }\n            Type::Ref(_) => write!(out, \"*\"),\n            Type::Str(_) => {\n                out.builtin.rust_str_new_unchecked = true;\n                write!(out, \"::rust::impl<::rust::Str>::new_unchecked(\");\n            }\n            Type::SliceRef(_) => {\n                out.builtin.rust_slice_new = true;\n                write!(out, \"::rust::impl<\");\n                write_type(out, ret);\n                write!(out, \">::slice(\");\n            }\n            _ => {}\n        }\n    }\n    if sig.throws {\n        out.builtin.ptr_len = true;\n        write!(out, \"::rust::repr::PtrLen error$ = \");\n    }\n    write!(out, \"{}(\", invoke);\n    let mut needs_comma = false;\n    if matches!(sig.kind, FnKind::Method(_)) {\n        write!(out, \"*this\");\n        needs_comma = true;\n    }\n    for arg in &sig.args {\n        if needs_comma {\n            write!(out, \", \");\n        }\n        if out.types.needs_indirect_abi(&arg.ty) {\n            write!(out, \"&\");\n        }\n        write!(out, \"{}\", arg.name.cxx);\n        match &arg.ty {\n            Type::RustBox(_) => write!(out, \".into_raw()\"),\n            Type::UniquePtr(_) => write!(out, \".release()\"),\n            ty if ty != RustString && out.types.needs_indirect_abi(ty) => write!(out, \"$.value\"),\n            _ => {}\n        }\n        needs_comma = true;\n    }\n    if indirect_return {\n        if needs_comma {\n            write!(out, \", \");\n        }\n        write!(out, \"&return$.value\");\n        needs_comma = true;\n    }\n    if indirect_call {\n        if needs_comma {\n            write!(out, \", \");\n        }\n        write!(out, \"extern$\");\n    }\n    write!(out, \")\");\n    if !indirect_return {\n        if let Some(Type::RustBox(_) | Type::UniquePtr(_) | Type::Str(_) | Type::SliceRef(_)) =\n            &sig.ret\n        {\n            write!(out, \")\");\n        }\n    }\n    writeln!(out, \";\");\n    if sig.throws {\n        out.builtin.rust_error = true;\n        writeln!(out, \"  if (error$.ptr) {{\");\n        writeln!(out, \"    throw ::rust::impl<::rust::Error>::error(error$);\");\n        writeln!(out, \"  }}\");\n    }\n    if indirect_return {\n        write!(out, \"  return \");\n        match sig.ret.as_ref().unwrap() {\n            Type::Ref(_) => write!(out, \"*return$.value\"),\n            _ => {\n                out.include.utility = true;\n                write!(out, \"::std::move(return$.value)\");\n            }\n        }\n        writeln!(out, \";\");\n    }\n    writeln!(out, \"}}\");\n}\n\nfn write_return_type(out: &mut OutFile, ty: &Option<Type>) {\n    match ty {\n        None => write!(out, \"void \"),\n        Some(ty) => write_type_space(out, ty),\n    }\n}\n\nfn indirect_return(sig: &Signature, types: &Types, lang: Lang) -> bool {\n    sig.ret.as_ref().is_some_and(|ret| {\n        sig.throws\n            || types.needs_indirect_abi(ret)\n            || match lang {\n                Lang::Cxx | Lang::CxxUnwind => types.contains_elided_lifetime(ret),\n                Lang::Rust => false,\n            }\n    })\n}\n\nfn write_indirect_return_type(out: &mut OutFile, ty: &Type) {\n    match ty {\n        Type::RustBox(ty) | Type::UniquePtr(ty) => {\n            write_type_space(out, &ty.inner);\n            write!(out, \"*\");\n        }\n        Type::Ref(ty) => {\n            write_type_space(out, &ty.inner);\n            if !ty.mutable {\n                write!(out, \"const \");\n            }\n            write!(out, \"*\");\n        }\n        _ => write_type(out, ty),\n    }\n}\n\nfn write_indirect_return_type_space(out: &mut OutFile, ty: &Type) {\n    write_indirect_return_type(out, ty);\n    match ty {\n        Type::RustBox(_) | Type::UniquePtr(_) | Type::Ref(_) => {}\n        Type::Str(_) | Type::SliceRef(_) => write!(out, \" \"),\n        _ => write_space_after_type(out, ty),\n    }\n}\n\nfn write_extern_return_type_space(out: &mut OutFile, sig: &Signature, lang: Lang) {\n    match &sig.ret {\n        Some(_) if indirect_return(sig, out.types, lang) => write!(out, \"void \"),\n        Some(Type::RustBox(ty) | Type::UniquePtr(ty)) => {\n            write_type_space(out, &ty.inner);\n            write!(out, \"*\");\n        }\n        Some(Type::Ref(ty)) => {\n            write_type_space(out, &ty.inner);\n            if !ty.mutable {\n                write!(out, \"const \");\n            }\n            write!(out, \"*\");\n        }\n        Some(Type::Str(_) | Type::SliceRef(_)) => {\n            out.builtin.repr_fat = true;\n            write!(out, \"::rust::repr::Fat \");\n        }\n        ty => write_return_type(out, ty),\n    }\n}\n\nfn write_extern_arg(out: &mut OutFile, arg: &Var) {\n    match &arg.ty {\n        Type::RustBox(ty) | Type::UniquePtr(ty) | Type::CxxVector(ty) => {\n            write_type_space(out, &ty.inner);\n            write!(out, \"*\");\n        }\n        _ => write_type_space(out, &arg.ty),\n    }\n    if out.types.needs_indirect_abi(&arg.ty) {\n        write!(out, \"*\");\n    }\n    write!(out, \"{}\", arg.name.cxx);\n}\n\nfn write_type(out: &mut OutFile, ty: &Type) {\n    write_type_to_generic_writer(out, ty, out.types);\n}\n\nfn stringify_type(ty: &Type, types: &Types) -> String {\n    let mut s = String::new();\n    write_type_to_generic_writer(&mut s, ty, types);\n    s\n}\n\nfn write_type_to_generic_writer(out: &mut impl InfallibleWrite, ty: &Type, types: &Types) {\n    match ty {\n        Type::Ident(ident) => match Atom::from(&ident.rust) {\n            Some(atom) => write_atom(out, atom),\n            None => write!(out, \"{}\", types.resolve(ident).name.to_fully_qualified()),\n        },\n        Type::RustBox(ty) => {\n            write!(out, \"::rust::Box<\");\n            write_type_to_generic_writer(out, &ty.inner, types);\n            write!(out, \">\");\n        }\n        Type::RustVec(ty) => {\n            write!(out, \"::rust::Vec<\");\n            write_type_to_generic_writer(out, &ty.inner, types);\n            write!(out, \">\");\n        }\n        Type::UniquePtr(ptr) => {\n            write!(out, \"::std::unique_ptr<\");\n            write_type_to_generic_writer(out, &ptr.inner, types);\n            write!(out, \">\");\n        }\n        Type::SharedPtr(ptr) => {\n            write!(out, \"::std::shared_ptr<\");\n            write_type_to_generic_writer(out, &ptr.inner, types);\n            write!(out, \">\");\n        }\n        Type::WeakPtr(ptr) => {\n            write!(out, \"::std::weak_ptr<\");\n            write_type_to_generic_writer(out, &ptr.inner, types);\n            write!(out, \">\");\n        }\n        Type::CxxVector(ty) => {\n            write!(out, \"::std::vector<\");\n            write_type_to_generic_writer(out, &ty.inner, types);\n            write!(out, \">\");\n        }\n        Type::Ref(r) => {\n            write_type_space_to_generic_writer(out, &r.inner, types);\n            if !r.mutable {\n                write!(out, \"const \");\n            }\n            write!(out, \"&\");\n        }\n        Type::Ptr(p) => {\n            write_type_space_to_generic_writer(out, &p.inner, types);\n            if !p.mutable {\n                write!(out, \"const \");\n            }\n            write!(out, \"*\");\n        }\n        Type::Str(_) => {\n            write!(out, \"::rust::Str\");\n        }\n        Type::SliceRef(slice) => {\n            write!(out, \"::rust::Slice<\");\n            write_type_space_to_generic_writer(out, &slice.inner, types);\n            if slice.mutability.is_none() {\n                write!(out, \"const\");\n            }\n            write!(out, \">\");\n        }\n        Type::Fn(f) => {\n            write!(out, \"::rust::Fn<\");\n            match &f.ret {\n                Some(ret) => write_type_to_generic_writer(out, ret, types),\n                None => write!(out, \"void\"),\n            }\n            write!(out, \"(\");\n            for (i, arg) in f.args.iter().enumerate() {\n                if i > 0 {\n                    write!(out, \", \");\n                }\n                write_type_to_generic_writer(out, &arg.ty, types);\n            }\n            write!(out, \")>\");\n        }\n        Type::Array(a) => {\n            write!(out, \"::std::array<\");\n            write_type_to_generic_writer(out, &a.inner, types);\n            write!(out, \", {}>\", &a.len);\n        }\n        Type::Void(_) => unreachable!(),\n    }\n}\n\nfn write_atom(out: &mut impl InfallibleWrite, atom: Atom) {\n    match atom {\n        Bool => write!(out, \"bool\"),\n        Char => write!(out, \"char\"),\n        U8 => write!(out, \"::std::uint8_t\"),\n        U16 => write!(out, \"::std::uint16_t\"),\n        U32 => write!(out, \"::std::uint32_t\"),\n        U64 => write!(out, \"::std::uint64_t\"),\n        Usize => write!(out, \"::std::size_t\"),\n        I8 => write!(out, \"::std::int8_t\"),\n        I16 => write!(out, \"::std::int16_t\"),\n        I32 => write!(out, \"::std::int32_t\"),\n        I64 => write!(out, \"::std::int64_t\"),\n        Isize => write!(out, \"::rust::isize\"),\n        F32 => write!(out, \"float\"),\n        F64 => write!(out, \"double\"),\n        CxxString => write!(out, \"::std::string\"),\n        RustString => write!(out, \"::rust::String\"),\n    }\n}\n\nfn write_type_space(out: &mut OutFile, ty: &Type) {\n    write_type_space_to_generic_writer(out, ty, out.types);\n}\n\nfn write_type_space_to_generic_writer(out: &mut impl InfallibleWrite, ty: &Type, types: &Types) {\n    write_type_to_generic_writer(out, ty, types);\n    write_space_after_type(out, ty);\n}\n\nfn write_space_after_type(out: &mut impl InfallibleWrite, ty: &Type) {\n    match ty {\n        Type::Ident(_)\n        | Type::RustBox(_)\n        | Type::UniquePtr(_)\n        | Type::SharedPtr(_)\n        | Type::WeakPtr(_)\n        | Type::Str(_)\n        | Type::CxxVector(_)\n        | Type::RustVec(_)\n        | Type::SliceRef(_)\n        | Type::Fn(_)\n        | Type::Array(_) => write!(out, \" \"),\n        Type::Ref(_) | Type::Ptr(_) => {}\n        Type::Void(_) => unreachable!(),\n    }\n}\n\nfn write_generic_instantiations(out: &mut OutFile) {\n    if out.header {\n        return;\n    }\n\n    out.next_section();\n    out.set_namespace(Default::default());\n    out.begin_block(Block::ExternC);\n    for impl_key in out.types.impls.keys() {\n        out.next_section();\n        match impl_key {\n            ImplKey::RustBox(ident) => write_rust_box_extern(out, ident),\n            ImplKey::RustVec(ident) => write_rust_vec_extern(out, ident),\n            ImplKey::UniquePtr(ident) => write_unique_ptr(out, ident),\n            ImplKey::SharedPtr(ident) => write_shared_ptr(out, ident),\n            ImplKey::WeakPtr(ident) => write_weak_ptr(out, ident),\n            ImplKey::CxxVector(ident) => write_cxx_vector(out, ident),\n        }\n    }\n    out.end_block(Block::ExternC);\n\n    out.begin_block(Block::Namespace(\"rust\"));\n    out.begin_block(Block::InlineNamespace(\"cxxbridge1\"));\n    for impl_key in out.types.impls.keys() {\n        match impl_key {\n            ImplKey::RustBox(ident) => write_rust_box_impl(out, ident),\n            ImplKey::RustVec(ident) => write_rust_vec_impl(out, ident),\n            _ => {}\n        }\n    }\n    out.end_block(Block::InlineNamespace(\"cxxbridge1\"));\n    out.end_block(Block::Namespace(\"rust\"));\n}\n\nfn write_rust_box_extern(out: &mut OutFile, key: &NamedImplKey) {\n    let inner = stringify_type(key.inner, out.types);\n    let instance = &key.symbol;\n\n    out.pragma.dollar_in_identifier = true;\n\n    writeln!(\n        out,\n        \"{} *cxxbridge1$box${}$alloc() noexcept;\",\n        inner, instance,\n    );\n    writeln!(\n        out,\n        \"void cxxbridge1$box${}$dealloc({} *) noexcept;\",\n        instance, inner,\n    );\n    writeln!(\n        out,\n        \"void cxxbridge1$box${}$drop(::rust::Box<{}> *ptr) noexcept;\",\n        instance, inner,\n    );\n}\n\nfn write_rust_vec_extern(out: &mut OutFile, key: &NamedImplKey) {\n    let inner = stringify_type(key.inner, out.types);\n    let instance = &key.symbol;\n\n    out.include.cstddef = true;\n    out.pragma.dollar_in_identifier = true;\n\n    writeln!(\n        out,\n        \"void cxxbridge1$rust_vec${}$new(::rust::Vec<{}> const *ptr) noexcept;\",\n        instance, inner,\n    );\n    writeln!(\n        out,\n        \"void cxxbridge1$rust_vec${}$drop(::rust::Vec<{}> *ptr) noexcept;\",\n        instance, inner,\n    );\n    writeln!(\n        out,\n        \"::std::size_t cxxbridge1$rust_vec${}$len(::rust::Vec<{}> const *ptr) noexcept;\",\n        instance, inner,\n    );\n    writeln!(\n        out,\n        \"::std::size_t cxxbridge1$rust_vec${}$capacity(::rust::Vec<{}> const *ptr) noexcept;\",\n        instance, inner,\n    );\n    writeln!(\n        out,\n        \"{} const *cxxbridge1$rust_vec${}$data(::rust::Vec<{0}> const *ptr) noexcept;\",\n        inner, instance,\n    );\n    writeln!(\n        out,\n        \"void cxxbridge1$rust_vec${}$reserve_total(::rust::Vec<{}> *ptr, ::std::size_t new_cap) noexcept;\",\n        instance, inner,\n    );\n    writeln!(\n        out,\n        \"void cxxbridge1$rust_vec${}$set_len(::rust::Vec<{}> *ptr, ::std::size_t len) noexcept;\",\n        instance, inner,\n    );\n    writeln!(\n        out,\n        \"void cxxbridge1$rust_vec${}$truncate(::rust::Vec<{}> *ptr, ::std::size_t len) noexcept;\",\n        instance, inner,\n    );\n}\n\nfn write_rust_box_impl(out: &mut OutFile, key: &NamedImplKey) {\n    let inner = stringify_type(key.inner, out.types);\n    let instance = &key.symbol;\n\n    out.pragma.dollar_in_identifier = true;\n\n    writeln!(out, \"template <>\");\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"{} *Box<{}>::allocation::alloc() noexcept {{\",\n        inner, inner,\n    );\n    writeln!(out, \"  return cxxbridge1$box${}$alloc();\", instance);\n    writeln!(out, \"}}\");\n\n    writeln!(out, \"template <>\");\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void Box<{}>::allocation::dealloc({} *ptr) noexcept {{\",\n        inner, inner,\n    );\n    writeln!(out, \"  cxxbridge1$box${}$dealloc(ptr);\", instance);\n    writeln!(out, \"}}\");\n\n    writeln!(out, \"template <>\");\n    begin_function_definition(out);\n    writeln!(out, \"void Box<{}>::drop() noexcept {{\", inner);\n    writeln!(out, \"  cxxbridge1$box${}$drop(this);\", instance);\n    writeln!(out, \"}}\");\n}\n\nfn write_rust_vec_impl(out: &mut OutFile, key: &NamedImplKey) {\n    let inner = stringify_type(key.inner, out.types);\n    let instance = &key.symbol;\n\n    out.include.cstddef = true;\n    out.pragma.dollar_in_identifier = true;\n\n    writeln!(out, \"template <>\");\n    begin_function_definition(out);\n    writeln!(out, \"Vec<{}>::Vec() noexcept {{\", inner);\n    writeln!(out, \"  cxxbridge1$rust_vec${}$new(this);\", instance);\n    writeln!(out, \"}}\");\n\n    writeln!(out, \"template <>\");\n    begin_function_definition(out);\n    writeln!(out, \"void Vec<{}>::drop() noexcept {{\", inner);\n    writeln!(out, \"  return cxxbridge1$rust_vec${}$drop(this);\", instance);\n    writeln!(out, \"}}\");\n\n    writeln!(out, \"template <>\");\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"::std::size_t Vec<{}>::size() const noexcept {{\",\n        inner,\n    );\n    writeln!(out, \"  return cxxbridge1$rust_vec${}$len(this);\", instance);\n    writeln!(out, \"}}\");\n\n    writeln!(out, \"template <>\");\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"::std::size_t Vec<{}>::capacity() const noexcept {{\",\n        inner,\n    );\n    writeln!(\n        out,\n        \"  return cxxbridge1$rust_vec${}$capacity(this);\",\n        instance,\n    );\n    writeln!(out, \"}}\");\n\n    writeln!(out, \"template <>\");\n    begin_function_definition(out);\n    writeln!(out, \"{} const *Vec<{0}>::data() const noexcept {{\", inner);\n    writeln!(out, \"  return cxxbridge1$rust_vec${}$data(this);\", instance);\n    writeln!(out, \"}}\");\n\n    writeln!(out, \"template <>\");\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void Vec<{}>::reserve_total(::std::size_t new_cap) noexcept {{\",\n        inner,\n    );\n    writeln!(\n        out,\n        \"  return cxxbridge1$rust_vec${}$reserve_total(this, new_cap);\",\n        instance,\n    );\n    writeln!(out, \"}}\");\n\n    writeln!(out, \"template <>\");\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void Vec<{}>::set_len(::std::size_t len) noexcept {{\",\n        inner,\n    );\n    writeln!(\n        out,\n        \"  return cxxbridge1$rust_vec${}$set_len(this, len);\",\n        instance,\n    );\n    writeln!(out, \"}}\");\n\n    writeln!(out, \"template <>\");\n    begin_function_definition(out);\n    writeln!(out, \"void Vec<{}>::truncate(::std::size_t len) {{\", inner);\n    writeln!(\n        out,\n        \"  return cxxbridge1$rust_vec${}$truncate(this, len);\",\n        instance,\n    );\n    writeln!(out, \"}}\");\n}\n\nfn write_unique_ptr(out: &mut OutFile, key: &NamedImplKey) {\n    write_unique_ptr_common(out, key.inner);\n}\n\n// Shared by UniquePtr<T> and UniquePtr<CxxVector<T>>.\nfn write_unique_ptr_common(out: &mut OutFile, ty: &Type) {\n    out.include.new = true;\n    out.include.utility = true;\n    out.pragma.dollar_in_identifier = true;\n    out.pragma.missing_declarations = true;\n\n    let inner = stringify_type(ty, out.types);\n    let instance = mangle::typename(ty, &out.types.resolutions)\n        .expect(\"unexpected UniquePtr generic parameter allowed through by syntax/check.rs\");\n\n    // Some aliases are to opaque types; some are to trivial types. We can't\n    // know at code generation time, so we generate both C++ and Rust side\n    // bindings for a \"new\" method anyway. But the Rust code can't be called for\n    // Opaque types because the 'new' method is not implemented.\n    let can_construct_from_value = out.types.is_maybe_trivial(ty);\n\n    out.builtin.is_complete = true;\n    writeln!(\n        out,\n        \"static_assert(::rust::detail::is_complete<::std::remove_extent<{}>::type>::value, \\\"definition of `{}` is required\\\");\",\n        inner, inner,\n    );\n    writeln!(\n        out,\n        \"static_assert(sizeof(::std::unique_ptr<{}>) == sizeof(void *), \\\"\\\");\",\n        inner,\n    );\n    writeln!(\n        out,\n        \"static_assert(alignof(::std::unique_ptr<{}>) == alignof(void *), \\\"\\\");\",\n        inner,\n    );\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void cxxbridge1$unique_ptr${}$null(::std::unique_ptr<{}> *ptr) noexcept {{\",\n        instance, inner,\n    );\n    writeln!(out, \"  ::new (ptr) ::std::unique_ptr<{}>();\", inner);\n    writeln!(out, \"}}\");\n\n    if can_construct_from_value {\n        out.builtin.maybe_uninit = true;\n        out.pragma.mismatched_new_delete = true;\n        begin_function_definition(out);\n        writeln!(\n            out,\n            \"{} *cxxbridge1$unique_ptr${}$uninit(::std::unique_ptr<{}> *ptr) noexcept {{\",\n            inner, instance, inner,\n        );\n        writeln!(\n            out,\n            \"  {} *uninit = reinterpret_cast<{} *>(new ::rust::MaybeUninit<{}>);\",\n            inner, inner, inner,\n        );\n        writeln!(out, \"  ::new (ptr) ::std::unique_ptr<{}>(uninit);\", inner);\n        writeln!(out, \"  return uninit;\");\n        writeln!(out, \"}}\");\n    }\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void cxxbridge1$unique_ptr${}$raw(::std::unique_ptr<{}> *ptr, ::std::unique_ptr<{}>::pointer raw) noexcept {{\",\n        instance, inner, inner,\n    );\n    writeln!(out, \"  ::new (ptr) ::std::unique_ptr<{}>(raw);\", inner);\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"::std::unique_ptr<{}>::element_type const *cxxbridge1$unique_ptr${}$get(::std::unique_ptr<{}> const &ptr) noexcept {{\",\n        inner, instance, inner,\n    );\n    writeln!(out, \"  return ptr.get();\");\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"::std::unique_ptr<{}>::pointer cxxbridge1$unique_ptr${}$release(::std::unique_ptr<{}> &ptr) noexcept {{\",\n        inner, instance, inner,\n    );\n    writeln!(out, \"  return ptr.release();\");\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void cxxbridge1$unique_ptr${}$drop(::std::unique_ptr<{}> *ptr) noexcept {{\",\n        instance, inner,\n    );\n    out.builtin.deleter_if = true;\n    writeln!(\n        out,\n        \"  ::rust::deleter_if<::rust::detail::is_complete<{}>::value>{{}}(ptr);\",\n        inner,\n    );\n    writeln!(out, \"}}\");\n}\n\nfn write_shared_ptr(out: &mut OutFile, key: &NamedImplKey) {\n    let inner = stringify_type(key.inner, out.types);\n    let instance = &key.symbol;\n\n    out.include.new = true;\n    out.include.utility = true;\n    out.pragma.dollar_in_identifier = true;\n    out.pragma.missing_declarations = true;\n\n    // Some aliases are to opaque types; some are to trivial types. We can't\n    // know at code generation time, so we generate both C++ and Rust side\n    // bindings for a \"new\" method anyway. But the Rust code can't be called for\n    // Opaque types because the 'new' method is not implemented.\n    let can_construct_from_value = out.types.is_maybe_trivial(key.inner);\n\n    writeln!(\n        out,\n        \"static_assert(sizeof(::std::shared_ptr<{}>) == 2 * sizeof(void *), \\\"\\\");\",\n        inner,\n    );\n    writeln!(\n        out,\n        \"static_assert(alignof(::std::shared_ptr<{}>) == alignof(void *), \\\"\\\");\",\n        inner,\n    );\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void cxxbridge1$shared_ptr${}$null(::std::shared_ptr<{}> *ptr) noexcept {{\",\n        instance, inner,\n    );\n    writeln!(out, \"  ::new (ptr) ::std::shared_ptr<{}>();\", inner);\n    writeln!(out, \"}}\");\n\n    if can_construct_from_value {\n        out.builtin.maybe_uninit = true;\n        out.pragma.mismatched_new_delete = true;\n        begin_function_definition(out);\n        writeln!(\n            out,\n            \"{} *cxxbridge1$shared_ptr${}$uninit(::std::shared_ptr<{}> *ptr) noexcept {{\",\n            inner, instance, inner,\n        );\n        writeln!(\n            out,\n            \"  {} *uninit = reinterpret_cast<{} *>(new ::rust::MaybeUninit<{}>);\",\n            inner, inner, inner,\n        );\n        writeln!(out, \"  ::new (ptr) ::std::shared_ptr<{}>(uninit);\", inner);\n        writeln!(out, \"  return uninit;\");\n        writeln!(out, \"}}\");\n    }\n\n    out.builtin.shared_ptr = true;\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"bool cxxbridge1$shared_ptr${}$raw(::std::shared_ptr<{}> *ptr, ::std::shared_ptr<{}>::element_type *raw) noexcept {{\",\n        instance, inner, inner,\n    );\n    writeln!(\n        out,\n        \"  ::new (ptr) ::rust::shared_ptr_if_destructible<{}>(raw);\",\n        inner,\n    );\n    writeln!(out, \"  return ::rust::is_destructible<{}>::value;\", inner);\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void cxxbridge1$shared_ptr${}$clone(::std::shared_ptr<{}> const &self, ::std::shared_ptr<{}> *ptr) noexcept {{\",\n        instance, inner, inner,\n    );\n    writeln!(out, \"  ::new (ptr) ::std::shared_ptr<{}>(self);\", inner);\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"::std::shared_ptr<{}>::element_type const *cxxbridge1$shared_ptr${}$get(::std::shared_ptr<{}> const &self) noexcept {{\",\n        inner, instance, inner,\n    );\n    writeln!(out, \"  return self.get();\");\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void cxxbridge1$shared_ptr${}$drop(::std::shared_ptr<{}> *self) noexcept {{\",\n        instance, inner,\n    );\n    writeln!(out, \"  self->~shared_ptr();\");\n    writeln!(out, \"}}\");\n}\n\nfn write_weak_ptr(out: &mut OutFile, key: &NamedImplKey) {\n    let inner = stringify_type(key.inner, out.types);\n    let instance = &key.symbol;\n\n    out.include.new = true;\n    out.include.utility = true;\n    out.pragma.dollar_in_identifier = true;\n    out.pragma.missing_declarations = true;\n\n    writeln!(\n        out,\n        \"static_assert(sizeof(::std::weak_ptr<{}>) == 2 * sizeof(void *), \\\"\\\");\",\n        inner,\n    );\n    writeln!(\n        out,\n        \"static_assert(alignof(::std::weak_ptr<{}>) == alignof(void *), \\\"\\\");\",\n        inner,\n    );\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void cxxbridge1$weak_ptr${}$null(::std::weak_ptr<{}> *ptr) noexcept {{\",\n        instance, inner,\n    );\n    writeln!(out, \"  ::new (ptr) ::std::weak_ptr<{}>();\", inner);\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void cxxbridge1$weak_ptr${}$clone(::std::weak_ptr<{}> const &self, ::std::weak_ptr<{}> *ptr) noexcept {{\",\n        instance, inner, inner,\n    );\n    writeln!(out, \"  ::new (ptr) ::std::weak_ptr<{}>(self);\", inner);\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void cxxbridge1$weak_ptr${}$downgrade(::std::shared_ptr<{}> const &shared, ::std::weak_ptr<{}> *weak) noexcept {{\",\n        instance, inner, inner,\n    );\n    writeln!(out, \"  ::new (weak) ::std::weak_ptr<{}>(shared);\", inner);\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void cxxbridge1$weak_ptr${}$upgrade(::std::weak_ptr<{}> const &weak, ::std::shared_ptr<{}> *shared) noexcept {{\",\n        instance, inner, inner,\n    );\n    writeln!(\n        out,\n        \"  ::new (shared) ::std::shared_ptr<{}>(weak.lock());\",\n        inner,\n    );\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"void cxxbridge1$weak_ptr${}$drop(::std::weak_ptr<{}> *self) noexcept {{\",\n        instance, inner,\n    );\n    writeln!(out, \"  self->~weak_ptr();\");\n    writeln!(out, \"}}\");\n}\n\nfn write_cxx_vector(out: &mut OutFile, key: &NamedImplKey) {\n    let inner = stringify_type(key.inner, out.types);\n    let instance = &key.symbol;\n\n    out.include.cstddef = true;\n    out.include.utility = true;\n    out.builtin.destroy = true;\n    out.builtin.vector = true;\n    out.pragma.dollar_in_identifier = true;\n    out.pragma.missing_declarations = true;\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"::std::vector<{}> *cxxbridge1$std$vector${}$new() noexcept {{\",\n        inner, instance,\n    );\n    writeln!(out, \"  return new ::std::vector<{}>();\", inner);\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"::std::size_t cxxbridge1$std$vector${}$size(::std::vector<{}> const &s) noexcept {{\",\n        instance, inner,\n    );\n    writeln!(out, \"  return s.size();\");\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"::std::size_t cxxbridge1$std$vector${}$capacity(::std::vector<{}> const &s) noexcept {{\",\n        instance, inner,\n    );\n    writeln!(out, \"  return s.capacity();\");\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"{} *cxxbridge1$std$vector${}$get_unchecked(::std::vector<{}> *s, ::std::size_t pos) noexcept {{\",\n        inner, instance, inner,\n    );\n    writeln!(out, \"  return &(*s)[pos];\");\n    writeln!(out, \"}}\");\n\n    begin_function_definition(out);\n    writeln!(\n        out,\n        \"bool cxxbridge1$std$vector${}$reserve(::std::vector<{}> *s, ::std::size_t new_cap) noexcept {{\",\n        instance, inner,\n    );\n    writeln!(\n        out,\n        \"  return ::rust::if_move_constructible<{}>::reserve(*s, new_cap);\",\n        inner,\n    );\n    writeln!(out, \"}}\");\n\n    if out.types.is_maybe_trivial(key.inner) {\n        begin_function_definition(out);\n        writeln!(\n            out,\n            \"void cxxbridge1$std$vector${}$push_back(::std::vector<{}> *v, {} *value) noexcept {{\",\n            instance, inner, inner,\n        );\n        writeln!(out, \"  v->push_back(::std::move(*value));\");\n        writeln!(out, \"  ::rust::destroy(value);\");\n        writeln!(out, \"}}\");\n\n        begin_function_definition(out);\n        writeln!(\n            out,\n            \"void cxxbridge1$std$vector${}$pop_back(::std::vector<{}> *v, {} *out) noexcept {{\",\n            instance, inner, inner,\n        );\n        writeln!(out, \"  ::new (out) {}(::std::move(v->back()));\", inner);\n        writeln!(out, \"  v->pop_back();\");\n        writeln!(out, \"}}\");\n    }\n\n    out.include.memory = true;\n    write_unique_ptr_common(out, key.outer);\n}\n"
  },
  {
    "path": "include/cxx.h",
    "content": "#pragma once\n#include <algorithm>\n#include <array>\n#include <cassert>\n#include <cstddef>\n#include <cstdint>\n#include <exception>\n#include <initializer_list>\n#include <iosfwd>\n#include <iterator>\n#include <new>\n#include <stdexcept>\n#include <string>\n#include <type_traits>\n#include <utility>\n#include <vector>\n#if defined(_WIN32)\n#include <basetsd.h>\n#else\n#include <sys/types.h>\n#endif\n\n#if __cplusplus >= 201703L\n#include <string_view>\n#endif\n\n#if __cplusplus >= 202002L\n#include <ranges>\n#endif\n\nnamespace rust {\ninline namespace cxxbridge1 {\n\nstruct unsafe_bitcopy_t;\n\nnamespace {\ntemplate <typename T>\nclass impl;\n}\n\n#ifndef CXXBRIDGE1_RUST_STRING\n#define CXXBRIDGE1_RUST_STRING\n// https://cxx.rs/binding/string.html\nclass String final {\npublic:\n  String() noexcept;\n  String(const String &) noexcept;\n  String(String &&) noexcept;\n  ~String() noexcept;\n\n  String(const std::string &);\n  String(const char *);\n  String(const char *, std::size_t);\n  String(const char16_t *);\n  String(const char16_t *, std::size_t);\n#ifdef __cpp_char8_t\n  String(const char8_t *s);\n  String(const char8_t *s, std::size_t len);\n#endif\n\n  // Replace invalid Unicode data with the replacement character (U+FFFD).\n  static String lossy(const std::string &) noexcept;\n  static String lossy(const char *) noexcept;\n  static String lossy(const char *, std::size_t) noexcept;\n  static String lossy(const char16_t *) noexcept;\n  static String lossy(const char16_t *, std::size_t) noexcept;\n\n  String &operator=(const String &) & noexcept;\n  String &operator=(String &&) & noexcept;\n\n  explicit operator std::string() const;\n\n  // Note: no null terminator.\n  const char *data() const noexcept;\n  std::size_t size() const noexcept;\n  std::size_t length() const noexcept;\n  bool empty() const noexcept;\n\n  const char *c_str() noexcept;\n\n  std::size_t capacity() const noexcept;\n  void reserve(size_t new_cap) noexcept;\n\n  using iterator = char *;\n  iterator begin() noexcept;\n  iterator end() noexcept;\n\n  using const_iterator = const char *;\n  const_iterator begin() const noexcept;\n  const_iterator end() const noexcept;\n  const_iterator cbegin() const noexcept;\n  const_iterator cend() const noexcept;\n\n  bool operator==(const String &) const noexcept;\n  bool operator!=(const String &) const noexcept;\n  bool operator<(const String &) const noexcept;\n  bool operator<=(const String &) const noexcept;\n  bool operator>(const String &) const noexcept;\n  bool operator>=(const String &) const noexcept;\n\n  void swap(String &) noexcept;\n\n  // Internal API only intended for the cxxbridge code generator.\n  String(unsafe_bitcopy_t, const String &) noexcept;\n\nprivate:\n  struct lossy_t;\n  String(lossy_t, const char *, std::size_t) noexcept;\n  String(lossy_t, const char16_t *, std::size_t) noexcept;\n  friend void swap(String &lhs, String &rhs) noexcept { lhs.swap(rhs); }\n\n  // Size and alignment statically verified by rust_string.rs.\n  std::array<std::uintptr_t, 3> repr;\n};\n#endif // CXXBRIDGE1_RUST_STRING\n\n#ifndef CXXBRIDGE1_RUST_STR\n#define CXXBRIDGE1_RUST_STR\n// https://cxx.rs/binding/str.html\nclass Str final {\npublic:\n  Str() noexcept;\n  Str(const String &) noexcept;\n  Str(const std::string &);\n  Str(const char *);\n  Str(const char *, std::size_t);\n\n  Str &operator=(const Str &) & noexcept = default;\n\n  explicit operator std::string() const;\n#if __cplusplus >= 201703L\n  explicit operator std::string_view() const;\n#endif\n\n  // Note: no null terminator.\n  const char *data() const noexcept;\n  std::size_t size() const noexcept;\n  std::size_t length() const noexcept;\n  bool empty() const noexcept;\n\n  // Important in order for System V ABI to pass in registers.\n  Str(const Str &) noexcept = default;\n  ~Str() noexcept = default;\n\n  using iterator = const char *;\n  using const_iterator = const char *;\n  const_iterator begin() const noexcept;\n  const_iterator end() const noexcept;\n  const_iterator cbegin() const noexcept;\n  const_iterator cend() const noexcept;\n\n  bool operator==(const Str &) const noexcept;\n  bool operator!=(const Str &) const noexcept;\n  bool operator<(const Str &) const noexcept;\n  bool operator<=(const Str &) const noexcept;\n  bool operator>(const Str &) const noexcept;\n  bool operator>=(const Str &) const noexcept;\n\n  void swap(Str &) noexcept;\n\nprivate:\n  class uninit;\n  Str(uninit) noexcept;\n  friend impl<Str>;\n\n  std::array<std::uintptr_t, 2> repr;\n};\n#endif // CXXBRIDGE1_RUST_STR\n\n#ifndef CXXBRIDGE1_RUST_SLICE\nnamespace detail {\ntemplate <bool>\nstruct copy_assignable_if {};\n\ntemplate <>\nstruct copy_assignable_if<false> {\n  copy_assignable_if() noexcept = default;\n  copy_assignable_if(const copy_assignable_if &) noexcept = default;\n  copy_assignable_if &operator=(const copy_assignable_if &) & noexcept = delete;\n  copy_assignable_if &operator=(copy_assignable_if &&) & noexcept = default;\n};\n} // namespace detail\n\n// https://cxx.rs/binding/slice.html\ntemplate <typename T>\nclass Slice final\n    : private detail::copy_assignable_if<std::is_const<T>::value> {\npublic:\n  using value_type = T;\n\n  Slice() noexcept;\n  Slice(T *, std::size_t count) noexcept;\n\n  template <typename C>\n  explicit Slice(C &c) : Slice(c.data(), c.size()) {}\n\n  Slice &operator=(const Slice<T> &) & noexcept = default;\n  Slice &operator=(Slice<T> &&) & noexcept = default;\n\n  T *data() const noexcept;\n  std::size_t size() const noexcept;\n  std::size_t length() const noexcept;\n  bool empty() const noexcept;\n\n  T &operator[](std::size_t n) const noexcept;\n  T &at(std::size_t n) const;\n  T &front() const noexcept;\n  T &back() const noexcept;\n\n  // Important in order for System V ABI to pass in registers.\n  Slice(const Slice<T> &) noexcept = default;\n  ~Slice() noexcept = default;\n\n  class iterator;\n  iterator begin() const noexcept;\n  iterator end() const noexcept;\n\n  void swap(Slice &) noexcept;\n\nprivate:\n  class uninit;\n  Slice(uninit) noexcept;\n  friend impl<Slice>;\n  friend void sliceInit(void *, const void *, std::size_t) noexcept;\n  friend void *slicePtr(const void *) noexcept;\n  friend std::size_t sliceLen(const void *) noexcept;\n\n  std::array<std::uintptr_t, 2> repr;\n};\n\n#ifdef __cpp_deduction_guides\ntemplate <typename C>\nexplicit Slice(C &c)\n    -> Slice<std::remove_reference_t<decltype(*std::declval<C>().data())>>;\n#endif // __cpp_deduction_guides\n\ntemplate <typename T>\nclass Slice<T>::iterator final {\npublic:\n#if __cplusplus >= 202002L\n  using iterator_category = std::contiguous_iterator_tag;\n#else\n  using iterator_category = std::random_access_iterator_tag;\n#endif\n  using value_type = T;\n  using difference_type = std::ptrdiff_t;\n  using pointer = typename std::add_pointer<T>::type;\n  using reference = typename std::add_lvalue_reference<T>::type;\n\n  reference operator*() const noexcept;\n  pointer operator->() const noexcept;\n  reference operator[](difference_type) const noexcept;\n\n  iterator &operator++() noexcept;\n  iterator operator++(int) noexcept;\n  iterator &operator--() noexcept;\n  iterator operator--(int) noexcept;\n\n  iterator &operator+=(difference_type) noexcept;\n  iterator &operator-=(difference_type) noexcept;\n  iterator operator+(difference_type) const noexcept;\n  friend inline iterator operator+(difference_type lhs, iterator rhs) noexcept {\n    return rhs + lhs;\n  }\n  iterator operator-(difference_type) const noexcept;\n  difference_type operator-(const iterator &) const noexcept;\n\n  bool operator==(const iterator &) const noexcept;\n  bool operator!=(const iterator &) const noexcept;\n  bool operator<(const iterator &) const noexcept;\n  bool operator<=(const iterator &) const noexcept;\n  bool operator>(const iterator &) const noexcept;\n  bool operator>=(const iterator &) const noexcept;\n\nprivate:\n  friend class Slice;\n  void *pos;\n  std::size_t stride;\n};\n\n#if __cplusplus >= 202002L\nstatic_assert(std::ranges::contiguous_range<rust::Slice<const uint8_t>>);\nstatic_assert(std::contiguous_iterator<rust::Slice<const uint8_t>::iterator>);\n#endif\n\n#endif // CXXBRIDGE1_RUST_SLICE\n\n#ifndef CXXBRIDGE1_RUST_BOX\n// https://cxx.rs/binding/box.html\ntemplate <typename T>\nclass Box final {\npublic:\n  using element_type = T;\n  using const_pointer =\n      typename std::add_pointer<typename std::add_const<T>::type>::type;\n  using pointer = typename std::add_pointer<T>::type;\n\n  Box() = delete;\n  Box(Box &&) noexcept;\n  ~Box() noexcept;\n\n  explicit Box(const T &);\n  explicit Box(T &&);\n\n  Box &operator=(Box &&) & noexcept;\n\n  const T *operator->() const noexcept;\n  const T &operator*() const noexcept;\n  T *operator->() noexcept;\n  T &operator*() noexcept;\n\n  template <typename... Fields>\n  static Box in_place(Fields &&...);\n\n  void swap(Box &) noexcept;\n\n  // Important: requires that `raw` came from an into_raw call. Do not pass a\n  // pointer from `new` or any other source.\n  static Box from_raw(T *) noexcept;\n\n  T *into_raw() noexcept;\n\n  /* Deprecated */ using value_type = element_type;\n\nprivate:\n  class uninit;\n  class allocation;\n  Box(uninit) noexcept;\n  void drop() noexcept;\n\n  friend void swap(Box &lhs, Box &rhs) noexcept { lhs.swap(rhs); }\n\n  T *ptr;\n};\n#endif // CXXBRIDGE1_RUST_BOX\n\n#ifndef CXXBRIDGE1_RUST_VEC\n// https://cxx.rs/binding/vec.html\ntemplate <typename T>\nclass Vec final {\npublic:\n  using value_type = T;\n\n  Vec() noexcept;\n  Vec(std::initializer_list<T>);\n  Vec(const Vec &);\n  Vec(Vec &&) noexcept;\n  ~Vec() noexcept;\n\n  Vec &operator=(Vec &&) & noexcept;\n  Vec &operator=(const Vec &) &;\n\n  std::size_t size() const noexcept;\n  bool empty() const noexcept;\n  const T *data() const noexcept;\n  T *data() noexcept;\n  std::size_t capacity() const noexcept;\n\n  const T &operator[](std::size_t n) const noexcept;\n  const T &at(std::size_t n) const;\n  const T &front() const noexcept;\n  const T &back() const noexcept;\n\n  T &operator[](std::size_t n) noexcept;\n  T &at(std::size_t n);\n  T &front() noexcept;\n  T &back() noexcept;\n\n  void reserve(std::size_t new_cap);\n  void push_back(const T &value);\n  void push_back(T &&value);\n  template <typename... Args>\n  void emplace_back(Args &&...args);\n  void truncate(std::size_t len);\n  void clear();\n\n  using iterator = typename Slice<T>::iterator;\n  iterator begin() noexcept;\n  iterator end() noexcept;\n\n  using const_iterator = typename Slice<const T>::iterator;\n  const_iterator begin() const noexcept;\n  const_iterator end() const noexcept;\n  const_iterator cbegin() const noexcept;\n  const_iterator cend() const noexcept;\n\n  void swap(Vec &) noexcept;\n\n  // Internal API only intended for the cxxbridge code generator.\n  Vec(unsafe_bitcopy_t, const Vec &) noexcept;\n\nprivate:\n  void reserve_total(std::size_t new_cap) noexcept;\n  void set_len(std::size_t len) noexcept;\n  void drop() noexcept;\n\n  friend void swap(Vec &lhs, Vec &rhs) noexcept { lhs.swap(rhs); }\n\n  // Size and alignment statically verified by rust_vec.rs.\n  std::array<std::uintptr_t, 3> repr;\n};\n#endif // CXXBRIDGE1_RUST_VEC\n\n#ifndef CXXBRIDGE1_RUST_FN\n// https://cxx.rs/binding/fn.html\ntemplate <typename Signature>\nclass Fn;\n\ntemplate <typename Ret, typename... Args>\nclass Fn<Ret(Args...)> final {\npublic:\n  Ret operator()(Args... args) const noexcept;\n  Fn operator*() const noexcept;\n\nprivate:\n  Ret (*trampoline)(Args..., void *fn) noexcept;\n  void *fn;\n};\n#endif // CXXBRIDGE1_RUST_FN\n\n#ifndef CXXBRIDGE1_RUST_ERROR\n#define CXXBRIDGE1_RUST_ERROR\n// https://cxx.rs/binding/result.html\nclass Error final : public std::exception {\npublic:\n  Error(const Error &);\n  Error(Error &&) noexcept;\n  ~Error() noexcept override;\n\n  Error &operator=(const Error &) &;\n  Error &operator=(Error &&) & noexcept;\n\n  const char *what() const noexcept override;\n\nprivate:\n  Error() noexcept = default;\n  friend impl<Error>;\n  const char *msg;\n  std::size_t len;\n};\n#endif // CXXBRIDGE1_RUST_ERROR\n\n#ifndef CXXBRIDGE1_RUST_ISIZE\n#define CXXBRIDGE1_RUST_ISIZE\n#if defined(_WIN32)\nusing isize = SSIZE_T;\n#else\nusing isize = ssize_t;\n#endif\n#endif // CXXBRIDGE1_RUST_ISIZE\n\nstd::ostream &operator<<(std::ostream &, const String &);\nstd::ostream &operator<<(std::ostream &, const Str &);\n\n#ifndef CXXBRIDGE1_RUST_OPAQUE\n#define CXXBRIDGE1_RUST_OPAQUE\n// Base class of generated opaque Rust types.\nclass Opaque {\npublic:\n  Opaque() = delete;\n  Opaque(const Opaque &) = delete;\n  ~Opaque() = delete;\n};\n#endif // CXXBRIDGE1_RUST_OPAQUE\n\ntemplate <typename T>\nstd::size_t size_of();\ntemplate <typename T>\nstd::size_t align_of();\n\n// IsRelocatable<T> is used in assertions that a C++ type passed by value\n// between Rust and C++ is soundly relocatable by Rust.\n//\n// There may be legitimate reasons to opt out of the check for support of types\n// that the programmer knows are soundly Rust-movable despite not being\n// recognized as such by the C++ type system due to a move constructor or\n// destructor. To opt out of the relocatability check, do either of the\n// following things in any header used by `include!` in the bridge.\n//\n//      --- if you define the type:\n//      struct MyType {\n//        ...\n//    +   using IsRelocatable = std::true_type;\n//      };\n//\n//      --- otherwise:\n//    + template <>\n//    + struct rust::IsRelocatable<MyType> : std::true_type {};\ntemplate <typename T>\nstruct IsRelocatable;\n\nusing u8 = std::uint8_t;\nusing u16 = std::uint16_t;\nusing u32 = std::uint32_t;\nusing u64 = std::uint64_t;\nusing usize = std::size_t; // see static asserts in cxx.cc\nusing i8 = std::int8_t;\nusing i16 = std::int16_t;\nusing i32 = std::int32_t;\nusing i64 = std::int64_t;\nusing f32 = float;\nusing f64 = double;\n\n// Snake case aliases for use in code that uses this style for type names.\nusing string = String;\nusing str = Str;\ntemplate <typename T>\nusing slice = Slice<T>;\ntemplate <typename T>\nusing box = Box<T>;\ntemplate <typename T>\nusing vec = Vec<T>;\nusing error = Error;\ntemplate <typename Signature>\nusing fn = Fn<Signature>;\ntemplate <typename T>\nusing is_relocatable = IsRelocatable<T>;\n\n\n\n////////////////////////////////////////////////////////////////////////////////\n/// end public API, begin implementation details\n\n#ifndef CXXBRIDGE1_PANIC\n#define CXXBRIDGE1_PANIC\ntemplate <typename Exception>\nvoid panic [[noreturn]] (const char *msg);\n#endif // CXXBRIDGE1_PANIC\n\n#ifndef CXXBRIDGE1_RUST_FN\n#define CXXBRIDGE1_RUST_FN\ntemplate <typename Ret, typename... Args>\nRet Fn<Ret(Args...)>::operator()(Args... args) const noexcept {\n  return (*this->trampoline)(std::forward<Args>(args)..., this->fn);\n}\n\ntemplate <typename Ret, typename... Args>\nFn<Ret(Args...)> Fn<Ret(Args...)>::operator*() const noexcept {\n  return *this;\n}\n#endif // CXXBRIDGE1_RUST_FN\n\n#ifndef CXXBRIDGE1_RUST_BITCOPY_T\n#define CXXBRIDGE1_RUST_BITCOPY_T\nstruct unsafe_bitcopy_t final {\n  explicit unsafe_bitcopy_t() = default;\n};\n#endif // CXXBRIDGE1_RUST_BITCOPY_T\n\n#ifndef CXXBRIDGE1_RUST_BITCOPY\n#define CXXBRIDGE1_RUST_BITCOPY\nconstexpr unsafe_bitcopy_t unsafe_bitcopy{};\n#endif // CXXBRIDGE1_RUST_BITCOPY\n\n#ifndef CXXBRIDGE1_RUST_SLICE\n#define CXXBRIDGE1_RUST_SLICE\ntemplate <typename T>\nSlice<T>::Slice() noexcept {\n  sliceInit(this, reinterpret_cast<void *>(align_of<T>()), 0);\n}\n\ntemplate <typename T>\nSlice<T>::Slice(T *s, std::size_t count) noexcept {\n  assert(s != nullptr || count == 0);\n  sliceInit(this,\n            s == nullptr && count == 0\n                ? reinterpret_cast<void *>(align_of<T>())\n                : const_cast<typename std::remove_const<T>::type *>(s),\n            count);\n}\n\ntemplate <typename T>\nT *Slice<T>::data() const noexcept {\n  return reinterpret_cast<T *>(slicePtr(this));\n}\n\ntemplate <typename T>\nstd::size_t Slice<T>::size() const noexcept {\n  return sliceLen(this);\n}\n\ntemplate <typename T>\nstd::size_t Slice<T>::length() const noexcept {\n  return this->size();\n}\n\ntemplate <typename T>\nbool Slice<T>::empty() const noexcept {\n  return this->size() == 0;\n}\n\ntemplate <typename T>\nT &Slice<T>::operator[](std::size_t n) const noexcept {\n  assert(n < this->size());\n  auto ptr = static_cast<char *>(slicePtr(this)) + size_of<T>() * n;\n  return *reinterpret_cast<T *>(ptr);\n}\n\ntemplate <typename T>\nT &Slice<T>::at(std::size_t n) const {\n  if (n >= this->size()) {\n    panic<std::out_of_range>(\"rust::Slice index out of range\");\n  }\n  return (*this)[n];\n}\n\ntemplate <typename T>\nT &Slice<T>::front() const noexcept {\n  assert(!this->empty());\n  return (*this)[0];\n}\n\ntemplate <typename T>\nT &Slice<T>::back() const noexcept {\n  assert(!this->empty());\n  return (*this)[this->size() - 1];\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator::reference\nSlice<T>::iterator::operator*() const noexcept {\n  return *static_cast<T *>(this->pos);\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator::pointer\nSlice<T>::iterator::operator->() const noexcept {\n  return static_cast<T *>(this->pos);\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator::reference Slice<T>::iterator::operator[](\n    typename Slice<T>::iterator::difference_type n) const noexcept {\n  auto ptr = static_cast<char *>(this->pos) + this->stride * n;\n  return *reinterpret_cast<T *>(ptr);\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator &Slice<T>::iterator::operator++() noexcept {\n  this->pos = static_cast<char *>(this->pos) + this->stride;\n  return *this;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator Slice<T>::iterator::operator++(int) noexcept {\n  auto ret = iterator(*this);\n  this->pos = static_cast<char *>(this->pos) + this->stride;\n  return ret;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator &Slice<T>::iterator::operator--() noexcept {\n  this->pos = static_cast<char *>(this->pos) - this->stride;\n  return *this;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator Slice<T>::iterator::operator--(int) noexcept {\n  auto ret = iterator(*this);\n  this->pos = static_cast<char *>(this->pos) - this->stride;\n  return ret;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator &Slice<T>::iterator::operator+=(\n    typename Slice<T>::iterator::difference_type n) noexcept {\n  this->pos = static_cast<char *>(this->pos) + this->stride * n;\n  return *this;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator &Slice<T>::iterator::operator-=(\n    typename Slice<T>::iterator::difference_type n) noexcept {\n  this->pos = static_cast<char *>(this->pos) - this->stride * n;\n  return *this;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator Slice<T>::iterator::operator+(\n    typename Slice<T>::iterator::difference_type n) const noexcept {\n  auto ret = iterator(*this);\n  ret.pos = static_cast<char *>(this->pos) + this->stride * n;\n  return ret;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator Slice<T>::iterator::operator-(\n    typename Slice<T>::iterator::difference_type n) const noexcept {\n  auto ret = iterator(*this);\n  ret.pos = static_cast<char *>(this->pos) - this->stride * n;\n  return ret;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator::difference_type\nSlice<T>::iterator::operator-(const iterator &other) const noexcept {\n  auto diff = std::distance(static_cast<char *>(other.pos),\n                            static_cast<char *>(this->pos));\n  return diff / static_cast<typename Slice<T>::iterator::difference_type>(\n                    this->stride);\n}\n\ntemplate <typename T>\nbool Slice<T>::iterator::operator==(const iterator &other) const noexcept {\n  return this->pos == other.pos;\n}\n\ntemplate <typename T>\nbool Slice<T>::iterator::operator!=(const iterator &other) const noexcept {\n  return this->pos != other.pos;\n}\n\ntemplate <typename T>\nbool Slice<T>::iterator::operator<(const iterator &other) const noexcept {\n  return this->pos < other.pos;\n}\n\ntemplate <typename T>\nbool Slice<T>::iterator::operator<=(const iterator &other) const noexcept {\n  return this->pos <= other.pos;\n}\n\ntemplate <typename T>\nbool Slice<T>::iterator::operator>(const iterator &other) const noexcept {\n  return this->pos > other.pos;\n}\n\ntemplate <typename T>\nbool Slice<T>::iterator::operator>=(const iterator &other) const noexcept {\n  return this->pos >= other.pos;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator Slice<T>::begin() const noexcept {\n  iterator it;\n  it.pos = slicePtr(this);\n  it.stride = size_of<T>();\n  return it;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator Slice<T>::end() const noexcept {\n  iterator it = this->begin();\n  it.pos = static_cast<char *>(it.pos) + it.stride * this->size();\n  return it;\n}\n\ntemplate <typename T>\nvoid Slice<T>::swap(Slice &rhs) noexcept {\n  std::swap(*this, rhs);\n}\n#endif // CXXBRIDGE1_RUST_SLICE\n\n#ifndef CXXBRIDGE1_RUST_BOX\n#define CXXBRIDGE1_RUST_BOX\ntemplate <typename T>\nclass Box<T>::uninit {};\n\ntemplate <typename T>\nclass Box<T>::allocation {\n  static T *alloc() noexcept;\n  static void dealloc(T *) noexcept;\n\npublic:\n  allocation() noexcept : ptr(alloc()) {}\n  ~allocation() noexcept {\n    if (this->ptr) {\n      dealloc(this->ptr);\n    }\n  }\n  T *ptr;\n};\n\ntemplate <typename T>\nBox<T>::Box(Box &&other) noexcept : ptr(other.ptr) {\n  other.ptr = nullptr;\n}\n\ntemplate <typename T>\nBox<T>::Box(const T &val) {\n  allocation alloc;\n  ::new (alloc.ptr) T(val);\n  this->ptr = alloc.ptr;\n  alloc.ptr = nullptr;\n}\n\ntemplate <typename T>\nBox<T>::Box(T &&val) {\n  allocation alloc;\n  ::new (alloc.ptr) T(std::move(val));\n  this->ptr = alloc.ptr;\n  alloc.ptr = nullptr;\n}\n\ntemplate <typename T>\nBox<T>::~Box() noexcept {\n  if (this->ptr) {\n    this->drop();\n  }\n}\n\ntemplate <typename T>\nBox<T> &Box<T>::operator=(Box &&other) & noexcept {\n  if (this->ptr) {\n    this->drop();\n  }\n  this->ptr = other.ptr;\n  other.ptr = nullptr;\n  return *this;\n}\n\ntemplate <typename T>\nconst T *Box<T>::operator->() const noexcept {\n  return this->ptr;\n}\n\ntemplate <typename T>\nconst T &Box<T>::operator*() const noexcept {\n  return *this->ptr;\n}\n\ntemplate <typename T>\nT *Box<T>::operator->() noexcept {\n  return this->ptr;\n}\n\ntemplate <typename T>\nT &Box<T>::operator*() noexcept {\n  return *this->ptr;\n}\n\ntemplate <typename T>\ntemplate <typename... Fields>\nBox<T> Box<T>::in_place(Fields &&...fields) {\n  allocation alloc;\n  auto ptr = alloc.ptr;\n  ::new (ptr) T{std::forward<Fields>(fields)...};\n  alloc.ptr = nullptr;\n  return from_raw(ptr);\n}\n\ntemplate <typename T>\nvoid Box<T>::swap(Box &rhs) noexcept {\n  using std::swap;\n  swap(this->ptr, rhs.ptr);\n}\n\ntemplate <typename T>\nBox<T> Box<T>::from_raw(T *raw) noexcept {\n  Box box = uninit{};\n  box.ptr = raw;\n  return box;\n}\n\ntemplate <typename T>\nT *Box<T>::into_raw() noexcept {\n  T *raw = this->ptr;\n  this->ptr = nullptr;\n  return raw;\n}\n\ntemplate <typename T>\nBox<T>::Box(uninit) noexcept {}\n#endif // CXXBRIDGE1_RUST_BOX\n\n#ifndef CXXBRIDGE1_RUST_VEC\n#define CXXBRIDGE1_RUST_VEC\ntemplate <typename T>\nVec<T>::Vec(std::initializer_list<T> init) : Vec{} {\n  this->reserve_total(init.size());\n  std::move(init.begin(), init.end(), std::back_inserter(*this));\n}\n\ntemplate <typename T>\nVec<T>::Vec(const Vec &other) : Vec() {\n  this->reserve_total(other.size());\n  std::copy(other.begin(), other.end(), std::back_inserter(*this));\n}\n\ntemplate <typename T>\nVec<T>::Vec(Vec &&other) noexcept : repr(other.repr) {\n  new (&other) Vec();\n}\n\ntemplate <typename T>\nVec<T>::~Vec() noexcept {\n  this->drop();\n}\n\ntemplate <typename T>\nVec<T> &Vec<T>::operator=(Vec &&other) & noexcept {\n  this->drop();\n  this->repr = other.repr;\n  new (&other) Vec();\n  return *this;\n}\n\ntemplate <typename T>\nVec<T> &Vec<T>::operator=(const Vec &other) & {\n  if (this != &other) {\n    this->drop();\n    new (this) Vec(other);\n  }\n  return *this;\n}\n\ntemplate <typename T>\nbool Vec<T>::empty() const noexcept {\n  return this->size() == 0;\n}\n\ntemplate <typename T>\nT *Vec<T>::data() noexcept {\n  return const_cast<T *>(const_cast<const Vec<T> *>(this)->data());\n}\n\ntemplate <typename T>\nconst T &Vec<T>::operator[](std::size_t n) const noexcept {\n  assert(n < this->size());\n  auto data = reinterpret_cast<const char *>(this->data());\n  return *reinterpret_cast<const T *>(data + n * size_of<T>());\n}\n\ntemplate <typename T>\nconst T &Vec<T>::at(std::size_t n) const {\n  if (n >= this->size()) {\n    panic<std::out_of_range>(\"rust::Vec index out of range\");\n  }\n  return (*this)[n];\n}\n\ntemplate <typename T>\nconst T &Vec<T>::front() const noexcept {\n  assert(!this->empty());\n  return (*this)[0];\n}\n\ntemplate <typename T>\nconst T &Vec<T>::back() const noexcept {\n  assert(!this->empty());\n  return (*this)[this->size() - 1];\n}\n\ntemplate <typename T>\nT &Vec<T>::operator[](std::size_t n) noexcept {\n  assert(n < this->size());\n  auto data = reinterpret_cast<char *>(this->data());\n  return *reinterpret_cast<T *>(data + n * size_of<T>());\n}\n\ntemplate <typename T>\nT &Vec<T>::at(std::size_t n) {\n  if (n >= this->size()) {\n    panic<std::out_of_range>(\"rust::Vec index out of range\");\n  }\n  return (*this)[n];\n}\n\ntemplate <typename T>\nT &Vec<T>::front() noexcept {\n  assert(!this->empty());\n  return (*this)[0];\n}\n\ntemplate <typename T>\nT &Vec<T>::back() noexcept {\n  assert(!this->empty());\n  return (*this)[this->size() - 1];\n}\n\ntemplate <typename T>\nvoid Vec<T>::reserve(std::size_t new_cap) {\n  this->reserve_total(new_cap);\n}\n\ntemplate <typename T>\nvoid Vec<T>::push_back(const T &value) {\n  this->emplace_back(value);\n}\n\ntemplate <typename T>\nvoid Vec<T>::push_back(T &&value) {\n  this->emplace_back(std::move(value));\n}\n\ntemplate <typename T>\ntemplate <typename... Args>\nvoid Vec<T>::emplace_back(Args &&...args) {\n  auto size = this->size();\n  this->reserve_total(size + 1);\n  ::new (reinterpret_cast<T *>(reinterpret_cast<char *>(this->data()) +\n                               size * size_of<T>()))\n      T(std::forward<Args>(args)...);\n  this->set_len(size + 1);\n}\n\ntemplate <typename T>\nvoid Vec<T>::clear() {\n  this->truncate(0);\n}\n\ntemplate <typename T>\ntypename Vec<T>::iterator Vec<T>::begin() noexcept {\n  return Slice<T>(this->data(), this->size()).begin();\n}\n\ntemplate <typename T>\ntypename Vec<T>::iterator Vec<T>::end() noexcept {\n  return Slice<T>(this->data(), this->size()).end();\n}\n\ntemplate <typename T>\ntypename Vec<T>::const_iterator Vec<T>::begin() const noexcept {\n  return this->cbegin();\n}\n\ntemplate <typename T>\ntypename Vec<T>::const_iterator Vec<T>::end() const noexcept {\n  return this->cend();\n}\n\ntemplate <typename T>\ntypename Vec<T>::const_iterator Vec<T>::cbegin() const noexcept {\n  return Slice<const T>(this->data(), this->size()).begin();\n}\n\ntemplate <typename T>\ntypename Vec<T>::const_iterator Vec<T>::cend() const noexcept {\n  return Slice<const T>(this->data(), this->size()).end();\n}\n\ntemplate <typename T>\nvoid Vec<T>::swap(Vec &rhs) noexcept {\n  using std::swap;\n  swap(this->repr, rhs.repr);\n}\n\n// Internal API only intended for the cxxbridge code generator.\ntemplate <typename T>\nVec<T>::Vec(unsafe_bitcopy_t, const Vec &bits) noexcept : repr(bits.repr) {}\n#endif // CXXBRIDGE1_RUST_VEC\n\n#ifndef CXXBRIDGE1_IS_COMPLETE\n#define CXXBRIDGE1_IS_COMPLETE\nnamespace detail {\nnamespace {\ntemplate <typename T, typename = std::size_t>\nstruct is_complete : std::false_type {};\ntemplate <typename T>\nstruct is_complete<T, decltype(sizeof(T))> : std::true_type {};\n} // namespace\n} // namespace detail\n#endif // CXXBRIDGE1_IS_COMPLETE\n\n#ifndef CXXBRIDGE1_LAYOUT\n#define CXXBRIDGE1_LAYOUT\nclass layout {\n  template <typename T>\n  friend std::size_t size_of();\n  template <typename T>\n  friend std::size_t align_of();\n  template <typename T>\n  static typename std::enable_if<std::is_base_of<Opaque, T>::value,\n                                 std::size_t>::type\n  do_size_of() {\n    return T::layout::size();\n  }\n  template <typename T>\n  static typename std::enable_if<!std::is_base_of<Opaque, T>::value,\n                                 std::size_t>::type\n  do_size_of() {\n    return sizeof(T);\n  }\n  template <typename T>\n  static\n      typename std::enable_if<detail::is_complete<T>::value, std::size_t>::type\n      size_of() {\n    return do_size_of<T>();\n  }\n  template <typename T>\n  static typename std::enable_if<std::is_base_of<Opaque, T>::value,\n                                 std::size_t>::type\n  do_align_of() {\n    return T::layout::align();\n  }\n  template <typename T>\n  static typename std::enable_if<!std::is_base_of<Opaque, T>::value,\n                                 std::size_t>::type\n  do_align_of() {\n    return alignof(T);\n  }\n  template <typename T>\n  static\n      typename std::enable_if<detail::is_complete<T>::value, std::size_t>::type\n      align_of() {\n    return do_align_of<T>();\n  }\n};\n\ntemplate <typename T>\nstd::size_t size_of() {\n  return layout::size_of<T>();\n}\n\ntemplate <typename T>\nstd::size_t align_of() {\n  return layout::align_of<T>();\n}\n#endif // CXXBRIDGE1_LAYOUT\n\n#ifndef CXXBRIDGE1_RELOCATABLE\n#define CXXBRIDGE1_RELOCATABLE\nnamespace detail {\ntemplate <typename... Ts>\nstruct make_void {\n  using type = void;\n};\n\ntemplate <typename... Ts>\nusing void_t = typename make_void<Ts...>::type;\n\ntemplate <typename Void, template <typename...> class, typename...>\nstruct detect : std::false_type {};\ntemplate <template <typename...> class T, typename... A>\nstruct detect<void_t<T<A...>>, T, A...> : std::true_type {};\n\ntemplate <template <typename...> class T, typename... A>\nusing is_detected = detect<void, T, A...>;\n\ntemplate <typename T>\nusing detect_IsRelocatable = typename T::IsRelocatable;\n\ntemplate <typename T>\nstruct get_IsRelocatable\n    : std::is_same<typename T::IsRelocatable, std::true_type> {};\n} // namespace detail\n\ntemplate <typename T>\nstruct IsRelocatable\n    : std::conditional<\n          detail::is_detected<detail::detect_IsRelocatable, T>::value,\n          detail::get_IsRelocatable<T>,\n          std::integral_constant<\n              bool, std::is_trivially_move_constructible<T>::value &&\n                        std::is_trivially_destructible<T>::value>>::type {};\n#endif // CXXBRIDGE1_RELOCATABLE\n\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "macro/Cargo.toml",
    "content": "[package]\nname = \"cxxbridge-macro\"\nversion = \"1.0.194\"\nauthors = [\"David Tolnay <dtolnay@gmail.com>\"]\ncategories = [\"development-tools::ffi\"]\ndescription = \"Implementation detail of the `cxx` crate.\"\nedition = \"2021\"\nexclude = [\"build.rs\", \"README.md\"]\nhomepage = \"https://cxx.rs\"\nkeywords = [\"ffi\"]\nlicense = \"MIT OR Apache-2.0\"\nrepository = \"https://github.com/dtolnay/cxx\"\nrust-version = \"1.85\"\n\n[lib]\nproc-macro = true\n\n[dependencies]\nindexmap = \"2.9.0\"\nproc-macro2 = \"1.0.74\"\nquote = \"1.0.35\"\nsyn = { version = \"2.0.46\", features = [\"full\"] }\n\n[dev-dependencies]\ncxx = { version = \"1.0\", path = \"..\" }\nprettyplease = \"0.2.35\"\n\n[package.metadata.docs.rs]\ntargets = [\"x86_64-unknown-linux-gnu\"]\nrustdoc-args = [\n    \"--generate-link-to-definition\",\n    \"--generate-macro-expansion\",\n    \"--extern-html-root-url=core=https://doc.rust-lang.org\",\n    \"--extern-html-root-url=alloc=https://doc.rust-lang.org\",\n    \"--extern-html-root-url=std=https://doc.rust-lang.org\",\n    \"--extern-html-root-url=proc_macro=https://doc.rust-lang.org\",\n]\n"
  },
  {
    "path": "macro/README.md",
    "content": "This directory contains CXX's Rust code generator, which is a procedural macro.\nUsers won't depend on this crate directly. Instead they'll invoke its macro\nthrough the reexport in the main `cxx` crate.\n"
  },
  {
    "path": "macro/build.rs",
    "content": "include!(\"../tools/cargo/build.rs\");\n"
  },
  {
    "path": "macro/src/attrs.rs",
    "content": "use crate::syntax::attrs::OtherAttrs;\nuse proc_macro2::TokenStream;\nuse quote::ToTokens;\nuse syn::Attribute;\n\nimpl OtherAttrs {\n    pub(crate) fn all(&self) -> PrintOtherAttrs {\n        PrintOtherAttrs {\n            attrs: self,\n            cfg: true,\n            lint: true,\n            passthrough: true,\n        }\n    }\n\n    pub(crate) fn cfg(&self) -> PrintOtherAttrs {\n        PrintOtherAttrs {\n            attrs: self,\n            cfg: true,\n            lint: false,\n            passthrough: false,\n        }\n    }\n\n    pub(crate) fn cfg_and_lint(&self) -> PrintOtherAttrs {\n        PrintOtherAttrs {\n            attrs: self,\n            cfg: true,\n            lint: true,\n            passthrough: false,\n        }\n    }\n}\n\npub(crate) struct PrintOtherAttrs<'a> {\n    attrs: &'a OtherAttrs,\n    cfg: bool,\n    lint: bool,\n    passthrough: bool,\n}\n\nimpl<'a> ToTokens for PrintOtherAttrs<'a> {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        if self.cfg {\n            print_attrs_as_outer(&self.attrs.cfg, tokens);\n        }\n        if self.lint {\n            print_attrs_as_outer(&self.attrs.lint, tokens);\n        }\n        if self.passthrough {\n            print_attrs_as_outer(&self.attrs.passthrough, tokens);\n        }\n    }\n}\n\nfn print_attrs_as_outer(attrs: &[Attribute], tokens: &mut TokenStream) {\n    for attr in attrs {\n        let Attribute {\n            pound_token,\n            style,\n            bracket_token,\n            meta,\n        } = attr;\n        pound_token.to_tokens(tokens);\n        let _ = style; // ignore; render outer and inner attrs both as outer\n        bracket_token.surround(tokens, |tokens| meta.to_tokens(tokens));\n    }\n}\n"
  },
  {
    "path": "macro/src/cfg.rs",
    "content": "use crate::syntax::cfg::{CfgExpr, ComputedCfg};\nuse proc_macro2::{Delimiter, Group, Ident, Span, TokenStream};\nuse quote::{ToTokens, TokenStreamExt as _};\nuse syn::{token, AttrStyle, Attribute, MacroDelimiter, Meta, MetaList, Path, Token};\n\nimpl<'a> ComputedCfg<'a> {\n    pub(crate) fn into_attr(&self) -> Option<Attribute> {\n        if let ComputedCfg::Leaf(CfgExpr::Unconditional) = self {\n            None\n        } else {\n            let span = Span::call_site();\n            Some(Attribute {\n                pound_token: Token![#](span),\n                style: AttrStyle::Outer,\n                bracket_token: token::Bracket(span),\n                meta: Meta::List(MetaList {\n                    path: Path::from(Ident::new(\"cfg\", span)),\n                    delimiter: MacroDelimiter::Paren(token::Paren(span)),\n                    tokens: self.as_meta().into_token_stream(),\n                }),\n            })\n        }\n    }\n\n    pub(crate) fn as_meta(&self) -> impl ToTokens + '_ {\n        Print {\n            cfg: self,\n            span: Span::call_site(),\n        }\n    }\n}\n\nstruct Print<'a, Cfg> {\n    cfg: &'a Cfg,\n    span: Span,\n}\n\nimpl<'a> ToTokens for Print<'a, CfgExpr> {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let span = self.span;\n        let print = |cfg| Print { cfg, span };\n        match self.cfg {\n            CfgExpr::Unconditional => unreachable!(),\n            CfgExpr::Eq(ident, value) => {\n                ident.to_tokens(tokens);\n                if let Some(value) = value {\n                    Token![=](span).to_tokens(tokens);\n                    value.to_tokens(tokens);\n                }\n            }\n            CfgExpr::All(inner) => {\n                tokens.append(Ident::new(\"all\", span));\n                let mut group = TokenStream::new();\n                group.append_separated(inner.iter().map(print), Token![,](span));\n                tokens.append(Group::new(Delimiter::Parenthesis, group));\n            }\n            CfgExpr::Any(inner) => {\n                tokens.append(Ident::new(\"any\", span));\n                let mut group = TokenStream::new();\n                group.append_separated(inner.iter().map(print), Token![,](span));\n                tokens.append(Group::new(Delimiter::Parenthesis, group));\n            }\n            CfgExpr::Not(inner) => {\n                tokens.append(Ident::new(\"not\", span));\n                let group = print(inner).into_token_stream();\n                tokens.append(Group::new(Delimiter::Parenthesis, group));\n            }\n        }\n    }\n}\n\nimpl<'a> ToTokens for Print<'a, ComputedCfg<'a>> {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let span = self.span;\n        match *self.cfg {\n            ComputedCfg::Leaf(cfg) => Print { cfg, span }.to_tokens(tokens),\n            ComputedCfg::All(ref inner) => {\n                tokens.append(Ident::new(\"all\", span));\n                let mut group = TokenStream::new();\n                group.append_separated(\n                    inner.iter().map(|&cfg| Print { cfg, span }),\n                    Token![,](span),\n                );\n                tokens.append(Group::new(Delimiter::Parenthesis, group));\n            }\n            ComputedCfg::Any(ref inner) => {\n                tokens.append(Ident::new(\"any\", span));\n                let mut group = TokenStream::new();\n                group\n                    .append_separated(inner.iter().map(|cfg| Print { cfg, span }), Token![,](span));\n                tokens.append(Group::new(Delimiter::Parenthesis, group));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "macro/src/derive.rs",
    "content": "use crate::syntax::{derive, Enum, Struct};\nuse proc_macro2::{Ident, Span, TokenStream};\nuse quote::{quote, quote_spanned, ToTokens};\n\npub(crate) use crate::syntax::derive::*;\n\npub(crate) fn expand_struct(\n    strct: &Struct,\n    actual_derives: &mut Option<TokenStream>,\n) -> TokenStream {\n    let mut expanded = TokenStream::new();\n    let mut traits = Vec::new();\n\n    for derive in &strct.derives {\n        let span = derive.span;\n        match derive.what {\n            Trait::BitAnd => unreachable!(),\n            Trait::BitOr => unreachable!(),\n            Trait::BitXor => unreachable!(),\n            Trait::Copy => expanded.extend(struct_copy(strct, span)),\n            Trait::Clone => expanded.extend(struct_clone(strct, span)),\n            Trait::Debug => expanded.extend(struct_debug(strct, span)),\n            Trait::Default => expanded.extend(struct_default(strct, span)),\n            Trait::Eq => traits.push(quote_spanned!(span=> ::cxx::core::cmp::Eq)),\n            Trait::ExternType => unreachable!(),\n            Trait::Hash => traits.push(quote_spanned!(span=> ::cxx::core::hash::Hash)),\n            Trait::Ord => expanded.extend(struct_ord(strct, span)),\n            Trait::PartialEq => traits.push(quote_spanned!(span=> ::cxx::core::cmp::PartialEq)),\n            Trait::PartialOrd => expanded.extend(struct_partial_ord(strct, span)),\n            Trait::Serialize => traits.push(quote_spanned!(span=> ::serde::Serialize)),\n            Trait::Deserialize => traits.push(quote_spanned!(span=> ::serde::Deserialize)),\n        }\n    }\n\n    if traits.is_empty() {\n        *actual_derives = None;\n    } else {\n        *actual_derives = Some(quote!(#[derive(#(#traits),*)]));\n    }\n\n    expanded\n}\n\npub(crate) fn expand_enum(enm: &Enum, actual_derives: &mut Option<TokenStream>) -> TokenStream {\n    let mut expanded = TokenStream::new();\n    let mut traits = Vec::new();\n    let mut has_copy = false;\n    let mut has_clone = false;\n    let mut has_eq = false;\n    let mut has_partial_eq = false;\n\n    for derive in &enm.derives {\n        let span = derive.span;\n        match derive.what {\n            Trait::BitAnd => expanded.extend(enum_bitand(enm, span)),\n            Trait::BitOr => expanded.extend(enum_bitor(enm, span)),\n            Trait::BitXor => expanded.extend(enum_bitxor(enm, span)),\n            Trait::Copy => {\n                expanded.extend(enum_copy(enm, span));\n                has_copy = true;\n            }\n            Trait::Clone => {\n                expanded.extend(enum_clone(enm, span));\n                has_clone = true;\n            }\n            Trait::Debug => expanded.extend(enum_debug(enm, span)),\n            Trait::Default => expanded.extend(enum_default(enm, span)),\n            Trait::Eq => {\n                traits.push(quote_spanned!(span=> ::cxx::core::cmp::Eq));\n                has_eq = true;\n            }\n            Trait::ExternType => unreachable!(),\n            Trait::Hash => traits.push(quote_spanned!(span=> ::cxx::core::hash::Hash)),\n            Trait::Ord => expanded.extend(enum_ord(enm, span)),\n            Trait::PartialEq => {\n                traits.push(quote_spanned!(span=> ::cxx::core::cmp::PartialEq));\n                has_partial_eq = true;\n            }\n            Trait::PartialOrd => expanded.extend(enum_partial_ord(enm, span)),\n            Trait::Serialize => traits.push(quote_spanned!(span=> ::serde::Serialize)),\n            Trait::Deserialize => traits.push(quote_spanned!(span=> ::serde::Deserialize)),\n        }\n    }\n\n    let span = enm.name.rust.span();\n    if !has_copy {\n        expanded.extend(enum_copy(enm, span));\n    }\n    if !has_clone {\n        expanded.extend(enum_clone(enm, span));\n    }\n    if !has_eq {\n        // Required to be derived in order for the enum's \"variants\" to be\n        // usable in patterns.\n        traits.push(quote!(::cxx::core::cmp::Eq));\n    }\n    if !has_partial_eq {\n        traits.push(quote!(::cxx::core::cmp::PartialEq));\n    }\n\n    *actual_derives = Some(quote!(#[derive(#(#traits),*)]));\n\n    expanded\n}\n\nfn struct_copy(strct: &Struct, span: Span) -> TokenStream {\n    let ident = &strct.name.rust;\n    let generics = &strct.generics;\n    let cfg_and_lint_attrs = strct.attrs.cfg_and_lint();\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        impl #generics ::cxx::core::marker::Copy for #ident #generics {}\n    }\n}\n\nfn struct_clone(strct: &Struct, span: Span) -> TokenStream {\n    let ident = &strct.name.rust;\n    let generics = &strct.generics;\n    let cfg_and_lint_attrs = strct.attrs.cfg_and_lint();\n\n    let body = if derive::contains(&strct.derives, Trait::Copy) {\n        quote!(*self)\n    } else {\n        let fields = strct.fields.iter().map(|field| &field.name.rust);\n        let values = strct.fields.iter().map(|field| {\n            let ident = &field.name.rust;\n            let ty = field.ty.to_token_stream();\n            let span = ty.into_iter().last().unwrap().span();\n            quote_spanned!(span=> &self.#ident)\n        });\n        quote_spanned!(span=> #ident {\n            #(#fields: ::cxx::core::clone::Clone::clone(#values),)*\n        })\n    };\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        #[allow(clippy::expl_impl_clone_on_copy)]\n        impl #generics ::cxx::core::clone::Clone for #ident #generics {\n            fn clone(&self) -> Self {\n                #body\n            }\n        }\n    }\n}\n\nfn struct_debug(strct: &Struct, span: Span) -> TokenStream {\n    let ident = &strct.name.rust;\n    let generics = &strct.generics;\n    let cfg_and_lint_attrs = strct.attrs.cfg_and_lint();\n    let struct_name = ident.to_string();\n    let fields = strct.fields.iter().map(|field| &field.name.rust);\n    let field_names = fields.clone().map(Ident::to_string);\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        impl #generics ::cxx::core::fmt::Debug for #ident #generics {\n            fn fmt(&self, formatter: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {\n                formatter.debug_struct(#struct_name)\n                    #(.field(#field_names, &self.#fields))*\n                    .finish()\n            }\n        }\n    }\n}\n\nfn struct_default(strct: &Struct, span: Span) -> TokenStream {\n    let ident = &strct.name.rust;\n    let generics = &strct.generics;\n    let cfg_and_lint_attrs = strct.attrs.cfg_and_lint();\n    let fields = strct.fields.iter().map(|field| &field.name.rust);\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        #[allow(clippy::derivable_impls)] // different spans than the derived impl\n        impl #generics ::cxx::core::default::Default for #ident #generics {\n            fn default() -> Self {\n                #ident {\n                    #(\n                        #fields: ::cxx::core::default::Default::default(),\n                    )*\n                }\n            }\n        }\n    }\n}\n\nfn struct_ord(strct: &Struct, span: Span) -> TokenStream {\n    let ident = &strct.name.rust;\n    let generics = &strct.generics;\n    let cfg_and_lint_attrs = strct.attrs.cfg_and_lint();\n    let fields = strct.fields.iter().map(|field| &field.name.rust);\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        impl #generics ::cxx::core::cmp::Ord for #ident #generics {\n            fn cmp(&self, other: &Self) -> ::cxx::core::cmp::Ordering {\n                #(\n                    match ::cxx::core::cmp::Ord::cmp(&self.#fields, &other.#fields) {\n                        ::cxx::core::cmp::Ordering::Equal => {}\n                        ordering => return ordering,\n                    }\n                )*\n                ::cxx::core::cmp::Ordering::Equal\n            }\n        }\n    }\n}\n\nfn struct_partial_ord(strct: &Struct, span: Span) -> TokenStream {\n    let ident = &strct.name.rust;\n    let generics = &strct.generics;\n    let cfg_and_lint_attrs = strct.attrs.cfg_and_lint();\n\n    let body = if derive::contains(&strct.derives, Trait::Ord) {\n        quote! {\n            ::cxx::core::option::Option::Some(::cxx::core::cmp::Ord::cmp(self, other))\n        }\n    } else {\n        let fields = strct.fields.iter().map(|field| &field.name.rust);\n        quote! {\n            #(\n                match ::cxx::core::cmp::PartialOrd::partial_cmp(&self.#fields, &other.#fields) {\n                    ::cxx::core::option::Option::Some(::cxx::core::cmp::Ordering::Equal) => {}\n                    ordering => return ordering,\n                }\n            )*\n            ::cxx::core::option::Option::Some(::cxx::core::cmp::Ordering::Equal)\n        }\n    };\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        impl #generics ::cxx::core::cmp::PartialOrd for #ident #generics {\n            #[allow(clippy::non_canonical_partial_ord_impl)]\n            fn partial_cmp(&self, other: &Self) -> ::cxx::core::option::Option<::cxx::core::cmp::Ordering> {\n                #body\n            }\n        }\n    }\n}\n\nfn enum_bitand(enm: &Enum, span: Span) -> TokenStream {\n    let ident = &enm.name.rust;\n    let cfg_and_lint_attrs = enm.attrs.cfg_and_lint();\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        impl ::cxx::core::ops::BitAnd for #ident {\n            type Output = #ident;\n            fn bitand(self, rhs: Self) -> Self::Output {\n                #ident {\n                    repr: self.repr & rhs.repr,\n                }\n            }\n        }\n    }\n}\n\nfn enum_bitor(enm: &Enum, span: Span) -> TokenStream {\n    let ident = &enm.name.rust;\n    let cfg_and_lint_attrs = enm.attrs.cfg_and_lint();\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        impl ::cxx::core::ops::BitOr for #ident {\n            type Output = #ident;\n            fn bitor(self, rhs: Self) -> Self::Output {\n                #ident {\n                    repr: self.repr | rhs.repr,\n                }\n            }\n        }\n    }\n}\n\nfn enum_bitxor(enm: &Enum, span: Span) -> TokenStream {\n    let ident = &enm.name.rust;\n    let cfg_and_lint_attrs = enm.attrs.cfg_and_lint();\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        impl ::cxx::core::ops::BitXor for #ident {\n            type Output = #ident;\n            fn bitxor(self, rhs: Self) -> Self::Output {\n                #ident {\n                    repr: self.repr ^ rhs.repr,\n                }\n            }\n        }\n    }\n}\n\nfn enum_copy(enm: &Enum, span: Span) -> TokenStream {\n    let ident = &enm.name.rust;\n    let cfg_and_lint_attrs = enm.attrs.cfg_and_lint();\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        impl ::cxx::core::marker::Copy for #ident {}\n    }\n}\n\nfn enum_clone(enm: &Enum, span: Span) -> TokenStream {\n    let ident = &enm.name.rust;\n    let cfg_and_lint_attrs = enm.attrs.cfg_and_lint();\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        #[allow(clippy::expl_impl_clone_on_copy)]\n        impl ::cxx::core::clone::Clone for #ident {\n            fn clone(&self) -> Self {\n                *self\n            }\n        }\n    }\n}\n\nfn enum_debug(enm: &Enum, span: Span) -> TokenStream {\n    let ident = &enm.name.rust;\n    let cfg_and_lint_attrs = enm.attrs.cfg_and_lint();\n    let variants = enm.variants.iter().map(|variant| {\n        let variant = &variant.name.rust;\n        let name = variant.to_string();\n        quote_spanned! {span=>\n            #ident::#variant => formatter.write_str(#name),\n        }\n    });\n    let fallback = format!(\"{}({{}})\", ident);\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        impl ::cxx::core::fmt::Debug for #ident {\n            fn fmt(&self, formatter: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {\n                match *self {\n                    #(#variants)*\n                    _ => ::cxx::core::write!(formatter, #fallback, self.repr),\n                }\n            }\n        }\n    }\n}\n\nfn enum_default(enm: &Enum, span: Span) -> TokenStream {\n    let ident = &enm.name.rust;\n    let cfg_and_lint_attrs = enm.attrs.cfg_and_lint();\n\n    for variant in &enm.variants {\n        if variant.default {\n            let variant = &variant.name.rust;\n            return quote_spanned! {span=>\n                #cfg_and_lint_attrs\n                #[automatically_derived]\n                impl ::cxx::core::default::Default for #ident {\n                    fn default() -> Self {\n                        #ident::#variant\n                    }\n                }\n            };\n        }\n    }\n\n    unreachable!(\"no #[default] variant\");\n}\n\nfn enum_ord(enm: &Enum, span: Span) -> TokenStream {\n    let ident = &enm.name.rust;\n    let cfg_and_lint_attrs = enm.attrs.cfg_and_lint();\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        impl ::cxx::core::cmp::Ord for #ident {\n            fn cmp(&self, other: &Self) -> ::cxx::core::cmp::Ordering {\n                ::cxx::core::cmp::Ord::cmp(&self.repr, &other.repr)\n            }\n        }\n    }\n}\n\nfn enum_partial_ord(enm: &Enum, span: Span) -> TokenStream {\n    let ident = &enm.name.rust;\n    let cfg_and_lint_attrs = enm.attrs.cfg_and_lint();\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        impl ::cxx::core::cmp::PartialOrd for #ident {\n            #[allow(clippy::non_canonical_partial_ord_impl)]\n            fn partial_cmp(&self, other: &Self) -> ::cxx::core::option::Option<::cxx::core::cmp::Ordering> {\n                ::cxx::core::cmp::PartialOrd::partial_cmp(&self.repr, &other.repr)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "macro/src/expand.rs",
    "content": "use crate::syntax::atom::Atom::*;\nuse crate::syntax::attrs::{self, OtherAttrs};\nuse crate::syntax::cfg::{CfgExpr, ComputedCfg};\nuse crate::syntax::file::Module;\nuse crate::syntax::instantiate::{ImplKey, NamedImplKey};\nuse crate::syntax::map::OrderedMap;\nuse crate::syntax::message::Message;\nuse crate::syntax::namespace::Namespace;\nuse crate::syntax::qualified::QualifiedName;\nuse crate::syntax::report::Errors;\nuse crate::syntax::set::UnorderedSet;\nuse crate::syntax::symbol::Symbol;\nuse crate::syntax::trivial::TrivialReason;\nuse crate::syntax::types::ConditionalImpl;\nuse crate::syntax::unpin::UnpinReason;\nuse crate::syntax::{\n    self, check, mangle, Api, Doc, Enum, ExternFn, ExternType, FnKind, Lang, Pair, Signature,\n    Struct, Trait, Type, TypeAlias, Types,\n};\nuse crate::type_id::Crate;\nuse crate::{derive, generics};\nuse proc_macro2::{Ident, Span, TokenStream};\nuse quote::{format_ident, quote, quote_spanned, ToTokens};\nuse std::fmt::{self, Display};\nuse std::mem;\nuse syn::{parse_quote, GenericParam, Generics, Lifetime, Result, Token, Visibility};\n\npub(crate) fn bridge(mut ffi: Module) -> Result<TokenStream> {\n    let ref mut errors = Errors::new();\n\n    let mut cfg = CfgExpr::Unconditional;\n    let mut doc = Doc::new();\n    let attrs = attrs::parse(\n        errors,\n        mem::take(&mut ffi.attrs),\n        attrs::Parser {\n            cfg: Some(&mut cfg),\n            doc: Some(&mut doc),\n            ..Default::default()\n        },\n    );\n\n    let content = mem::take(&mut ffi.content);\n    let trusted = ffi.unsafety.is_some();\n    let namespace = &ffi.namespace;\n    let ref mut apis = syntax::parse_items(errors, content, trusted, namespace);\n    let ref types = Types::collect(errors, apis);\n    errors.propagate()?;\n\n    let generator = check::Generator::Macro;\n    check::typecheck(errors, apis, types, generator);\n    errors.propagate()?;\n\n    Ok(expand(ffi, doc, attrs, apis, types))\n}\n\nfn expand(ffi: Module, doc: Doc, attrs: OtherAttrs, apis: &[Api], types: &Types) -> TokenStream {\n    let mut expanded = TokenStream::new();\n    let mut hidden = TokenStream::new();\n    let mut forbid = TokenStream::new();\n\n    for api in apis {\n        if let Api::RustType(ety) = api {\n            expanded.extend(expand_rust_type_import(ety));\n            hidden.extend(expand_rust_type_assert_unpin(ety, types));\n        }\n    }\n\n    for api in apis {\n        match api {\n            Api::Include(_) | Api::Impl(_) => {}\n            Api::Struct(strct) => {\n                expanded.extend(expand_struct(strct));\n                expanded.extend(expand_associated_functions(&strct.name.rust, types));\n                hidden.extend(expand_struct_nonempty(strct));\n                hidden.extend(expand_struct_operators(strct));\n                forbid.extend(expand_struct_forbid_drop(strct));\n            }\n            Api::Enum(enm) => expanded.extend(expand_enum(enm)),\n            Api::CxxType(ety) => {\n                let ident = &ety.name.rust;\n                if types.structs.contains_key(ident) {\n                    hidden.extend(expand_extern_shared_struct(ety, &ffi));\n                } else if !types.enums.contains_key(ident) {\n                    expanded.extend(expand_cxx_type(ety));\n                    expanded.extend(expand_associated_functions(&ety.name.rust, types));\n                    hidden.extend(expand_cxx_type_assert_pinned(ety, types));\n                }\n            }\n            Api::CxxFunction(efn) => {\n                if efn.self_type().is_none() {\n                    expanded.extend(expand_cxx_function_shim(efn, types));\n                }\n            }\n            Api::RustType(ety) => {\n                expanded.extend(expand_rust_type_impl(ety));\n                expanded.extend(expand_associated_functions(&ety.name.rust, types));\n                hidden.extend(expand_rust_type_layout(ety, types));\n            }\n            Api::RustFunction(efn) => hidden.extend(expand_rust_function_shim(efn, types)),\n            Api::TypeAlias(alias) => {\n                expanded.extend(expand_type_alias(alias));\n                expanded.extend(expand_associated_functions(&alias.name.rust, types));\n                hidden.extend(expand_type_alias_verify(alias, types));\n            }\n        }\n    }\n\n    for (impl_key, conditional_impl) in &types.impls {\n        match impl_key {\n            ImplKey::RustBox(ident) => {\n                hidden.extend(expand_rust_box(ident, types, conditional_impl));\n            }\n            ImplKey::RustVec(ident) => {\n                hidden.extend(expand_rust_vec(ident, types, conditional_impl));\n            }\n            ImplKey::UniquePtr(ident) => {\n                expanded.extend(expand_unique_ptr(ident, types, conditional_impl));\n            }\n            ImplKey::SharedPtr(ident) => {\n                expanded.extend(expand_shared_ptr(ident, types, conditional_impl));\n            }\n            ImplKey::WeakPtr(ident) => {\n                expanded.extend(expand_weak_ptr(ident, types, conditional_impl));\n            }\n            ImplKey::CxxVector(ident) => {\n                expanded.extend(expand_cxx_vector(ident, conditional_impl, types));\n            }\n        }\n    }\n\n    if !forbid.is_empty() {\n        hidden.extend(expand_forbid(forbid));\n    }\n\n    // Work around https://github.com/rust-lang/rust/issues/67851.\n    if !hidden.is_empty() {\n        expanded.extend(quote! {\n            #[doc(hidden)]\n            const _: () = {\n                #hidden\n            };\n        });\n    }\n\n    let all_attrs = attrs.all();\n    let vis = &ffi.vis;\n    let mod_token = &ffi.mod_token;\n    let ident = &ffi.ident;\n    let span = ffi.brace_token.span;\n    let expanded = quote_spanned!(span=> {#expanded});\n\n    quote! {\n        #doc\n        #all_attrs\n        #[deny(improper_ctypes, improper_ctypes_definitions)]\n        #[allow(clippy::unknown_lints)]\n        #[allow(\n            non_camel_case_types,\n            non_snake_case,\n            clippy::extra_unused_type_parameters,\n            clippy::items_after_statements,\n            clippy::no_effect_underscore_binding,\n            clippy::unsafe_derive_deserialize,\n            clippy::upper_case_acronyms,\n            clippy::use_self,\n        )]\n        #vis #mod_token #ident #expanded\n    }\n}\n\nfn expand_struct(strct: &Struct) -> TokenStream {\n    let ident = &strct.name.rust;\n    let doc = &strct.doc;\n    let all_attrs = strct.attrs.all();\n    let cfg_and_lint_attrs = strct.attrs.cfg_and_lint();\n    let generics = &strct.generics;\n    let type_id = type_id(&strct.name);\n    let fields = strct.fields.iter().map(|field| {\n        let doc = &field.doc;\n        let all_attrs = field.attrs.all();\n        // This span on the pub makes \"private type in public interface\" errors\n        // appear in the right place.\n        let vis = field.visibility;\n        quote!(#doc #all_attrs #vis #field)\n    });\n    let mut derives = None;\n    let derived_traits = derive::expand_struct(strct, &mut derives);\n\n    let span = ident.span();\n    let visibility = strct.visibility;\n    let struct_token = strct.struct_token;\n    let struct_def = quote_spanned! {span=>\n        #visibility #struct_token #ident #generics {\n            #(#fields,)*\n        }\n    };\n\n    let align = strct.align.as_ref().map(|align| quote!(, align(#align)));\n\n    quote! {\n        #doc\n        #derives\n        #all_attrs\n        #[repr(C #align)]\n        #struct_def\n\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        unsafe impl #generics ::cxx::ExternType for #ident #generics {\n            #[allow(unused_attributes)] // incorrect lint\n            #[doc(hidden)]\n            type Id = #type_id;\n            type Kind = ::cxx::kind::Trivial;\n        }\n\n        #derived_traits\n    }\n}\n\nfn expand_struct_nonempty(strct: &Struct) -> TokenStream {\n    let has_unconditional_field = strct\n        .fields\n        .iter()\n        .any(|field| matches!(field.cfg, CfgExpr::Unconditional));\n    if has_unconditional_field {\n        return TokenStream::new();\n    }\n\n    let mut fields = strct.fields.iter();\n    let mut cfg = ComputedCfg::from(&fields.next().unwrap().cfg);\n    fields.for_each(|field| cfg.merge_or(&field.cfg));\n\n    if let ComputedCfg::Leaf(CfgExpr::Unconditional) = cfg {\n        // At least one field is unconditional, nothing to check.\n        TokenStream::new()\n    } else {\n        let meta = cfg.as_meta();\n        let msg = \"structs without any fields are not supported\";\n        let error = syn::Error::new_spanned(strct, msg).into_compile_error();\n        quote! {\n            #[cfg(not(#meta))]\n            #error\n        }\n    }\n}\n\nfn expand_struct_operators(strct: &Struct) -> TokenStream {\n    let ident = &strct.name.rust;\n    let generics = &strct.generics;\n    let cfg_and_lint_attrs = strct.attrs.cfg_and_lint();\n    let mut operators = TokenStream::new();\n\n    for derive in &strct.derives {\n        let span = derive.span;\n        match derive.what {\n            Trait::PartialEq => {\n                let link_name = mangle::operator(&strct.name, \"eq\");\n                let local_name = format_ident!(\"__operator_eq_{}\", strct.name.rust);\n                let prevent_unwind_label = format!(\"::{} as PartialEq>::eq\", strct.name.rust);\n                operators.extend(quote_spanned! {span=>\n                    #cfg_and_lint_attrs\n                    #[doc(hidden)]\n                    #[unsafe(export_name = #link_name)]\n                    extern \"C\" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> ::cxx::core::primitive::bool {\n                        let __fn = ::cxx::core::concat!(\"<\", ::cxx::core::module_path!(), #prevent_unwind_label);\n                        ::cxx::private::prevent_unwind(__fn, || *lhs == *rhs)\n                    }\n                });\n\n                if !derive::contains(&strct.derives, Trait::Eq) {\n                    let link_name = mangle::operator(&strct.name, \"ne\");\n                    let local_name = format_ident!(\"__operator_ne_{}\", strct.name.rust);\n                    let prevent_unwind_label = format!(\"::{} as PartialEq>::ne\", strct.name.rust);\n                    operators.extend(quote_spanned! {span=>\n                        #cfg_and_lint_attrs\n                        #[doc(hidden)]\n                        #[unsafe(export_name = #link_name)]\n                        extern \"C\" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> ::cxx::core::primitive::bool {\n                            let __fn = ::cxx::core::concat!(\"<\", ::cxx::core::module_path!(), #prevent_unwind_label);\n                            ::cxx::private::prevent_unwind(__fn, || *lhs != *rhs)\n                        }\n                    });\n                }\n            }\n            Trait::PartialOrd => {\n                let link_name = mangle::operator(&strct.name, \"lt\");\n                let local_name = format_ident!(\"__operator_lt_{}\", strct.name.rust);\n                let prevent_unwind_label = format!(\"::{} as PartialOrd>::lt\", strct.name.rust);\n                operators.extend(quote_spanned! {span=>\n                    #cfg_and_lint_attrs\n                    #[doc(hidden)]\n                    #[unsafe(export_name = #link_name)]\n                    extern \"C\" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> ::cxx::core::primitive::bool {\n                        let __fn = ::cxx::core::concat!(\"<\", ::cxx::core::module_path!(), #prevent_unwind_label);\n                        ::cxx::private::prevent_unwind(__fn, || *lhs < *rhs)\n                    }\n                });\n\n                let link_name = mangle::operator(&strct.name, \"le\");\n                let local_name = format_ident!(\"__operator_le_{}\", strct.name.rust);\n                let prevent_unwind_label = format!(\"::{} as PartialOrd>::le\", strct.name.rust);\n                operators.extend(quote_spanned! {span=>\n                    #cfg_and_lint_attrs\n                    #[doc(hidden)]\n                    #[unsafe(export_name = #link_name)]\n                    extern \"C\" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> ::cxx::core::primitive::bool {\n                        let __fn = ::cxx::core::concat!(\"<\", ::cxx::core::module_path!(), #prevent_unwind_label);\n                        ::cxx::private::prevent_unwind(__fn, || *lhs <= *rhs)\n                    }\n                });\n\n                if !derive::contains(&strct.derives, Trait::Ord) {\n                    let link_name = mangle::operator(&strct.name, \"gt\");\n                    let local_name = format_ident!(\"__operator_gt_{}\", strct.name.rust);\n                    let prevent_unwind_label = format!(\"::{} as PartialOrd>::gt\", strct.name.rust);\n                    operators.extend(quote_spanned! {span=>\n                        #cfg_and_lint_attrs\n                        #[doc(hidden)]\n                        #[unsafe(export_name = #link_name)]\n                        extern \"C\" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> ::cxx::core::primitive::bool {\n                            let __fn = ::cxx::core::concat!(\"<\", ::cxx::core::module_path!(), #prevent_unwind_label);\n                            ::cxx::private::prevent_unwind(__fn, || *lhs > *rhs)\n                        }\n                    });\n\n                    let link_name = mangle::operator(&strct.name, \"ge\");\n                    let local_name = format_ident!(\"__operator_ge_{}\", strct.name.rust);\n                    let prevent_unwind_label = format!(\"::{} as PartialOrd>::ge\", strct.name.rust);\n                    operators.extend(quote_spanned! {span=>\n                        #cfg_and_lint_attrs\n                        #[doc(hidden)]\n                        #[unsafe(export_name = #link_name)]\n                        extern \"C\" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> ::cxx::core::primitive::bool {\n                            let __fn = ::cxx::core::concat!(\"<\", ::cxx::core::module_path!(), #prevent_unwind_label);\n                            ::cxx::private::prevent_unwind(__fn, || *lhs >= *rhs)\n                        }\n                    });\n                }\n            }\n            Trait::Hash => {\n                let link_name = mangle::operator(&strct.name, \"hash\");\n                let local_name = format_ident!(\"__operator_hash_{}\", strct.name.rust);\n                let prevent_unwind_label = format!(\"::{} as Hash>::hash\", strct.name.rust);\n                operators.extend(quote_spanned! {span=>\n                    #cfg_and_lint_attrs\n                    #[doc(hidden)]\n                    #[unsafe(export_name = #link_name)]\n                    #[allow(clippy::cast_possible_truncation)]\n                    extern \"C\" fn #local_name #generics(this: &#ident #generics) -> ::cxx::core::primitive::usize {\n                        let __fn = ::cxx::core::concat!(\"<\", ::cxx::core::module_path!(), #prevent_unwind_label);\n                        ::cxx::private::prevent_unwind(__fn, || ::cxx::private::hash(this))\n                    }\n                });\n            }\n            _ => {}\n        }\n    }\n\n    operators\n}\n\nfn expand_struct_forbid_drop(strct: &Struct) -> TokenStream {\n    let ident = &strct.name.rust;\n    let generics = &strct.generics;\n    let cfg_and_lint_attrs = strct.attrs.cfg_and_lint();\n    let span = ident.span();\n    let impl_token = Token![impl](strct.visibility.span);\n\n    quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        #impl_token #generics self::Drop for super::#ident #generics {}\n    }\n}\n\nfn expand_enum(enm: &Enum) -> TokenStream {\n    let ident = &enm.name.rust;\n    let doc = &enm.doc;\n    let all_attrs = enm.attrs.all();\n    let cfg_and_lint_attrs = enm.attrs.cfg_and_lint();\n    let repr = &enm.repr;\n    let type_id = type_id(&enm.name);\n    let variants = enm.variants.iter().map(|variant| {\n        let doc = &variant.doc;\n        let all_attrs = variant.attrs.all();\n        let variant_ident = &variant.name.rust;\n        let discriminant = &variant.discriminant;\n        let span = variant_ident.span();\n        Some(quote_spanned! {span=>\n            #doc\n            #all_attrs\n            #[allow(dead_code)]\n            pub const #variant_ident: Self = #ident { repr: #discriminant };\n        })\n    });\n    let mut derives = None;\n    let derived_traits = derive::expand_enum(enm, &mut derives);\n\n    let span = ident.span();\n    let visibility = enm.visibility;\n    let struct_token = Token![struct](enm.enum_token.span);\n    let enum_repr = quote! {\n        #[allow(missing_docs)]\n        pub repr: #repr,\n    };\n    let enum_def = quote_spanned! {span=>\n        #visibility #struct_token #ident {\n            #enum_repr\n        }\n    };\n\n    quote! {\n        #doc\n        #derives\n        #all_attrs\n        #[repr(transparent)]\n        #enum_def\n\n        #cfg_and_lint_attrs\n        #[allow(non_upper_case_globals)]\n        impl #ident {\n            #(#variants)*\n        }\n\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        unsafe impl ::cxx::ExternType for #ident {\n            #[allow(unused_attributes)] // incorrect lint\n            #[doc(hidden)]\n            type Id = #type_id;\n            type Kind = ::cxx::kind::Trivial;\n        }\n\n        #derived_traits\n    }\n}\n\nfn expand_cxx_type(ety: &ExternType) -> TokenStream {\n    let ident = &ety.name.rust;\n    let doc = &ety.doc;\n    let all_attrs = ety.attrs.all();\n    let cfg_and_lint_attrs = ety.attrs.cfg_and_lint();\n    let generics = &ety.generics;\n    let type_id = type_id(&ety.name);\n\n    let lifetime_fields = ety.generics.lifetimes.iter().map(|lifetime| {\n        let field = format_ident!(\"_lifetime_{}\", lifetime.ident);\n        quote!(#field: ::cxx::core::marker::PhantomData<&#lifetime ()>)\n    });\n    let repr_fields = quote! {\n        _private: ::cxx::private::Opaque,\n        #(#lifetime_fields,)*\n    };\n\n    let span = ident.span();\n    let visibility = &ety.visibility;\n    let struct_token = Token![struct](ety.type_token.span);\n    let extern_type_def = quote_spanned! {span=>\n        #visibility #struct_token #ident #generics {\n            #repr_fields\n        }\n    };\n\n    quote! {\n        #doc\n        #all_attrs\n        #[repr(C)]\n        #extern_type_def\n\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        unsafe impl #generics ::cxx::ExternType for #ident #generics {\n            #[allow(unused_attributes)] // incorrect lint\n            #[doc(hidden)]\n            type Id = #type_id;\n            type Kind = ::cxx::kind::Opaque;\n        }\n    }\n}\n\nfn expand_cxx_type_assert_pinned(ety: &ExternType, types: &Types) -> TokenStream {\n    let ident = &ety.name.rust;\n    let cfg_and_lint_attrs = ety.attrs.cfg_and_lint();\n    let infer = Token![_](ident.span());\n\n    let resolve = types.resolve(ident);\n    let lifetimes = resolve.generics.to_underscore_lifetimes();\n\n    quote! {\n        #cfg_and_lint_attrs\n        let _: fn() = {\n            // Derived from https://github.com/nvzqz/static-assertions-rs.\n            trait __AmbiguousIfImpl<A> {\n                fn infer() {}\n            }\n\n            #[automatically_derived]\n            impl<T> __AmbiguousIfImpl<()> for T\n            where\n                T: ?::cxx::core::marker::Sized\n            {}\n\n            #[allow(dead_code)]\n            struct __Invalid;\n\n            #[automatically_derived]\n            impl<T> __AmbiguousIfImpl<__Invalid> for T\n            where\n                T: ?::cxx::core::marker::Sized + ::cxx::core::marker::Unpin,\n            {}\n\n            // If there is only one specialized trait impl, type inference with\n            // `_` can be resolved and this can compile. Fails to compile if\n            // user has added a manual Unpin impl for their opaque C++ type as\n            // then `__AmbiguousIfImpl<__Invalid>` also exists.\n            <#ident #lifetimes as __AmbiguousIfImpl<#infer>>::infer\n        };\n    }\n}\n\nfn expand_extern_shared_struct(ety: &ExternType, ffi: &Module) -> TokenStream {\n    let module = &ffi.ident;\n    let name = &ety.name.rust;\n    let namespaced_name = display_namespaced(&ety.name);\n    let cfg_and_lint_attrs = ety.attrs.cfg_and_lint();\n\n    let visibility = match &ffi.vis {\n        Visibility::Public(_) => \"pub \".to_owned(),\n        Visibility::Restricted(vis) => {\n            format!(\n                \"pub(in {}) \",\n                vis.path\n                    .segments\n                    .iter()\n                    .map(|segment| segment.ident.to_string())\n                    .collect::<Vec<_>>()\n                    .join(\"::\"),\n            )\n        }\n        Visibility::Inherited => String::new(),\n    };\n\n    let namespace_attr = if ety.name.namespace == Namespace::ROOT {\n        String::new()\n    } else {\n        format!(\n            \"#[namespace = \\\"{}\\\"]\\n        \",\n            ety.name\n                .namespace\n                .iter()\n                .map(Ident::to_string)\n                .collect::<Vec<_>>()\n                .join(\"::\"),\n        )\n    };\n\n    let message = format!(\n        \"\\\n        \\nShared struct redeclared as an unsafe extern C++ type is deprecated.\\\n        \\nIf this is intended to be a shared struct, remove this `type {name}`.\\\n        \\nIf this is intended to be an extern type, change it to:\\\n        \\n\\\n        \\n    use cxx::ExternType;\\\n        \\n    \\\n        \\n    #[repr(C)]\\\n        \\n    {visibility}struct {name} {{\\\n        \\n        ...\\\n        \\n    }}\\\n        \\n    \\\n        \\n    unsafe impl ExternType for {name} {{\\\n        \\n        type Id = cxx::type_id!(\\\"{namespaced_name}\\\");\\\n        \\n        type Kind = cxx::kind::Trivial;\\\n        \\n    }}\\\n        \\n    \\\n        \\n    {visibility}mod {module} {{\\\n        \\n        {namespace_attr}extern \\\"C++\\\" {{\\\n        \\n            type {name} = crate::{name};\\\n        \\n        }}\\\n        \\n        ...\\\n        \\n    }}\",\n    );\n\n    quote! {\n        #cfg_and_lint_attrs\n        #[deprecated = #message]\n        struct #name {}\n\n        #cfg_and_lint_attrs\n        let _ = #name {};\n    }\n}\n\nfn expand_associated_functions(self_type: &Ident, types: &Types) -> TokenStream {\n    let Some(functions) = types.associated_fn.get(self_type) else {\n        return TokenStream::new();\n    };\n\n    let resolve = types.resolve(self_type);\n    let self_type_cfg_attrs = resolve.attrs.cfg();\n    let elided_lifetime = Lifetime::new(\"'_\", Span::call_site());\n    let mut group_by_lifetimes = OrderedMap::new();\n    let mut tokens = TokenStream::new();\n\n    for efn in functions {\n        match efn.lang {\n            Lang::Cxx | Lang::CxxUnwind => {}\n            Lang::Rust => continue,\n        }\n        let mut impl_lifetimes = Vec::new();\n        let mut self_type_lifetimes = Vec::new();\n        let self_lt_token;\n        let self_gt_token;\n        match &efn.kind {\n            FnKind::Method(receiver) if receiver.ty.generics.lt_token.is_some() => {\n                for lifetime in &receiver.ty.generics.lifetimes {\n                    if lifetime.ident != \"_\"\n                        && efn\n                            .generics\n                            .lifetimes()\n                            .any(|param| param.lifetime == *lifetime)\n                    {\n                        impl_lifetimes.push(lifetime);\n                    }\n                    self_type_lifetimes.push(lifetime);\n                }\n                self_lt_token = receiver.ty.generics.lt_token;\n                self_gt_token = receiver.ty.generics.gt_token;\n            }\n            _ => {\n                self_type_lifetimes.resize(resolve.generics.lifetimes.len(), &elided_lifetime);\n                self_lt_token = resolve.generics.lt_token;\n                self_gt_token = resolve.generics.gt_token;\n            }\n        }\n        if efn.undeclared_lifetimes().is_empty()\n            && self_type_lifetimes.len() == resolve.generics.lifetimes.len()\n        {\n            group_by_lifetimes\n                .entry((impl_lifetimes, self_type_lifetimes))\n                .or_insert_with(Vec::new)\n                .push(efn);\n        } else {\n            let impl_token = Token![impl](efn.name.rust.span());\n            let impl_lt_token = efn.generics.lt_token;\n            let impl_gt_token = efn.generics.gt_token;\n            let self_type = efn.self_type().unwrap();\n            let function = expand_cxx_function_shim(efn, types);\n            tokens.extend(quote! {\n                #self_type_cfg_attrs\n                #impl_token #impl_lt_token #(#impl_lifetimes),* #impl_gt_token #self_type #self_lt_token #(#self_type_lifetimes),* #self_gt_token {\n                    #function\n                }\n            });\n        }\n    }\n\n    for ((impl_lifetimes, self_type_lifetimes), functions) in &group_by_lifetimes {\n        let functions = functions\n            .iter()\n            .map(|efn| expand_cxx_function_shim(efn, types));\n        tokens.extend(quote! {\n            #self_type_cfg_attrs\n            impl <#(#impl_lifetimes),*> #self_type <#(#self_type_lifetimes),*> {\n                #(#functions)*\n            }\n        });\n    }\n\n    tokens\n}\n\nfn expand_cxx_function_decl(efn: &ExternFn, types: &Types) -> TokenStream {\n    let receiver = efn.receiver().into_iter().map(|receiver| {\n        if types.is_considered_improper_ctype(&receiver.ty) {\n            if receiver.mutable {\n                quote!(_: *mut ::cxx::core::ffi::c_void)\n            } else {\n                quote!(_: *const ::cxx::core::ffi::c_void)\n            }\n        } else {\n            let receiver_type = receiver.ty();\n            quote!(_: #receiver_type)\n        }\n    });\n    let args = efn.args.iter().map(|arg| {\n        let var = &arg.name.rust;\n        let colon = arg.colon_token;\n        let ty = expand_extern_type(&arg.ty, types, true);\n        if arg.ty == RustString {\n            quote!(#var #colon *const #ty)\n        } else if let Type::RustVec(_) = arg.ty {\n            quote!(#var #colon *const #ty)\n        } else if let Type::Fn(_) = arg.ty {\n            quote!(#var #colon ::cxx::private::FatFunction)\n        } else if types.needs_indirect_abi(&arg.ty) {\n            quote!(#var #colon *mut #ty)\n        } else {\n            quote!(#var #colon #ty)\n        }\n    });\n    let all_args = receiver.chain(args);\n    let ret = if efn.throws {\n        quote!(-> ::cxx::private::Result)\n    } else {\n        expand_extern_return_type(efn, types, true, efn.lang)\n    };\n    let mut outparam = None;\n    if indirect_return(efn, types, efn.lang) {\n        let ret = expand_extern_type(efn.ret.as_ref().unwrap(), types, true);\n        outparam = Some(quote!(__return: *mut #ret));\n    }\n    let link_name = mangle::extern_fn(efn, types);\n    let local_name = format_ident!(\"__{}\", efn.name.rust);\n    let lt_token = efn.generics.lt_token.unwrap_or_default();\n    let undeclared_lifetimes = efn.undeclared_lifetimes().into_iter();\n    let declared_lifetimes = &efn.generics.params;\n    let gt_token = efn.generics.gt_token.unwrap_or_default();\n    quote! {\n        #[link_name = #link_name]\n        fn #local_name #lt_token #(#undeclared_lifetimes,)* #declared_lifetimes #gt_token(#(#all_args,)* #outparam) #ret;\n    }\n}\n\nfn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {\n    let doc = &efn.doc;\n    let all_attrs = efn.attrs.all();\n    let decl = expand_cxx_function_decl(efn, types);\n    let receiver = efn.receiver().into_iter().map(|receiver| {\n        let var = receiver.var;\n        if receiver.pinned {\n            let colon = receiver.colon_token;\n            let ty = receiver.ty_self();\n            quote!(#var #colon #ty)\n        } else {\n            let ampersand = receiver.ampersand;\n            let lifetime = &receiver.lifetime;\n            let mutability = receiver.mutability;\n            quote!(#ampersand #lifetime #mutability #var)\n        }\n    });\n    let args = efn.args.iter().map(|arg| quote!(#arg));\n    let all_args = receiver.chain(args);\n    let ret = if efn.throws {\n        let ok = match &efn.ret {\n            Some(ret) => quote!(#ret),\n            None => quote!(()),\n        };\n        quote!(-> ::cxx::core::result::Result<#ok, ::cxx::Exception>)\n    } else {\n        expand_return_type(&efn.ret)\n    };\n    let indirect_return = indirect_return(efn, types, efn.lang);\n    let receiver_var = efn.receiver().into_iter().map(|receiver| {\n        if types.is_considered_improper_ctype(&receiver.ty) {\n            let var = receiver.var;\n            let ty = &receiver.ty.rust;\n            let resolve = types.resolve(ty);\n            let lifetimes = resolve.generics.to_underscore_lifetimes();\n            if receiver.pinned {\n                quote!(::cxx::core::ptr::from_mut::<#ty #lifetimes>(::cxx::core::pin::Pin::into_inner_unchecked(#var)).cast::<::cxx::core::ffi::c_void>())\n            } else if receiver.mutable {\n                quote!(::cxx::core::ptr::from_mut::<#ty #lifetimes>(#var).cast::<::cxx::core::ffi::c_void>())\n            } else {\n                quote!(::cxx::core::ptr::from_ref::<#ty #lifetimes>(#var).cast::<::cxx::core::ffi::c_void>())\n            }\n        } else {\n            receiver.var.to_token_stream()\n        }\n    });\n    let arg_vars = efn.args.iter().map(|arg| {\n        let var = &arg.name.rust;\n        let span = var.span();\n        match &arg.ty {\n            Type::Ident(ident) if ident.rust == RustString => {\n                quote_spanned!(span=> #var.as_mut_ptr().cast::<::cxx::private::RustString>().cast_const())\n            }\n            Type::RustBox(ty) => {\n                if types.is_considered_improper_ctype(&ty.inner) {\n                    quote_spanned!(span=> ::cxx::alloc::boxed::Box::into_raw(#var).cast())\n                } else {\n                    quote_spanned!(span=> ::cxx::alloc::boxed::Box::into_raw(#var))\n                }\n            }\n            Type::UniquePtr(ty) => {\n                if types.is_considered_improper_ctype(&ty.inner) {\n                    quote_spanned!(span=> ::cxx::UniquePtr::into_raw(#var).cast())\n                } else {\n                    quote_spanned!(span=> ::cxx::UniquePtr::into_raw(#var))\n                }\n            }\n            Type::RustVec(_) => quote_spanned!(span=> #var.as_mut_ptr().cast::<::cxx::private::RustVec<_>>().cast_const()),\n            Type::Ref(ty) => match &ty.inner {\n                Type::Ident(ident) if ident.rust == RustString => match ty.mutable {\n                    false => quote_spanned!(span=> ::cxx::private::RustString::from_ref(#var)),\n                    true => quote_spanned!(span=> ::cxx::private::RustString::from_mut(#var)),\n                },\n                Type::RustVec(_) => match ty.mutable {\n                    false => quote_spanned!(span=> ::cxx::private::RustVec::from_ref(#var)),\n                    true => quote_spanned!(span=> ::cxx::private::RustVec::from_mut(#var)),\n                },\n                inner if types.is_considered_improper_ctype(inner) => {\n                    let var = match ty.pinned {\n                        false => quote!(#var),\n                        true => quote_spanned!(span=> ::cxx::core::pin::Pin::into_inner_unchecked(#var)),\n                    };\n                    match ty.mutable {\n                        false => {\n                            quote_spanned!(span=> ::cxx::core::ptr::from_ref::<#inner>(#var).cast::<::cxx::core::ffi::c_void>())\n                        }\n                        true => quote_spanned!(span=> ::cxx::core::ptr::from_mut::<#inner>(#var).cast::<::cxx::core::ffi::c_void>()),\n                    }\n                }\n                _ => quote!(#var),\n            },\n            Type::Ptr(ty) => {\n                if types.is_considered_improper_ctype(&ty.inner) {\n                    quote_spanned!(span=> #var.cast())\n                } else {\n                    quote!(#var)\n                }\n            }\n            Type::Str(_) => quote_spanned!(span=> ::cxx::private::RustStr::from(#var)),\n            Type::SliceRef(ty) => match ty.mutable {\n                false => quote_spanned!(span=> ::cxx::private::RustSlice::from_ref(#var)),\n                true => quote_spanned!(span=> ::cxx::private::RustSlice::from_mut(#var)),\n            },\n            ty if types.needs_indirect_abi(ty) => quote_spanned!(span=> #var.as_mut_ptr()),\n            _ => quote!(#var),\n        }\n    });\n    let vars = receiver_var.chain(arg_vars);\n    let trampolines = efn\n        .args\n        .iter()\n        .filter_map(|arg| {\n            if let Type::Fn(f) = &arg.ty {\n                let var = &arg.name;\n                Some(expand_function_pointer_trampoline(efn, var, f, types))\n            } else {\n                None\n            }\n        })\n        .collect::<TokenStream>();\n    let mut setup = efn\n        .args\n        .iter()\n        .filter(|arg| types.needs_indirect_abi(&arg.ty))\n        .map(|arg| {\n            let var = &arg.name.rust;\n            let span = var.span();\n            // These are arguments for which C++ has taken ownership of the data\n            // behind the mut reference it received.\n            quote_spanned! {span=>\n                let mut #var = ::cxx::core::mem::MaybeUninit::new(#var);\n            }\n        })\n        .collect::<TokenStream>();\n    let local_name = format_ident!(\"__{}\", efn.name.rust);\n    let span = efn.semi_token.span;\n    let call = if indirect_return {\n        let ret = expand_extern_type(efn.ret.as_ref().unwrap(), types, true);\n        setup.extend(quote_spanned! {span=>\n            let mut __return = ::cxx::core::mem::MaybeUninit::<#ret>::uninit();\n        });\n        setup.extend(if efn.throws {\n            quote_spanned! {span=>\n                #local_name(#(#vars,)* __return.as_mut_ptr()).exception()?;\n            }\n        } else {\n            quote_spanned! {span=>\n                #local_name(#(#vars,)* __return.as_mut_ptr());\n            }\n        });\n        quote_spanned!(span=> __return.assume_init())\n    } else if efn.throws {\n        quote_spanned! {span=>\n            #local_name(#(#vars),*).exception()\n        }\n    } else {\n        quote_spanned! {span=>\n            #local_name(#(#vars),*)\n        }\n    };\n    let mut expr;\n    if let Some(ret) = &efn.ret {\n        expr = match ret {\n            Type::Ident(ident) if ident.rust == RustString => {\n                quote_spanned!(span=> #call.into_string())\n            }\n            Type::RustBox(ty) => {\n                if types.is_considered_improper_ctype(&ty.inner) {\n                    quote_spanned!(span=> ::cxx::alloc::boxed::Box::from_raw(#call.cast()))\n                } else {\n                    quote_spanned!(span=> ::cxx::alloc::boxed::Box::from_raw(#call))\n                }\n            }\n            Type::RustVec(_) => {\n                quote_spanned!(span=> #call.into_vec())\n            }\n            Type::UniquePtr(ty) => {\n                if types.is_considered_improper_ctype(&ty.inner) {\n                    quote_spanned!(span=> ::cxx::UniquePtr::from_raw(#call.cast()))\n                } else {\n                    quote_spanned!(span=> ::cxx::UniquePtr::from_raw(#call))\n                }\n            }\n            Type::Ref(ty) => match &ty.inner {\n                Type::Ident(ident) if ident.rust == RustString => match ty.mutable {\n                    false => quote_spanned!(span=> #call.as_string()),\n                    true => quote_spanned!(span=> #call.as_mut_string()),\n                },\n                Type::RustVec(_) => match ty.mutable {\n                    false => quote_spanned!(span=> #call.as_vec()),\n                    true => quote_spanned!(span=> #call.as_mut_vec()),\n                },\n                inner if types.is_considered_improper_ctype(inner) => {\n                    let mutability = ty.mutability;\n                    let deref_mut = quote_spanned!(span=> &#mutability *#call.cast());\n                    match ty.pinned {\n                        false => deref_mut,\n                        true => {\n                            quote_spanned!(span=> ::cxx::core::pin::Pin::new_unchecked(#deref_mut))\n                        }\n                    }\n                }\n                _ => call,\n            },\n            Type::Ptr(ty) => {\n                if types.is_considered_improper_ctype(&ty.inner) {\n                    quote_spanned!(span=> #call.cast())\n                } else {\n                    call\n                }\n            }\n            Type::Str(_) => quote_spanned!(span=> #call.as_str()),\n            Type::SliceRef(slice) => {\n                let inner = &slice.inner;\n                match slice.mutable {\n                    false => quote_spanned!(span=> #call.as_slice::<#inner>()),\n                    true => quote_spanned!(span=> #call.as_mut_slice::<#inner>()),\n                }\n            }\n            _ => call,\n        };\n        if efn.throws {\n            expr = quote_spanned!(span=> ::cxx::core::result::Result::Ok(#expr));\n        }\n    } else if efn.throws {\n        expr = call;\n    } else {\n        expr = quote! { #call; };\n    }\n    let dispatch = quote_spanned!(span=> unsafe { #setup #expr });\n    let visibility = efn.visibility;\n    let unsafety = &efn.unsafety;\n    let fn_token = efn.fn_token;\n    let ident = &efn.name.rust;\n    let lt_token = efn.generics.lt_token;\n    let lifetimes = {\n        let mut self_type_lifetimes = UnorderedSet::new();\n        if let FnKind::Method(receiver) = &efn.kind {\n            self_type_lifetimes.extend(&receiver.ty.generics.lifetimes);\n        }\n        efn.generics\n            .params\n            .pairs()\n            .filter(move |param| match param.value() {\n                GenericParam::Lifetime(param) => !self_type_lifetimes.contains(&param.lifetime),\n                GenericParam::Type(_) | GenericParam::Const(_) => unreachable!(),\n            })\n    };\n    let gt_token = efn.generics.gt_token;\n    let arg_list = quote_spanned!(efn.paren_token.span=> (#(#all_args,)*));\n    let calling_conv = match efn.lang {\n        Lang::Cxx => quote_spanned!(span=> \"C\"),\n        Lang::CxxUnwind => quote_spanned!(span=> \"C-unwind\"),\n        Lang::Rust => unreachable!(),\n    };\n    quote_spanned! {span=>\n        #doc\n        #all_attrs\n        #visibility #unsafety #fn_token #ident #lt_token #(#lifetimes)* #gt_token #arg_list #ret {\n            unsafe extern #calling_conv {\n                #decl\n            }\n            #trampolines\n            #dispatch\n        }\n    }\n}\n\nfn expand_function_pointer_trampoline(\n    efn: &ExternFn,\n    var: &Pair,\n    sig: &Signature,\n    types: &Types,\n) -> TokenStream {\n    let c_trampoline = mangle::c_trampoline(efn, var, types);\n    let r_trampoline = mangle::r_trampoline(efn, var, types);\n    let local_name = parse_quote!(__);\n    let prevent_unwind_label = format!(\"::{}::{}\", efn.name.rust, var.rust);\n    let body_span = efn.semi_token.span;\n    let shim = expand_rust_function_shim_impl(\n        sig,\n        types,\n        &r_trampoline,\n        local_name,\n        prevent_unwind_label,\n        None,\n        Some(&efn.generics),\n        &efn.attrs,\n        body_span,\n    );\n    let calling_conv = match efn.lang {\n        Lang::Cxx => \"C\",\n        Lang::CxxUnwind => \"C-unwind\",\n        Lang::Rust => unreachable!(),\n    };\n    let var = &var.rust;\n\n    quote! {\n        let #var = ::cxx::private::FatFunction {\n            trampoline: {\n                unsafe extern #calling_conv {\n                    #[link_name = #c_trampoline]\n                    fn trampoline();\n                }\n                #shim\n                trampoline as ::cxx::core::primitive::usize as *const ::cxx::core::ffi::c_void\n            },\n            ptr: #var as ::cxx::core::primitive::usize as *const ::cxx::core::ffi::c_void,\n        };\n    }\n}\n\nfn expand_rust_type_import(ety: &ExternType) -> TokenStream {\n    let ident = &ety.name.rust;\n    let all_attrs = ety.attrs.all();\n    let span = ident.span();\n\n    quote_spanned! {span=>\n        #all_attrs\n        use super::#ident;\n    }\n}\n\nfn expand_rust_type_impl(ety: &ExternType) -> TokenStream {\n    let ident = &ety.name.rust;\n    let generics = &ety.generics;\n    let cfg_and_lint_attrs = ety.attrs.cfg_and_lint();\n    let span = ident.span();\n    let unsafe_impl = quote_spanned!(ety.type_token.span=> unsafe impl);\n\n    let mut impls = quote_spanned! {span=>\n        #cfg_and_lint_attrs\n        #[automatically_derived]\n        #[doc(hidden)]\n        #unsafe_impl #generics ::cxx::private::RustType for #ident #generics {}\n    };\n\n    for derive in &ety.derives {\n        if derive.what == Trait::ExternType {\n            let type_id = type_id(&ety.name);\n            let span = derive.span;\n            impls.extend(quote_spanned! {span=>\n                #cfg_and_lint_attrs\n                #[automatically_derived]\n                unsafe impl #generics ::cxx::ExternType for #ident #generics {\n                    #[allow(unused_attributes)] // incorrect lint\n                    #[doc(hidden)]\n                    type Id = #type_id;\n                    type Kind = ::cxx::kind::Opaque;\n                }\n            });\n        }\n    }\n\n    impls\n}\n\nfn expand_rust_type_assert_unpin(ety: &ExternType, types: &Types) -> TokenStream {\n    let ident = &ety.name.rust;\n    let cfg_and_lint_attrs = ety.attrs.cfg_and_lint();\n\n    let resolve = types.resolve(ident);\n    let lifetimes = resolve.generics.to_underscore_lifetimes();\n\n    quote_spanned! {ident.span()=>\n        #cfg_and_lint_attrs\n        const _: fn() = ::cxx::private::require_unpin::<#ident #lifetimes>;\n    }\n}\n\nfn expand_rust_type_layout(ety: &ExternType, types: &Types) -> TokenStream {\n    // Rustc will render as follows if not sized:\n    //\n    //     type TheirType;\n    //     -----^^^^^^^^^-\n    //     |    |\n    //     |    doesn't have a size known at compile-time\n    //     required by this bound in `__AssertSized`\n\n    let ident = &ety.name.rust;\n    let cfg_and_lint_attrs = ety.attrs.cfg_and_lint();\n    let begin_span = Token![::](ety.type_token.span);\n    let sized = quote_spanned! {ety.semi_token.span=>\n        #begin_span cxx::core::marker::Sized\n    };\n\n    let link_sizeof = mangle::operator(&ety.name, \"sizeof\");\n    let link_alignof = mangle::operator(&ety.name, \"alignof\");\n\n    let local_sizeof = format_ident!(\"__sizeof_{}\", ety.name.rust);\n    let local_alignof = format_ident!(\"__alignof_{}\", ety.name.rust);\n\n    let resolve = types.resolve(ident);\n    let lifetimes = resolve.generics.to_underscore_lifetimes();\n\n    quote_spanned! {ident.span()=>\n        #cfg_and_lint_attrs\n        {\n            #[doc(hidden)]\n            #[allow(clippy::needless_maybe_sized)]\n            fn __AssertSized<T: ?#sized + #sized>() -> ::cxx::core::alloc::Layout {\n                ::cxx::core::alloc::Layout::new::<T>()\n            }\n            #[doc(hidden)]\n            #[unsafe(export_name = #link_sizeof)]\n            extern \"C\" fn #local_sizeof() -> ::cxx::core::primitive::usize {\n                __AssertSized::<#ident #lifetimes>().size()\n            }\n            #[doc(hidden)]\n            #[unsafe(export_name = #link_alignof)]\n            extern \"C\" fn #local_alignof() -> ::cxx::core::primitive::usize {\n                __AssertSized::<#ident #lifetimes>().align()\n            }\n        }\n    }\n}\n\nfn expand_forbid(impls: TokenStream) -> TokenStream {\n    quote! {\n        mod forbid {\n            pub trait Drop {}\n            #[automatically_derived]\n            #[allow(drop_bounds)]\n            impl<T: ?::cxx::core::marker::Sized + ::cxx::core::ops::Drop> self::Drop for T {}\n            #impls\n        }\n    }\n}\n\nfn expand_rust_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {\n    let link_name = mangle::extern_fn(efn, types);\n    let local_name = match efn.self_type() {\n        None => format_ident!(\"__{}\", efn.name.rust),\n        Some(self_type) => format_ident!(\"__{}__{}\", self_type, efn.name.rust),\n    };\n    let prevent_unwind_label = match efn.self_type() {\n        None => format!(\"::{}\", efn.name.rust),\n        Some(self_type) => format!(\"::{}::{}\", self_type, efn.name.rust),\n    };\n    let invoke = Some(&efn.name.rust);\n    let body_span = efn.semi_token.span;\n    expand_rust_function_shim_impl(\n        efn,\n        types,\n        &link_name,\n        local_name,\n        prevent_unwind_label,\n        invoke,\n        None,\n        &efn.attrs,\n        body_span,\n    )\n}\n\nfn expand_rust_function_shim_impl(\n    sig: &Signature,\n    types: &Types,\n    link_name: &Symbol,\n    local_name: Ident,\n    prevent_unwind_label: String,\n    invoke: Option<&Ident>,\n    outer_generics: Option<&Generics>,\n    attrs: &OtherAttrs,\n    body_span: Span,\n) -> TokenStream {\n    let all_attrs = attrs.all();\n    let generics = outer_generics.unwrap_or(&sig.generics);\n    let receiver_var = sig\n        .receiver()\n        .map(|receiver| quote_spanned!(receiver.var.span=> __self));\n    let receiver = sig.receiver().map(|receiver| {\n        let colon = receiver.colon_token;\n        let receiver_type = receiver.ty();\n        quote!(#receiver_var #colon #receiver_type)\n    });\n    let args = sig.args.iter().map(|arg| {\n        let var = &arg.name.rust;\n        let colon = arg.colon_token;\n        let ty = expand_extern_type(&arg.ty, types, false);\n        if types.needs_indirect_abi(&arg.ty) {\n            quote!(#var #colon *mut #ty)\n        } else {\n            quote!(#var #colon #ty)\n        }\n    });\n    let all_args = receiver.into_iter().chain(args);\n\n    let mut requires_unsafe = false;\n    let arg_vars = sig.args.iter().map(|arg| {\n        let var = &arg.name.rust;\n        let span = var.span();\n        match &arg.ty {\n            Type::Ident(i) if i.rust == RustString => {\n                requires_unsafe = true;\n                quote_spanned!(span=> ::cxx::core::mem::take((*#var).as_mut_string()))\n            }\n            Type::RustBox(_) => {\n                requires_unsafe = true;\n                quote_spanned!(span=> ::cxx::alloc::boxed::Box::from_raw(#var))\n            }\n            Type::RustVec(_) => {\n                requires_unsafe = true;\n                quote_spanned!(span=> ::cxx::core::mem::take((*#var).as_mut_vec()))\n            }\n            Type::UniquePtr(_) => {\n                requires_unsafe = true;\n                quote_spanned!(span=> ::cxx::UniquePtr::from_raw(#var))\n            }\n            Type::Ref(ty) => match &ty.inner {\n                Type::Ident(i) if i.rust == RustString => match ty.mutable {\n                    false => quote_spanned!(span=> #var.as_string()),\n                    true => quote_spanned!(span=> #var.as_mut_string()),\n                },\n                Type::RustVec(_) => match ty.mutable {\n                    false => quote_spanned!(span=> #var.as_vec()),\n                    true => quote_spanned!(span=> #var.as_mut_vec()),\n                },\n                _ => quote!(#var),\n            },\n            Type::Str(_) => {\n                requires_unsafe = true;\n                quote_spanned!(span=> #var.as_str())\n            }\n            Type::SliceRef(slice) => {\n                requires_unsafe = true;\n                let inner = &slice.inner;\n                match slice.mutable {\n                    false => quote_spanned!(span=> #var.as_slice::<#inner>()),\n                    true => quote_spanned!(span=> #var.as_mut_slice::<#inner>()),\n                }\n            }\n            ty if types.needs_indirect_abi(ty) => {\n                requires_unsafe = true;\n                quote_spanned!(span=> ::cxx::core::ptr::read(#var))\n            }\n            _ => quote!(#var),\n        }\n    });\n    let vars: Vec<_> = receiver_var.into_iter().chain(arg_vars).collect();\n\n    let mut requires_closure;\n    let mut call = match invoke {\n        Some(_) => {\n            requires_closure = false;\n            quote!(#local_name)\n        }\n        None => {\n            requires_closure = true;\n            requires_unsafe = true;\n            quote!(::cxx::core::mem::transmute::<*const (), #sig>(__extern))\n        }\n    };\n    requires_closure |= !vars.is_empty();\n    call.extend(quote! { (#(#vars),*) });\n\n    let wrap_super = invoke.map(|invoke| {\n        // If the wrapper function is being passed directly to prevent_unwind,\n        // it must implement `FnOnce() -> R` and cannot be an unsafe fn.\n        let unsafety = sig.unsafety.filter(|_| requires_closure);\n        expand_rust_function_shim_super(sig, &local_name, invoke, unsafety)\n    });\n\n    let span = body_span;\n    let conversion = sig.ret.as_ref().and_then(|ret| match ret {\n        Type::Ident(ident) if ident.rust == RustString => {\n            Some(quote_spanned!(span=> ::cxx::private::RustString::from))\n        }\n        Type::RustBox(_) => Some(quote_spanned!(span=> ::cxx::alloc::boxed::Box::into_raw)),\n        Type::RustVec(_) => Some(quote_spanned!(span=> ::cxx::private::RustVec::from)),\n        Type::UniquePtr(_) => Some(quote_spanned!(span=> ::cxx::UniquePtr::into_raw)),\n        Type::Ref(ty) => match &ty.inner {\n            Type::Ident(ident) if ident.rust == RustString => match ty.mutable {\n                false => Some(quote_spanned!(span=> ::cxx::private::RustString::from_ref)),\n                true => Some(quote_spanned!(span=> ::cxx::private::RustString::from_mut)),\n            },\n            Type::RustVec(_) => match ty.mutable {\n                false => Some(quote_spanned!(span=> ::cxx::private::RustVec::from_ref)),\n                true => Some(quote_spanned!(span=> ::cxx::private::RustVec::from_mut)),\n            },\n            _ => None,\n        },\n        Type::Str(_) => Some(quote_spanned!(span=> ::cxx::private::RustStr::from)),\n        Type::SliceRef(ty) => match ty.mutable {\n            false => Some(quote_spanned!(span=> ::cxx::private::RustSlice::from_ref)),\n            true => Some(quote_spanned!(span=> ::cxx::private::RustSlice::from_mut)),\n        },\n        _ => None,\n    });\n\n    let mut expr = match conversion {\n        None => call,\n        Some(conversion) if !sig.throws => {\n            requires_closure = true;\n            quote_spanned!(span=> #conversion(#call))\n        }\n        Some(conversion) => {\n            requires_closure = true;\n            quote_spanned!(span=> ::cxx::core::result::Result::map(#call, #conversion))\n        }\n    };\n\n    let mut outparam = None;\n    let indirect_return = indirect_return(sig, types, Lang::Rust);\n    if indirect_return {\n        let ret = expand_extern_type(sig.ret.as_ref().unwrap(), types, false);\n        outparam = Some(quote_spanned!(span=> __return: *mut #ret,));\n    }\n    if sig.throws {\n        let out = match sig.ret {\n            Some(_) => quote_spanned!(span=> __return),\n            None => quote_spanned!(span=> &mut ()),\n        };\n        requires_closure = true;\n        requires_unsafe = true;\n        expr = quote_spanned!(span=> ::cxx::private::r#try(#out, #expr));\n    } else if indirect_return {\n        requires_closure = true;\n        requires_unsafe = true;\n        expr = quote_spanned!(span=> ::cxx::core::ptr::write(__return, #expr));\n    }\n\n    if requires_unsafe {\n        expr = quote_spanned!(span=> unsafe { #expr });\n    }\n\n    let closure = if requires_closure {\n        quote_spanned!(span=> move || #expr)\n    } else {\n        quote!(#local_name)\n    };\n\n    expr = quote_spanned!(span=> ::cxx::private::prevent_unwind(__fn, #closure));\n\n    let ret = if sig.throws {\n        quote!(-> ::cxx::private::Result)\n    } else {\n        expand_extern_return_type(sig, types, false, Lang::Rust)\n    };\n\n    let pointer = match invoke {\n        None => Some(quote_spanned!(span=> __extern: *const ())),\n        Some(_) => None,\n    };\n\n    quote_spanned! {span=>\n        #all_attrs\n        #[doc(hidden)]\n        #[unsafe(export_name = #link_name)]\n        unsafe extern \"C\" fn #local_name #generics(#(#all_args,)* #outparam #pointer) #ret {\n            let __fn = ::cxx::core::concat!(::cxx::core::module_path!(), #prevent_unwind_label);\n            #wrap_super\n            #expr\n        }\n    }\n}\n\n// A wrapper like `fn f(x: Arg) { super::f(x) }` just to ensure we have the\n// accurate unsafety declaration and no problematic elided lifetimes.\nfn expand_rust_function_shim_super(\n    sig: &Signature,\n    local_name: &Ident,\n    invoke: &Ident,\n    unsafety: Option<Token![unsafe]>,\n) -> TokenStream {\n    let generics = &sig.generics;\n\n    let receiver_var = sig\n        .receiver()\n        .map(|receiver| Ident::new(\"__self\", receiver.var.span));\n    let receiver = sig.receiver().into_iter().map(|receiver| {\n        let receiver_type = receiver.ty();\n        quote!(#receiver_var: #receiver_type)\n    });\n    let args = sig.args.iter().map(|arg| quote!(#arg));\n    let all_args = receiver.chain(args);\n\n    let ret = if let Some((result, _langle, rangle)) = sig.throws_tokens {\n        let ok = match &sig.ret {\n            Some(ret) => quote!(#ret),\n            None => quote!(()),\n        };\n        // Set spans that result in the `Result<...>` written by the user being\n        // highlighted as the cause if their error type has no Display impl.\n        let result_begin = quote_spanned!(result.span=> ::cxx::core::result::Result<#ok, impl);\n        let result_end = quote_spanned!(rangle.span=> ::cxx::core::fmt::Display + use<>>);\n        quote!(-> #result_begin #result_end)\n    } else {\n        expand_return_type(&sig.ret)\n    };\n\n    let arg_vars = sig.args.iter().map(|arg| &arg.name.rust);\n    let vars = receiver_var.iter().chain(arg_vars);\n\n    let span = invoke.span();\n    let call = match sig.self_type() {\n        None => quote_spanned!(span=> super::#invoke),\n        Some(self_type) => quote_spanned!(span=> #self_type::#invoke),\n    };\n\n    let mut body = quote_spanned!(span=> #call(#(#vars,)*));\n    let mut allow_unused_unsafe = None;\n    if sig.unsafety.is_some() {\n        body = quote_spanned!(span=> unsafe { #body });\n        allow_unused_unsafe = Some(quote_spanned!(span=> #[allow(unused_unsafe)]));\n    }\n\n    quote_spanned! {span=>\n        #allow_unused_unsafe\n        #unsafety fn #local_name #generics(#(#all_args,)*) #ret {\n            #body\n        }\n    }\n}\n\nfn expand_type_alias(alias: &TypeAlias) -> TokenStream {\n    let doc = &alias.doc;\n    let all_attrs = alias.attrs.all();\n    let visibility = alias.visibility;\n    let type_token = alias.type_token;\n    let ident = &alias.name.rust;\n    let generics = &alias.generics;\n    let eq_token = alias.eq_token;\n    let ty = &alias.ty;\n    let semi_token = alias.semi_token;\n\n    quote! {\n        #doc\n        #all_attrs\n        #visibility #type_token #ident #generics #eq_token #ty #semi_token\n    }\n}\n\nfn expand_type_alias_verify(alias: &TypeAlias, types: &Types) -> TokenStream {\n    let cfg_and_lint_attrs = alias.attrs.cfg_and_lint();\n    let ident = &alias.name.rust;\n    let type_id = type_id(&alias.name);\n    let begin_span = alias.type_token.span;\n    let end_span = alias.semi_token.span;\n    let begin = quote_spanned!(begin_span=> ::cxx::private::verify_extern_type::<);\n    let end = quote_spanned!(end_span=> >);\n\n    let resolve = types.resolve(ident);\n    let lifetimes = resolve.generics.to_underscore_lifetimes();\n\n    let mut verify = quote! {\n        #cfg_and_lint_attrs\n        const _: fn() = #begin #ident #lifetimes, #type_id #end;\n    };\n\n    let mut require_unpin = false;\n    let mut require_box = false;\n    let mut require_vec = false;\n    let mut require_extern_type_trivial = false;\n    let mut require_rust_type_or_trivial = None;\n    if let Some(reasons) = types.required_trivial.get(&alias.name.rust) {\n        for reason in reasons {\n            match reason {\n                TrivialReason::BoxTarget { local: true }\n                | TrivialReason::VecElement { local: true } => require_unpin = true,\n                TrivialReason::BoxTarget { local: false } => require_box = true,\n                TrivialReason::VecElement { local: false } => require_vec = true,\n                TrivialReason::StructField(_)\n                | TrivialReason::FunctionArgument(_)\n                | TrivialReason::FunctionReturn(_) => require_extern_type_trivial = true,\n                TrivialReason::SliceElement(slice) => require_rust_type_or_trivial = Some(slice),\n            }\n        }\n    }\n\n    'unpin: {\n        if let Some(reason) = types.required_unpin.get(ident) {\n            let ampersand;\n            let reference_lifetime;\n            let mutability;\n            let mut inner;\n            let generics;\n            let shorthand;\n            match reason {\n                UnpinReason::Receiver(receiver) => {\n                    ampersand = &receiver.ampersand;\n                    reference_lifetime = &receiver.lifetime;\n                    mutability = &receiver.mutability;\n                    inner = receiver.ty.rust.clone();\n                    generics = &receiver.ty.generics;\n                    shorthand = receiver.shorthand;\n                    if receiver.shorthand {\n                        inner.set_span(receiver.var.span);\n                    }\n                }\n                UnpinReason::Ref(mutable_reference) => {\n                    ampersand = &mutable_reference.ampersand;\n                    reference_lifetime = &mutable_reference.lifetime;\n                    mutability = &mutable_reference.mutability;\n                    let Type::Ident(inner_type) = &mutable_reference.inner else {\n                        unreachable!();\n                    };\n                    inner = inner_type.rust.clone();\n                    generics = &inner_type.generics;\n                    shorthand = false;\n                }\n                UnpinReason::Slice(mutable_slice) => {\n                    ampersand = &mutable_slice.ampersand;\n                    mutability = &mutable_slice.mutability;\n                    let inner = quote_spanned!(mutable_slice.bracket.span=> [#ident #lifetimes]);\n                    let trait_name = format_ident!(\"SliceOfUnpin_{ident}\");\n                    let label = format!(\"requires `{ident}: Unpin`\");\n                    verify.extend(quote! {\n                        #cfg_and_lint_attrs\n                        let _ = {\n                            #[diagnostic::on_unimplemented(\n                                message = \"mutable slice of pinned type is not supported\",\n                                label = #label,\n                            )]\n                            trait #trait_name {\n                                fn check_unpin() {}\n                            }\n                            #[diagnostic::do_not_recommend]\n                            impl<'a, T: ?::cxx::core::marker::Sized + ::cxx::core::marker::Unpin> #trait_name for &'a #mutability T {}\n                            <#ampersand #mutability #inner as #trait_name>::check_unpin\n                        };\n                    });\n                    require_unpin = false;\n                    break 'unpin;\n                }\n            }\n            let trait_name = format_ident!(\"ReferenceToUnpin_{ident}\");\n            let message =\n                format!(\"mutable reference to C++ type requires a pin -- use Pin<&mut {ident}>\");\n            let label = {\n                let mut label = Message::new();\n                write!(label, \"use `\");\n                if shorthand {\n                    write!(label, \"self: \");\n                }\n                write!(label, \"Pin<&\");\n                if let Some(reference_lifetime) = reference_lifetime {\n                    write!(label, \"{reference_lifetime} \");\n                }\n                write!(label, \"mut {ident}\");\n                if !generics.lifetimes.is_empty() {\n                    write!(label, \"<\");\n                    for (i, lifetime) in generics.lifetimes.iter().enumerate() {\n                        if i > 0 {\n                            write!(label, \", \");\n                        }\n                        write!(label, \"{lifetime}\");\n                    }\n                    write!(label, \">\");\n                } else if shorthand && !alias.generics.lifetimes.is_empty() {\n                    write!(label, \"<\");\n                    for i in 0..alias.generics.lifetimes.len() {\n                        if i > 0 {\n                            write!(label, \", \");\n                        }\n                        write!(label, \"'_\");\n                    }\n                    write!(label, \">\");\n                }\n                write!(label, \">`\");\n                label\n            };\n            let lifetimes = generics.to_underscore_lifetimes();\n            verify.extend(quote! {\n                #cfg_and_lint_attrs\n                let _ = {\n                    #[diagnostic::on_unimplemented(message = #message, label = #label)]\n                    trait #trait_name {\n                        fn check_unpin() {}\n                    }\n                    #[diagnostic::do_not_recommend]\n                    impl<'a, T: ?::cxx::core::marker::Sized + ::cxx::core::marker::Unpin> #trait_name for &'a mut T {}\n                    <#ampersand #mutability #inner #lifetimes as #trait_name>::check_unpin\n                };\n            });\n            require_unpin = false;\n        }\n    }\n\n    if require_unpin {\n        verify.extend(quote! {\n            #cfg_and_lint_attrs\n            const _: fn() = ::cxx::private::require_unpin::<#ident #lifetimes>;\n        });\n    }\n\n    if require_box {\n        verify.extend(quote! {\n            #cfg_and_lint_attrs\n            const _: fn() = ::cxx::private::require_box::<#ident #lifetimes>;\n        });\n    }\n\n    if require_vec {\n        verify.extend(quote! {\n            #cfg_and_lint_attrs\n            const _: fn() = ::cxx::private::require_vec::<#ident #lifetimes>;\n        });\n    }\n\n    if require_extern_type_trivial {\n        let begin = quote_spanned!(begin_span=> ::cxx::private::verify_extern_kind::<);\n        verify.extend(quote! {\n            #cfg_and_lint_attrs\n            const _: fn() = #begin #ident #lifetimes, ::cxx::kind::Trivial #end;\n        });\n    } else if let Some(slice_type) = require_rust_type_or_trivial {\n        let ampersand = &slice_type.ampersand;\n        let mutability = &slice_type.mutability;\n        let inner = quote_spanned!(slice_type.bracket.span.join()=> [#ident #lifetimes]);\n        verify.extend(quote! {\n            #cfg_and_lint_attrs\n            let _ = || ::cxx::private::with::<#ident #lifetimes>().check_slice::<#ampersand #mutability #inner>();\n        });\n    }\n\n    verify\n}\n\nfn type_id(name: &Pair) -> TokenStream {\n    let namespace_segments = name.namespace.iter();\n    let mut segments = Vec::with_capacity(namespace_segments.len() + 1);\n    segments.extend(namespace_segments.cloned());\n    segments.push(Ident::new(&name.cxx.to_string(), Span::call_site()));\n    let qualified = QualifiedName { segments };\n    crate::type_id::expand(Crate::Cxx, qualified)\n}\n\nfn expand_rust_box(\n    key: &NamedImplKey,\n    types: &Types,\n    conditional_impl: &ConditionalImpl,\n) -> TokenStream {\n    let link_prefix = format!(\"cxxbridge1$box${}$\", key.symbol);\n    let link_alloc = format!(\"{}alloc\", link_prefix);\n    let link_dealloc = format!(\"{}dealloc\", link_prefix);\n    let link_drop = format!(\"{}drop\", link_prefix);\n\n    let (impl_generics, inner_with_generics) =\n        generics::split_for_impl(key, conditional_impl, types);\n\n    let cfg = conditional_impl.cfg.into_attr();\n    let begin_span = conditional_impl\n        .explicit_impl\n        .map_or(key.begin_span, |explicit| explicit.impl_token.span);\n    let end_span = conditional_impl\n        .explicit_impl\n        .map_or(key.end_span, |explicit| explicit.brace_token.span.join());\n    let unsafe_token = format_ident!(\"unsafe\", span = begin_span);\n    let prevent_unwind_type_label = generics::format_for_prevent_unwind_label(key.inner);\n\n    quote_spanned!(end_span=> {\n        #cfg\n        #[automatically_derived]\n        #[doc(hidden)]\n        #unsafe_token impl #impl_generics ::cxx::private::ImplBox for #inner_with_generics {}\n\n        #cfg\n        #[doc(hidden)]\n        #[unsafe(export_name = #link_alloc)]\n        unsafe extern \"C\" fn __alloc #impl_generics() -> *mut ::cxx::core::mem::MaybeUninit<#inner_with_generics> {\n            // No prevent_unwind: the global allocator is not allowed to panic.\n            ::cxx::alloc::boxed::Box::into_raw(::cxx::alloc::boxed::Box::new_uninit())\n        }\n\n        #cfg\n        #[doc(hidden)]\n        #[unsafe(export_name = #link_dealloc)]\n        unsafe extern \"C\" fn __dealloc #impl_generics(ptr: *mut ::cxx::core::mem::MaybeUninit<#inner_with_generics>) {\n            // No prevent_unwind: the global allocator is not allowed to panic.\n            let _ = unsafe { ::cxx::alloc::boxed::Box::from_raw(ptr) };\n        }\n\n        #cfg\n        #[doc(hidden)]\n        #[unsafe(export_name = #link_drop)]\n        unsafe extern \"C\" fn __drop #impl_generics(this: *mut ::cxx::alloc::boxed::Box<#inner_with_generics>) {\n            let __fn = ::cxx::core::concat!(\"<\", #prevent_unwind_type_label, \" as Drop>::drop\");\n            ::cxx::private::prevent_unwind(__fn, || unsafe { ::cxx::core::ptr::drop_in_place(this) });\n        }\n    })\n}\n\nfn expand_rust_vec(\n    key: &NamedImplKey,\n    types: &Types,\n    conditional_impl: &ConditionalImpl,\n) -> TokenStream {\n    let link_prefix = format!(\"cxxbridge1$rust_vec${}$\", key.symbol);\n    let link_new = format!(\"{}new\", link_prefix);\n    let link_drop = format!(\"{}drop\", link_prefix);\n    let link_len = format!(\"{}len\", link_prefix);\n    let link_capacity = format!(\"{}capacity\", link_prefix);\n    let link_data = format!(\"{}data\", link_prefix);\n    let link_reserve_total = format!(\"{}reserve_total\", link_prefix);\n    let link_set_len = format!(\"{}set_len\", link_prefix);\n    let link_truncate = format!(\"{}truncate\", link_prefix);\n\n    let (impl_generics, inner_with_generics) =\n        generics::split_for_impl(key, conditional_impl, types);\n\n    let cfg = conditional_impl.cfg.into_attr();\n    let begin_span = conditional_impl\n        .explicit_impl\n        .map_or(key.begin_span, |explicit| explicit.impl_token.span);\n    let end_span = conditional_impl\n        .explicit_impl\n        .map_or(key.end_span, |explicit| explicit.brace_token.span.join());\n    let unsafe_token = format_ident!(\"unsafe\", span = begin_span);\n    let prevent_unwind_type_label = generics::format_for_prevent_unwind_label(key.inner);\n\n    quote_spanned!(end_span=> {\n        #cfg\n        #[automatically_derived]\n        #[doc(hidden)]\n        #unsafe_token impl #impl_generics ::cxx::private::ImplVec for #inner_with_generics {}\n\n        #cfg\n        #[doc(hidden)]\n        #[unsafe(export_name = #link_new)]\n        unsafe extern \"C\" fn __new #impl_generics(this: *mut ::cxx::private::RustVec<#inner_with_generics>) {\n            // No prevent_unwind: cannot panic.\n            unsafe {\n                ::cxx::core::ptr::write(this, ::cxx::private::RustVec::new());\n            }\n        }\n\n        #cfg\n        #[doc(hidden)]\n        #[unsafe(export_name = #link_drop)]\n        unsafe extern \"C\" fn __drop #impl_generics(this: *mut ::cxx::private::RustVec<#inner_with_generics>) {\n            let __fn = ::cxx::core::concat!(\"<\", #prevent_unwind_type_label, \" as Drop>::drop\");\n            ::cxx::private::prevent_unwind(\n                __fn,\n                || unsafe { ::cxx::core::ptr::drop_in_place(this) },\n            );\n        }\n\n        #cfg\n        #[doc(hidden)]\n        #[unsafe(export_name = #link_len)]\n        unsafe extern \"C\" fn __len #impl_generics(this: *const ::cxx::private::RustVec<#inner_with_generics>) -> ::cxx::core::primitive::usize {\n            // No prevent_unwind: cannot panic.\n            unsafe { (*this).len() }\n        }\n\n        #cfg\n        #[doc(hidden)]\n        #[unsafe(export_name = #link_capacity)]\n        unsafe extern \"C\" fn __capacity #impl_generics(this: *const ::cxx::private::RustVec<#inner_with_generics>) -> ::cxx::core::primitive::usize {\n            // No prevent_unwind: cannot panic.\n            unsafe { (*this).capacity() }\n        }\n\n        #cfg\n        #[doc(hidden)]\n        #[unsafe(export_name = #link_data)]\n        unsafe extern \"C\" fn __data #impl_generics(this: *const ::cxx::private::RustVec<#inner_with_generics>) -> *const #inner_with_generics {\n            // No prevent_unwind: cannot panic.\n            unsafe { (*this).as_ptr() }\n        }\n\n        #cfg\n        #[doc(hidden)]\n        #[unsafe(export_name = #link_reserve_total)]\n        unsafe extern \"C\" fn __reserve_total #impl_generics(this: *mut ::cxx::private::RustVec<#inner_with_generics>, new_cap: ::cxx::core::primitive::usize) {\n            // No prevent_unwind: the global allocator is not allowed to panic.\n            unsafe {\n                (*this).reserve_total(new_cap);\n            }\n        }\n\n        #cfg\n        #[doc(hidden)]\n        #[unsafe(export_name = #link_set_len)]\n        unsafe extern \"C\" fn __set_len #impl_generics(this: *mut ::cxx::private::RustVec<#inner_with_generics>, len: ::cxx::core::primitive::usize) {\n            // No prevent_unwind: cannot panic.\n            unsafe {\n                (*this).set_len(len);\n            }\n        }\n\n        #cfg\n        #[doc(hidden)]\n        #[unsafe(export_name = #link_truncate)]\n        unsafe extern \"C\" fn __truncate #impl_generics(this: *mut ::cxx::private::RustVec<#inner_with_generics>, len: ::cxx::core::primitive::usize) {\n            let __fn = ::cxx::core::concat!(\"<\", #prevent_unwind_type_label, \" as Drop>::drop\");\n            ::cxx::private::prevent_unwind(\n                __fn,\n                || unsafe { (*this).truncate(len) },\n            );\n        }\n    })\n}\n\nfn expand_unique_ptr(\n    key: &NamedImplKey,\n    types: &Types,\n    conditional_impl: &ConditionalImpl,\n) -> TokenStream {\n    let prefix = format!(\"cxxbridge1$unique_ptr${}$\", key.symbol);\n    let link_null = format!(\"{}null\", prefix);\n    let link_uninit = format!(\"{}uninit\", prefix);\n    let link_raw = format!(\"{}raw\", prefix);\n    let link_get = format!(\"{}get\", prefix);\n    let link_release = format!(\"{}release\", prefix);\n    let link_drop = format!(\"{}drop\", prefix);\n\n    let name = generics::concise_rust_name(key.inner);\n    let (impl_generics, inner_with_generics) =\n        generics::split_for_impl(key, conditional_impl, types);\n\n    let can_construct_from_value = types.is_maybe_trivial(key.inner);\n    let new_method = if can_construct_from_value {\n        Some(quote! {\n            fn __new(value: Self) -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {\n                unsafe extern \"C\" {\n                    #[link_name = #link_uninit]\n                    fn __uninit(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::core::ffi::c_void;\n                }\n                let mut repr = ::cxx::core::mem::MaybeUninit::uninit();\n                unsafe {\n                    __uninit(&raw mut repr).cast::<#inner_with_generics>().write(value);\n                }\n                repr\n            }\n        })\n    } else {\n        None\n    };\n\n    let cfg = conditional_impl.cfg.into_attr();\n    let begin_span = conditional_impl\n        .explicit_impl\n        .map_or(key.begin_span, |explicit| explicit.impl_token.span);\n    let end_span = conditional_impl\n        .explicit_impl\n        .map_or(key.end_span, |explicit| explicit.brace_token.span.join());\n    let unsafe_token = format_ident!(\"unsafe\", span = begin_span);\n\n    quote_spanned! {end_span=>\n        #cfg\n        #[automatically_derived]\n        #unsafe_token impl #impl_generics ::cxx::memory::UniquePtrTarget for #inner_with_generics {\n            fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {\n                f.write_str(#name)\n            }\n            fn __null() -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {\n                unsafe extern \"C\" {\n                    #[link_name = #link_null]\n                    fn __null(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>);\n                }\n                let mut repr = ::cxx::core::mem::MaybeUninit::uninit();\n                unsafe {\n                    __null(&raw mut repr);\n                }\n                repr\n            }\n            #new_method\n            unsafe fn __raw(raw: *mut Self) -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {\n                unsafe extern \"C\" {\n                    #[link_name = #link_raw]\n                    fn __raw(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>, raw: *mut ::cxx::core::ffi::c_void);\n                }\n                let mut repr = ::cxx::core::mem::MaybeUninit::uninit();\n                unsafe {\n                    __raw(&raw mut repr, raw.cast());\n                }\n                repr\n            }\n            unsafe fn __get(repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const Self {\n                unsafe extern \"C\" {\n                    #[link_name = #link_get]\n                    fn __get(this: *const ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::core::ffi::c_void;\n                }\n                unsafe { __get(&raw const repr).cast() }\n            }\n            unsafe fn __release(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut Self {\n                unsafe extern \"C\" {\n                    #[link_name = #link_release]\n                    fn __release(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::core::ffi::c_void;\n                }\n                unsafe { __release(&raw mut repr).cast() }\n            }\n            unsafe fn __drop(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_drop]\n                    fn __drop(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>);\n                }\n                unsafe {\n                    __drop(&raw mut repr);\n                }\n            }\n        }\n    }\n}\n\nfn expand_shared_ptr(\n    key: &NamedImplKey,\n    types: &Types,\n    conditional_impl: &ConditionalImpl,\n) -> TokenStream {\n    let prefix = format!(\"cxxbridge1$shared_ptr${}$\", key.symbol);\n    let link_null = format!(\"{}null\", prefix);\n    let link_uninit = format!(\"{}uninit\", prefix);\n    let link_raw = format!(\"{}raw\", prefix);\n    let link_clone = format!(\"{}clone\", prefix);\n    let link_get = format!(\"{}get\", prefix);\n    let link_drop = format!(\"{}drop\", prefix);\n\n    let name = generics::concise_rust_name(key.inner);\n    let (impl_generics, inner_with_generics) =\n        generics::split_for_impl(key, conditional_impl, types);\n\n    let can_construct_from_value = types.is_maybe_trivial(key.inner);\n    let new_method = if can_construct_from_value {\n        Some(quote! {\n            unsafe fn __new(value: Self, new: *mut ::cxx::core::ffi::c_void) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_uninit]\n                    fn __uninit(new: *mut ::cxx::core::ffi::c_void) -> *mut ::cxx::core::ffi::c_void;\n                }\n                unsafe {\n                    __uninit(new).cast::<#inner_with_generics>().write(value);\n                }\n            }\n        })\n    } else {\n        None\n    };\n\n    let cfg = conditional_impl.cfg.into_attr();\n    let begin_span = conditional_impl\n        .explicit_impl\n        .map_or(key.begin_span, |explicit| explicit.impl_token.span);\n    let end_span = conditional_impl\n        .explicit_impl\n        .map_or(key.end_span, |explicit| explicit.brace_token.span.join());\n    let unsafe_token = format_ident!(\"unsafe\", span = begin_span);\n\n    let not_destructible_err = format!(\n        \"{} is not destructible\",\n        generics::concise_cxx_name(key.inner, types),\n    );\n\n    quote_spanned! {end_span=>\n        #cfg\n        #[automatically_derived]\n        #unsafe_token impl #impl_generics ::cxx::memory::SharedPtrTarget for #inner_with_generics {\n            fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {\n                f.write_str(#name)\n            }\n            unsafe fn __null(new: *mut ::cxx::core::ffi::c_void) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_null]\n                    fn __null(new: *mut ::cxx::core::ffi::c_void);\n                }\n                unsafe {\n                    __null(new);\n                }\n            }\n            #new_method\n            #[track_caller]\n            unsafe fn __raw(new: *mut ::cxx::core::ffi::c_void, raw: *mut Self) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_raw]\n                    fn __raw(new: *const ::cxx::core::ffi::c_void, raw: *mut ::cxx::core::ffi::c_void) -> ::cxx::core::primitive::bool;\n                }\n                if !unsafe { __raw(new, raw.cast::<::cxx::core::ffi::c_void>()) } {\n                    ::cxx::core::panic!(#not_destructible_err);\n                }\n            }\n            unsafe fn __clone(this: *const ::cxx::core::ffi::c_void, new: *mut ::cxx::core::ffi::c_void) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_clone]\n                    fn __clone(this: *const ::cxx::core::ffi::c_void, new: *mut ::cxx::core::ffi::c_void);\n                }\n                unsafe {\n                    __clone(this, new);\n                }\n            }\n            unsafe fn __get(this: *const ::cxx::core::ffi::c_void) -> *const Self {\n                unsafe extern \"C\" {\n                    #[link_name = #link_get]\n                    fn __get(this: *const ::cxx::core::ffi::c_void) -> *const ::cxx::core::ffi::c_void;\n                }\n                unsafe { __get(this).cast() }\n            }\n            unsafe fn __drop(this: *mut ::cxx::core::ffi::c_void) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_drop]\n                    fn __drop(this: *mut ::cxx::core::ffi::c_void);\n                }\n                unsafe {\n                    __drop(this);\n                }\n            }\n        }\n    }\n}\n\nfn expand_weak_ptr(\n    key: &NamedImplKey,\n    types: &Types,\n    conditional_impl: &ConditionalImpl,\n) -> TokenStream {\n    let prefix = format!(\"cxxbridge1$weak_ptr${}$\", key.symbol);\n    let link_null = format!(\"{}null\", prefix);\n    let link_clone = format!(\"{}clone\", prefix);\n    let link_downgrade = format!(\"{}downgrade\", prefix);\n    let link_upgrade = format!(\"{}upgrade\", prefix);\n    let link_drop = format!(\"{}drop\", prefix);\n\n    let name = generics::concise_rust_name(key.inner);\n    let (impl_generics, inner_with_generics) =\n        generics::split_for_impl(key, conditional_impl, types);\n\n    let cfg = conditional_impl.cfg.into_attr();\n    let begin_span = conditional_impl\n        .explicit_impl\n        .map_or(key.begin_span, |explicit| explicit.impl_token.span);\n    let end_span = conditional_impl\n        .explicit_impl\n        .map_or(key.end_span, |explicit| explicit.brace_token.span.join());\n    let unsafe_token = format_ident!(\"unsafe\", span = begin_span);\n\n    quote_spanned! {end_span=>\n        #cfg\n        #[automatically_derived]\n        #unsafe_token impl #impl_generics ::cxx::memory::WeakPtrTarget for #inner_with_generics {\n            fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {\n                f.write_str(#name)\n            }\n            unsafe fn __null(new: *mut ::cxx::core::ffi::c_void) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_null]\n                    fn __null(new: *mut ::cxx::core::ffi::c_void);\n                }\n                unsafe {\n                    __null(new);\n                }\n            }\n            unsafe fn __clone(this: *const ::cxx::core::ffi::c_void, new: *mut ::cxx::core::ffi::c_void) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_clone]\n                    fn __clone(this: *const ::cxx::core::ffi::c_void, new: *mut ::cxx::core::ffi::c_void);\n                }\n                unsafe {\n                    __clone(this, new);\n                }\n            }\n            unsafe fn __downgrade(shared: *const ::cxx::core::ffi::c_void, weak: *mut ::cxx::core::ffi::c_void) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_downgrade]\n                    fn __downgrade(shared: *const ::cxx::core::ffi::c_void, weak: *mut ::cxx::core::ffi::c_void);\n                }\n                unsafe {\n                    __downgrade(shared, weak);\n                }\n            }\n            unsafe fn __upgrade(weak: *const ::cxx::core::ffi::c_void, shared: *mut ::cxx::core::ffi::c_void) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_upgrade]\n                    fn __upgrade(weak: *const ::cxx::core::ffi::c_void, shared: *mut ::cxx::core::ffi::c_void);\n                }\n                unsafe {\n                    __upgrade(weak, shared);\n                }\n            }\n            unsafe fn __drop(this: *mut ::cxx::core::ffi::c_void) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_drop]\n                    fn __drop(this: *mut ::cxx::core::ffi::c_void);\n                }\n                unsafe {\n                    __drop(this);\n                }\n            }\n        }\n    }\n}\n\nfn expand_cxx_vector(\n    key: &NamedImplKey,\n    conditional_impl: &ConditionalImpl,\n    types: &Types,\n) -> TokenStream {\n    let prefix = format!(\"cxxbridge1$std$vector${}$\", key.symbol);\n    let link_new = format!(\"{}new\", prefix);\n    let link_size = format!(\"{}size\", prefix);\n    let link_capacity = format!(\"{}capacity\", prefix);\n    let link_get_unchecked = format!(\"{}get_unchecked\", prefix);\n    let link_reserve = format!(\"{}reserve\", prefix);\n    let link_push_back = format!(\"{}push_back\", prefix);\n    let link_pop_back = format!(\"{}pop_back\", prefix);\n    let unique_ptr_prefix = format!(\"cxxbridge1$unique_ptr$std$vector${}$\", key.symbol);\n    let link_unique_ptr_null = format!(\"{}null\", unique_ptr_prefix);\n    let link_unique_ptr_raw = format!(\"{}raw\", unique_ptr_prefix);\n    let link_unique_ptr_get = format!(\"{}get\", unique_ptr_prefix);\n    let link_unique_ptr_release = format!(\"{}release\", unique_ptr_prefix);\n    let link_unique_ptr_drop = format!(\"{}drop\", unique_ptr_prefix);\n\n    let name = generics::concise_rust_name(key.inner);\n    let (impl_generics, inner_with_generics) =\n        generics::split_for_impl(key, conditional_impl, types);\n\n    let cfg = conditional_impl.cfg.into_attr();\n    let begin_span = conditional_impl\n        .explicit_impl\n        .map_or(key.begin_span, |explicit| explicit.impl_token.span);\n    let end_span = conditional_impl\n        .explicit_impl\n        .map_or(key.end_span, |explicit| explicit.brace_token.span.join());\n    let unsafe_token = format_ident!(\"unsafe\", span = begin_span);\n\n    let can_pass_element_by_value = types.is_maybe_trivial(key.inner);\n    let by_value_methods = if can_pass_element_by_value {\n        Some(quote_spanned! {end_span=>\n            unsafe fn __push_back(\n                this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<Self>>,\n                value: &mut ::cxx::core::mem::ManuallyDrop<Self>,\n            ) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_push_back]\n                    fn __push_back #impl_generics(\n                        this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#inner_with_generics>>,\n                        value: *mut ::cxx::core::ffi::c_void,\n                    );\n                }\n                unsafe {\n                    __push_back(\n                        this,\n                        ::cxx::core::ptr::from_mut::<::cxx::core::mem::ManuallyDrop<Self>>(value).cast::<::cxx::core::ffi::c_void>(),\n                    );\n                }\n            }\n            unsafe fn __pop_back(\n                this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<Self>>,\n                out: &mut ::cxx::core::mem::MaybeUninit<Self>,\n            ) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_pop_back]\n                    fn __pop_back #impl_generics(\n                        this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#inner_with_generics>>,\n                        out: *mut ::cxx::core::ffi::c_void,\n                    );\n                }\n                unsafe {\n                    __pop_back(\n                        this,\n                        ::cxx::core::ptr::from_mut::<::cxx::core::mem::MaybeUninit<Self>>(out).cast::<::cxx::core::ffi::c_void>(),\n                    );\n                }\n            }\n        })\n    } else {\n        None\n    };\n\n    let not_move_constructible_err = format!(\n        \"{} is not move constructible\",\n        generics::concise_cxx_name(key.inner, types),\n    );\n\n    quote_spanned! {end_span=>\n        #cfg\n        #[automatically_derived]\n        #unsafe_token impl #impl_generics ::cxx::vector::VectorElement for #inner_with_generics {\n            fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {\n                f.write_str(#name)\n            }\n            fn __vector_new() -> *mut ::cxx::CxxVector<Self> {\n                unsafe extern \"C\" {\n                    #[link_name = #link_new]\n                    fn __vector_new #impl_generics() -> *mut ::cxx::CxxVector<#inner_with_generics>;\n                }\n                unsafe { __vector_new() }\n            }\n            fn __vector_size(v: &::cxx::CxxVector<Self>) -> ::cxx::core::primitive::usize {\n                unsafe extern \"C\" {\n                    #[link_name = #link_size]\n                    fn __vector_size #impl_generics(_: &::cxx::CxxVector<#inner_with_generics>) -> ::cxx::core::primitive::usize;\n                }\n                unsafe { __vector_size(v) }\n            }\n            fn __vector_capacity(v: &::cxx::CxxVector<Self>) -> ::cxx::core::primitive::usize {\n                unsafe extern \"C\" {\n                    #[link_name = #link_capacity]\n                    fn __vector_capacity #impl_generics(_: &::cxx::CxxVector<#inner_with_generics>) -> ::cxx::core::primitive::usize;\n                }\n                unsafe { __vector_capacity(v) }\n            }\n            unsafe fn __get_unchecked(v: *mut ::cxx::CxxVector<Self>, pos: ::cxx::core::primitive::usize) -> *mut Self {\n                unsafe extern \"C\" {\n                    #[link_name = #link_get_unchecked]\n                    fn __get_unchecked #impl_generics(\n                        v: *mut ::cxx::CxxVector<#inner_with_generics>,\n                        pos: ::cxx::core::primitive::usize,\n                    ) -> *mut ::cxx::core::ffi::c_void;\n                }\n                unsafe { __get_unchecked(v, pos).cast::<Self>() }\n            }\n            unsafe fn __reserve(v: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<Self>>, new_cap: ::cxx::core::primitive::usize) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_reserve]\n                    fn __reserve #impl_generics(\n                        v: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#inner_with_generics>>,\n                        new_cap: ::cxx::core::primitive::usize,\n                    ) -> ::cxx::core::primitive::bool;\n                }\n                if !unsafe { __reserve(v, new_cap) } {\n                    ::cxx::core::panic!(#not_move_constructible_err);\n                }\n            }\n            #by_value_methods\n            fn __unique_ptr_null() -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {\n                unsafe extern \"C\" {\n                    #[link_name = #link_unique_ptr_null]\n                    fn __unique_ptr_null(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>);\n                }\n                let mut repr = ::cxx::core::mem::MaybeUninit::uninit();\n                unsafe {\n                    __unique_ptr_null(&raw mut repr);\n                }\n                repr\n            }\n            unsafe fn __unique_ptr_raw(raw: *mut ::cxx::CxxVector<Self>) -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {\n                unsafe extern \"C\" {\n                    #[link_name = #link_unique_ptr_raw]\n                    fn __unique_ptr_raw #impl_generics(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>, raw: *mut ::cxx::CxxVector<#inner_with_generics>);\n                }\n                let mut repr = ::cxx::core::mem::MaybeUninit::uninit();\n                unsafe {\n                    __unique_ptr_raw(&raw mut repr, raw);\n                }\n                repr\n            }\n            unsafe fn __unique_ptr_get(repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::CxxVector<Self> {\n                unsafe extern \"C\" {\n                    #[link_name = #link_unique_ptr_get]\n                    fn __unique_ptr_get #impl_generics(this: *const ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::CxxVector<#inner_with_generics>;\n                }\n                unsafe { __unique_ptr_get(&raw const repr) }\n            }\n            unsafe fn __unique_ptr_release(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::CxxVector<Self> {\n                unsafe extern \"C\" {\n                    #[link_name = #link_unique_ptr_release]\n                    fn __unique_ptr_release #impl_generics(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::CxxVector<#inner_with_generics>;\n                }\n                unsafe { __unique_ptr_release(&raw mut repr) }\n            }\n            unsafe fn __unique_ptr_drop(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) {\n                unsafe extern \"C\" {\n                    #[link_name = #link_unique_ptr_drop]\n                    fn __unique_ptr_drop(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>);\n                }\n                unsafe {\n                    __unique_ptr_drop(&raw mut repr);\n                }\n            }\n        }\n    }\n}\n\nfn expand_return_type(ret: &Option<Type>) -> TokenStream {\n    match ret {\n        Some(ret) => quote!(-> #ret),\n        None => TokenStream::new(),\n    }\n}\n\nfn indirect_return(sig: &Signature, types: &Types, lang: Lang) -> bool {\n    sig.ret.as_ref().is_some_and(|ret| {\n        sig.throws\n            || types.needs_indirect_abi(ret)\n            || match lang {\n                Lang::Cxx | Lang::CxxUnwind => types.contains_elided_lifetime(ret),\n                Lang::Rust => false,\n            }\n    })\n}\n\nfn expand_extern_type(ty: &Type, types: &Types, proper: bool) -> TokenStream {\n    match ty {\n        Type::Ident(ident) if ident.rust == RustString => {\n            let span = ident.rust.span();\n            quote_spanned!(span=> ::cxx::private::RustString)\n        }\n        Type::RustBox(ty) | Type::UniquePtr(ty) => {\n            let span = ty.name.span();\n            if proper && types.is_considered_improper_ctype(&ty.inner) {\n                quote_spanned!(span=> *mut ::cxx::core::ffi::c_void)\n            } else {\n                let inner = expand_extern_type(&ty.inner, types, proper);\n                quote_spanned!(span=> *mut #inner)\n            }\n        }\n        Type::RustVec(ty) => {\n            // Replace Vec<Foo> with ::cxx::private::RustVec<Foo>. Both have the\n            // same layout but only the latter has a predictable ABI. Note that\n            // the overall size and alignment are independent of the element\n            // type, but the field order inside of Vec may not be.\n            let span = ty.name.span();\n            let langle = ty.langle;\n            let elem = &ty.inner;\n            let rangle = ty.rangle;\n            quote_spanned!(span=> ::cxx::private::RustVec #langle #elem #rangle)\n        }\n        Type::Ref(ty) => {\n            let ampersand = ty.ampersand;\n            let lifetime = &ty.lifetime;\n            let mutability = ty.mutability;\n            match &ty.inner {\n                Type::Ident(ident) if ident.rust == RustString => {\n                    let span = ident.rust.span();\n                    quote_spanned!(span=> #ampersand #lifetime #mutability ::cxx::private::RustString)\n                }\n                Type::RustVec(ty) => {\n                    let span = ty.name.span();\n                    let langle = ty.langle;\n                    let inner = &ty.inner;\n                    let rangle = ty.rangle;\n                    quote_spanned!(span=> #ampersand #lifetime #mutability ::cxx::private::RustVec #langle #inner #rangle)\n                }\n                inner if proper && types.is_considered_improper_ctype(inner) => {\n                    let star = Token![*](ampersand.span);\n                    match ty.mutable {\n                        false => quote!(#star const ::cxx::core::ffi::c_void),\n                        true => quote!(#star #mutability ::cxx::core::ffi::c_void),\n                    }\n                }\n                _ => quote!(#ty),\n            }\n        }\n        Type::Ptr(ty) => {\n            if proper && types.is_considered_improper_ctype(&ty.inner) {\n                let star = ty.star;\n                let mutability = ty.mutability;\n                let constness = ty.constness;\n                quote!(#star #mutability #constness ::cxx::core::ffi::c_void)\n            } else {\n                quote!(#ty)\n            }\n        }\n        Type::Str(ty) => {\n            let span = ty.ampersand.span;\n            let rust_str = Ident::new(\"RustStr\", syn::spanned::Spanned::span(&ty.inner));\n            quote_spanned!(span=> ::cxx::private::#rust_str)\n        }\n        Type::SliceRef(ty) => {\n            let span = ty.ampersand.span;\n            let rust_slice = Ident::new(\"RustSlice\", ty.bracket.span.join());\n            quote_spanned!(span=> ::cxx::private::#rust_slice)\n        }\n        _ => quote!(#ty),\n    }\n}\n\nfn expand_extern_return_type(\n    sig: &Signature,\n    types: &Types,\n    proper: bool,\n    lang: Lang,\n) -> TokenStream {\n    let ret = match &sig.ret {\n        Some(ret) if !indirect_return(sig, types, lang) => ret,\n        _ => return TokenStream::new(),\n    };\n    let ty = expand_extern_type(ret, types, proper);\n    quote!(-> #ty)\n}\n\npub(crate) fn display_namespaced(name: &Pair) -> impl Display + '_ {\n    struct Namespaced<'a>(&'a Pair);\n\n    impl<'a> Display for Namespaced<'a> {\n        fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n            for segment in &self.0.namespace {\n                write!(formatter, \"{segment}::\")?;\n            }\n            write!(formatter, \"{}\", self.0.cxx)\n        }\n    }\n\n    Namespaced(name)\n}\n"
  },
  {
    "path": "macro/src/generics.rs",
    "content": "use crate::expand::display_namespaced;\nuse crate::syntax::instantiate::NamedImplKey;\nuse crate::syntax::types::ConditionalImpl;\nuse crate::syntax::{Lifetimes, Type, Types};\nuse proc_macro2::TokenStream;\nuse quote::{quote, ToTokens};\nuse syn::{Lifetime, Token};\n\npub(crate) struct ResolvedGenericType<'a> {\n    ty: &'a Type,\n    explicit_impl: bool,\n    types: &'a Types<'a>,\n}\n\n/// Gets `(impl_generics, inner_with_generics)` pair that can be used when\n/// generating an `impl` for a generic type:\n///\n/// ```ignore\n/// quote! { impl #impl_generics SomeTrait for #inner_with_generics }\n/// ```\npub(crate) fn split_for_impl<'a>(\n    key: &NamedImplKey<'a>,\n    conditional_impl: &ConditionalImpl<'a>,\n    types: &'a Types<'a>,\n) -> (&'a Lifetimes, ResolvedGenericType<'a>) {\n    let impl_generics = if let Some(explicit_impl) = conditional_impl.explicit_impl {\n        &explicit_impl.impl_generics\n    } else {\n        get_impl_generics(key.inner, types)\n    };\n    let ty_generics = ResolvedGenericType {\n        ty: key.inner,\n        explicit_impl: conditional_impl.explicit_impl.is_some(),\n        types,\n    };\n    (impl_generics, ty_generics)\n}\n\nimpl<'a> ToTokens for ResolvedGenericType<'a> {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        match self.ty {\n            Type::Ident(named_type) => {\n                named_type.rust.to_tokens(tokens);\n                if self.explicit_impl {\n                    named_type.generics.to_tokens(tokens);\n                } else {\n                    let resolve = self.types.resolve(named_type);\n                    if !resolve.generics.lifetimes.is_empty() {\n                        let span = named_type.rust.span();\n                        named_type\n                            .generics\n                            .lt_token\n                            .unwrap_or_else(|| Token![<](span))\n                            .to_tokens(tokens);\n                        resolve.generics.lifetimes.to_tokens(tokens);\n                        named_type\n                            .generics\n                            .gt_token\n                            .unwrap_or_else(|| Token![>](span))\n                            .to_tokens(tokens);\n                    }\n                }\n            }\n            Type::RustBox(ty1) => {\n                let inner = ResolvedGenericType {\n                    ty: &ty1.inner,\n                    explicit_impl: self.explicit_impl,\n                    types: self.types,\n                };\n                tokens.extend(quote! {\n                    ::cxx::alloc::boxed::Box<#inner>\n                });\n            }\n            _ => unreachable!(\"syntax/check.rs should reject other types\"),\n        }\n    }\n}\n\nfn get_impl_generics<'a>(ty: &Type, types: &Types<'a>) -> &'a Lifetimes {\n    match ty {\n        Type::Ident(named_type) => types.resolve(named_type).generics,\n        Type::RustBox(ty1) => get_impl_generics(&ty1.inner, types),\n        _ => unreachable!(\"syntax/check.rs should reject other types\"),\n    }\n}\n\npub(crate) fn format_for_prevent_unwind_label(ty: &Type) -> TokenStream {\n    match ty {\n        Type::Ident(named_type) => {\n            let rust_name = named_type.rust.to_string();\n            quote! {\n                ::cxx::core::concat!(::cxx::core::module_path!(), \"::\", #rust_name)\n            }\n        }\n        Type::RustBox(ty1) => {\n            let inner = format_for_prevent_unwind_label(&ty1.inner);\n            quote! {\n                ::cxx::core::concat!(\"Box<\", #inner, \">\")\n            }\n        }\n        _ => unreachable!(\"syntax/check.rs should reject other types\"),\n    }\n}\n\npub(crate) fn concise_rust_name(ty: &Type) -> String {\n    match ty {\n        Type::Ident(named_type) => named_type.rust.to_string(),\n        Type::RustBox(ty1) => {\n            let inner = concise_rust_name(&ty1.inner);\n            format!(\"Box<{inner}>\")\n        }\n        _ => unreachable!(\"syntax/check.rs should reject other types\"),\n    }\n}\n\npub(crate) fn concise_cxx_name(ty: &Type, types: &Types) -> String {\n    match ty {\n        Type::Ident(named_type) => {\n            let res = types.resolve(&named_type.rust);\n            display_namespaced(res.name).to_string()\n        }\n        Type::RustBox(ty1) => {\n            let inner = concise_cxx_name(&ty1.inner, types);\n            format!(\"rust::Box<{inner}>\")\n        }\n        _ => unreachable!(\"syntax/check.rs should reject other types\"),\n    }\n}\n\npub(crate) struct UnderscoreLifetimes<'a> {\n    generics: &'a Lifetimes,\n}\n\nimpl Lifetimes {\n    pub(crate) fn to_underscore_lifetimes(&self) -> UnderscoreLifetimes {\n        UnderscoreLifetimes { generics: self }\n    }\n}\n\nimpl<'a> ToTokens for UnderscoreLifetimes<'a> {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let Lifetimes {\n            lt_token,\n            lifetimes,\n            gt_token,\n        } = self.generics;\n        lt_token.to_tokens(tokens);\n        for pair in lifetimes.pairs() {\n            let (lifetime, punct) = pair.into_tuple();\n            let lifetime = Lifetime::new(\"'_\", lifetime.span());\n            lifetime.to_tokens(tokens);\n            punct.to_tokens(tokens);\n        }\n        gt_token.to_tokens(tokens);\n    }\n}\n"
  },
  {
    "path": "macro/src/lib.rs",
    "content": "#![allow(\n    clippy::cast_sign_loss,\n    clippy::doc_markdown,\n    clippy::elidable_lifetime_names,\n    clippy::enum_glob_use,\n    clippy::expl_impl_clone_on_copy, // https://github.com/rust-lang/rust-clippy/issues/15842\n    clippy::inherent_to_string,\n    clippy::items_after_statements,\n    clippy::match_bool,\n    clippy::match_like_matches_macro,\n    clippy::match_same_arms,\n    clippy::needless_lifetimes,\n    clippy::needless_pass_by_value,\n    clippy::nonminimal_bool,\n    clippy::precedence,\n    clippy::redundant_else,\n    clippy::ref_option,\n    clippy::similar_names,\n    clippy::single_match_else,\n    clippy::struct_field_names,\n    clippy::too_many_arguments,\n    clippy::too_many_lines,\n    clippy::toplevel_ref_arg,\n    clippy::uninlined_format_args,\n    clippy::wrong_self_convention\n)]\n#![cfg_attr(test, allow(dead_code, unfulfilled_lint_expectations))]\n#![allow(unknown_lints, mismatched_lifetime_syntaxes)]\n\nmod attrs;\nmod cfg;\nmod derive;\nmod expand;\nmod generics;\nmod syntax;\n#[cfg(test)]\nmod tests;\nmod tokens;\nmod type_id;\n\nuse crate::syntax::file::Module;\nuse crate::syntax::namespace::Namespace;\nuse crate::syntax::qualified::QualifiedName;\nuse crate::type_id::Crate;\nuse proc_macro::TokenStream;\nuse syn::parse::{Parse, ParseStream, Parser, Result};\nuse syn::parse_macro_input;\n\n/// `#[cxx::bridge] mod ffi { ... }`\n///\n/// Refer to the crate-level documentation for the explanation of how this macro\n/// is intended to be used.\n///\n/// The only additional thing to note here is namespace support &mdash; if the\n/// types and functions on the `extern \"C++\"` side of our bridge are in a\n/// namespace, specify that namespace as an argument of the cxx::bridge\n/// attribute macro.\n///\n/// ```\n/// #[cxx::bridge(namespace = \"mycompany::rust\")]\n/// # mod ffi {}\n/// ```\n///\n/// The types and functions from the `extern \"Rust\"` side of the bridge will be\n/// placed into that same namespace in the generated C++ code.\n#[proc_macro_attribute]\npub fn bridge(args: TokenStream, input: TokenStream) -> TokenStream {\n    let _ = syntax::error::ERRORS;\n\n    let namespace = match Namespace::parse_bridge_attr_namespace.parse(args) {\n        Ok(namespace) => namespace,\n        Err(err) => return err.to_compile_error().into(),\n    };\n    let mut ffi = parse_macro_input!(input as Module);\n    ffi.namespace = namespace;\n\n    expand::bridge(ffi)\n        .unwrap_or_else(|err| err.to_compile_error())\n        .into()\n}\n\n#[doc(hidden)]\n#[proc_macro]\npub fn type_id(input: TokenStream) -> TokenStream {\n    struct TypeId {\n        krate: Crate,\n        path: QualifiedName,\n    }\n\n    impl Parse for TypeId {\n        fn parse(input: ParseStream) -> Result<Self> {\n            let krate = input.parse().map(Crate::DollarCrate)?;\n            let path = QualifiedName::parse_quoted_or_unquoted(input)?;\n            Ok(TypeId { krate, path })\n        }\n    }\n\n    let arg = parse_macro_input!(input as TypeId);\n    type_id::expand(arg.krate, arg.path).into()\n}\n"
  },
  {
    "path": "macro/src/tests.rs",
    "content": "use crate::expand;\nuse crate::syntax::file::Module;\nuse proc_macro2::TokenStream;\nuse quote::quote;\nuse syn::File;\n\nfn bridge(cxx_bridge: TokenStream) -> String {\n    let module = syn::parse2::<Module>(cxx_bridge).unwrap();\n    let tokens = expand::bridge(module).unwrap();\n    let file = match syn::parse2::<File>(tokens.clone()) {\n        Ok(file) => file,\n        Err(err) => {\n            eprintln!(\"The code below is syntactically invalid: {err}:\");\n            eprintln!(\"{tokens}\");\n            panic!(\"`expand::bridge` should generate syntactically valid code\");\n        }\n    };\n    let pretty = prettyplease::unparse(&file);\n    eprintln!(\"{0:/<80}\\n{pretty}{0:/<80}\", \"\");\n    pretty\n}\n\n#[test]\nfn test_unique_ptr_with_elided_lifetime_implicit_impl() {\n    let rs = bridge(quote! {\n        mod ffi {\n            unsafe extern \"C++\" {\n                type Borrowed<'a>;\n                fn borrowed(arg: &i32) -> UniquePtr<Borrowed>;\n            }\n        }\n    });\n\n    // It is okay that the return type elides Borrowed's lifetime parameter.\n    assert!(rs.contains(\"pub fn borrowed(arg: &i32) -> ::cxx::UniquePtr<Borrowed>\"));\n\n    // But in impl blocks, the lifetime parameter needs to be present.\n    assert!(rs.contains(\"unsafe impl<'a> ::cxx::ExternType for Borrowed<'a> {\"));\n    assert!(rs.contains(\"unsafe impl<'a> ::cxx::memory::UniquePtrTarget for Borrowed<'a> {\"));\n\n    // Wrong.\n    assert!(!rs.contains(\"unsafe impl ::cxx::ExternType for Borrowed {\"));\n    assert!(!rs.contains(\"unsafe impl ::cxx::memory::UniquePtrTarget for Borrowed {\"));\n\n    // Potentially okay, but not what we currently do.\n    assert!(!rs.contains(\"unsafe impl ::cxx::ExternType for Borrowed<'_> {\"));\n    assert!(!rs.contains(\"unsafe impl ::cxx::memory::UniquePtrTarget for Borrowed<'_> {\"));\n}\n\n#[test]\nfn test_unique_ptr_lifetimes_from_explicit_impl() {\n    let rs = bridge(quote! {\n        mod ffi {\n            unsafe extern \"C++\" {\n                type Borrowed<'a>;\n            }\n            impl<'b> UniquePtr<Borrowed<'c>> {}\n        }\n    });\n\n    // Lifetimes use the name from the extern type.\n    assert!(rs.contains(\"unsafe impl<'a> ::cxx::ExternType for Borrowed<'a>\"));\n\n    // Lifetimes use the names written in the explicit impl if one is present.\n    assert!(rs.contains(\"unsafe impl<'b> ::cxx::memory::UniquePtrTarget for Borrowed<'c>\"));\n}\n\n#[test]\nfn test_vec_string() {\n    let rs = bridge(quote! {\n        mod ffi {\n            extern \"Rust\" {\n                fn foo() -> Vec<String>;\n            }\n        }\n    });\n\n    // No substitution of String <=> ::cxx::private::RustString.\n    assert!(rs.contains(\"__return: *mut ::cxx::private::RustVec<::cxx::alloc::string::String>\"));\n    assert!(rs.contains(\"fn __foo() -> ::cxx::alloc::vec::Vec<::cxx::alloc::string::String>\"));\n\n    let rs = bridge(quote! {\n        mod ffi {\n            extern \"Rust\" {\n                fn foo(v: &Vec<String>);\n            }\n        }\n    });\n\n    // No substitution of String <=> ::cxx::private::RustString.\n    assert!(rs.contains(\"v: &::cxx::private::RustVec<::cxx::alloc::string::String>\"));\n    assert!(rs.contains(\"fn __foo(v: &::cxx::alloc::vec::Vec<::cxx::alloc::string::String>)\"));\n}\n\n#[test]\nfn test_mangling_covers_cpp_namespace_of_vec_elements() {\n    let rs = bridge(quote! {\n        mod ffi {\n            #[namespace = \"test_namespace\"]\n            struct Context { x: i32 }\n            impl Vec<Context> {}\n        }\n    });\n\n    // Mangling must include Context's C++ namespace to avoid colliding the\n    // symbol names for two identically named structs in different namespaces.\n    assert!(rs.contains(\"export_name = \\\"cxxbridge1$rust_vec$test_namespace$Context$set_len\\\"\"));\n}\n\n#[test]\nfn test_struct_with_lifetime() {\n    let rs = bridge(quote! {\n        mod ffi {\n            struct StructWithLifetime<'a> {\n                s: &'a str,\n            }\n            extern \"Rust\" {\n                fn f(_: UniquePtr<StructWithLifetime<>>);\n            }\n        }\n    });\n\n    // Regression test for <https://github.com/dtolnay/cxx/pull/1658#discussion_r2529463814>\n    // which generated this invalid code:\n    //\n    //     impl<'a> ::cxx::memory::UniquePtrTarget for StructWithLifetime < > < 'a > {\n    //\n    // Invalid syntax in the output code would already have caused the test\n    // helper `bridge` to panic above. But for completeness this assertion\n    // verifies the intended code has been generated.\n    assert!(rs.contains(\"impl<'a> ::cxx::memory::UniquePtrTarget for StructWithLifetime<'a> {\"));\n\n    // Assertions for other places that refer to `StructWithLifetime`.\n    assert!(rs.contains(\"pub struct StructWithLifetime<'a> {\"));\n    assert!(rs.contains(\"cast::<StructWithLifetime<'a>>()\"));\n    assert!(rs.contains(\"fn __f(arg0: ::cxx::UniquePtr<StructWithLifetime>) {\"));\n    assert!(rs.contains(\"impl<'a> self::Drop for super::StructWithLifetime<'a>\"));\n}\n\n#[test]\nfn test_original_lifetimes_used_in_impls() {\n    let rs = bridge(quote! {\n        mod ffi {\n            struct Context<'sess> {\n                session: &'sess str,\n            }\n            struct Server<'srv> {\n                ctx: UniquePtr<Context<'srv>>,\n            }\n            struct Client<'clt> {\n                ctx: UniquePtr<Context<'clt>>,\n            }\n        }\n    });\n\n    // Verify which lifetime name ('sess, 'srv, 'clt) gets used for this impl.\n    assert!(rs.contains(\"impl<'sess> ::cxx::memory::UniquePtrTarget for Context<'sess> {\"));\n}\n\n/// This test covers implicit impl of `Vec<Box<T>>`.\n#[test]\nfn test_vec_of_box() {\n    let rs = bridge(quote! {\n        mod ffi {\n            extern \"Rust\" {\n                type R;\n                fn foo() -> Vec<Box<R>>;\n            }\n        }\n    });\n\n    assert!(rs.contains(\"unsafe impl ::cxx::private::ImplBox for R {}\"));\n    assert!(rs.contains(\"export_name = \\\"cxxbridge1$box$R$drop\\\"\"));\n\n    assert!(rs.contains(\"unsafe impl ::cxx::private::ImplVec for ::cxx::alloc::boxed::Box<R> {}\"));\n    assert!(rs.contains(\"export_name = \\\"cxxbridge1$rust_vec$box$R$set_len\\\"\"));\n\n    // Not supposed to be `RustVec<*mut R>` (which happened in an early draft).\n    assert!(rs.contains(\"__return: *mut ::cxx::private::RustVec<::cxx::alloc::boxed::Box<R>>\"));\n    assert!(rs.contains(\"fn __foo() -> ::cxx::alloc::vec::Vec<::cxx::alloc::boxed::Box<R>>\"));\n}\n"
  },
  {
    "path": "macro/src/tokens.rs",
    "content": "use crate::syntax::Receiver;\nuse proc_macro2::TokenStream;\nuse quote::{quote_spanned, ToTokens};\nuse syn::Token;\n\npub(crate) struct ReceiverType<'a>(&'a Receiver);\npub(crate) struct ReceiverTypeSelf<'a>(&'a Receiver);\n\nimpl Receiver {\n    // &TheType\n    pub(crate) fn ty(&self) -> ReceiverType {\n        ReceiverType(self)\n    }\n\n    // &Self\n    pub(crate) fn ty_self(&self) -> ReceiverTypeSelf {\n        ReceiverTypeSelf(self)\n    }\n}\n\nimpl ToTokens for ReceiverType<'_> {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let Receiver {\n            pinned: _,\n            ampersand,\n            lifetime,\n            mutable: _,\n            var: _,\n            colon_token: _,\n            ty,\n            shorthand: _,\n            pin_tokens,\n            mutability,\n        } = &self.0;\n        if let Some((pin, langle, _rangle)) = pin_tokens {\n            tokens.extend(quote_spanned!(pin.span=> ::cxx::core::pin::Pin));\n            langle.to_tokens(tokens);\n        }\n        ampersand.to_tokens(tokens);\n        lifetime.to_tokens(tokens);\n        mutability.to_tokens(tokens);\n        ty.to_tokens(tokens);\n        if let Some((_pin, _langle, rangle)) = pin_tokens {\n            rangle.to_tokens(tokens);\n        }\n    }\n}\n\nimpl ToTokens for ReceiverTypeSelf<'_> {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let Receiver {\n            pinned: _,\n            ampersand,\n            lifetime,\n            mutable: _,\n            var: _,\n            colon_token: _,\n            ty,\n            shorthand: _,\n            pin_tokens,\n            mutability,\n        } = &self.0;\n        if let Some((pin, langle, _rangle)) = pin_tokens {\n            tokens.extend(quote_spanned!(pin.span=> ::cxx::core::pin::Pin));\n            langle.to_tokens(tokens);\n        }\n        ampersand.to_tokens(tokens);\n        lifetime.to_tokens(tokens);\n        mutability.to_tokens(tokens);\n        Token![Self](ty.rust.span()).to_tokens(tokens);\n        if let Some((_pin, _langle, rangle)) = pin_tokens {\n            rangle.to_tokens(tokens);\n        }\n    }\n}\n"
  },
  {
    "path": "macro/src/type_id.rs",
    "content": "use crate::syntax::qualified::QualifiedName;\nuse proc_macro2::{TokenStream, TokenTree};\nuse quote::{format_ident, quote, ToTokens};\nuse syn::ext::IdentExt;\n\npub(crate) enum Crate {\n    Cxx,\n    DollarCrate(TokenTree),\n}\n\nimpl ToTokens for Crate {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        match self {\n            Crate::Cxx => tokens.extend(quote!(::cxx)),\n            Crate::DollarCrate(krate) => krate.to_tokens(tokens),\n        }\n    }\n}\n\n// \"folly::File\" => `(f, o, l, l, y, (), F, i, l, e)`\npub(crate) fn expand(krate: Crate, arg: QualifiedName) -> TokenStream {\n    let mut ids = Vec::new();\n\n    for word in arg.segments {\n        if !ids.is_empty() {\n            ids.push(quote!(()));\n        }\n        for ch in word.unraw().to_string().chars() {\n            ids.push(match ch {\n                'A'..='Z' | 'a'..='z' => {\n                    let t = format_ident!(\"{}\", ch);\n                    quote!(#krate::#t)\n                }\n                '0'..='9' | '_' => {\n                    let t = format_ident!(\"_{}\", ch);\n                    quote!(#krate::#t)\n                }\n                _ => quote!([(); #ch as _]),\n            });\n        }\n    }\n\n    quote! { (#(#ids,)*) }\n}\n"
  },
  {
    "path": "reindeer.toml",
    "content": "error = \"This is the wrong directory. Run `reindeer buckify` in the third-party directory.\"\n"
  },
  {
    "path": "rust-toolchain.toml",
    "content": "[toolchain]\ncomponents = [\"rust-src\"]\n"
  },
  {
    "path": "src/cxx.cc",
    "content": "#include \"../include/cxx.h\"\n#include <cstdio>\n#include <cstring>\n#include <iostream>\n#include <memory>\n\n#ifdef __cpp_lib_bit_cast\n#include <bit>\n#endif\n\n// Most compilers set __cpp_attributes on C++11 and up, and set __cpp_exceptions\n// if the flag `-fno-exceptions` is not set. On these compilers we detect\n// `-fno-exceptions` this way.\n//\n// Some compilers never set either one. On these, rely on the user to do\n// `-DRUST_CXX_NO_EXCEPTIONS` if they are not using exceptions.\n//\n// On MSVC, it is possible for exception throwing and catching to be enabled\n// without __cpp_exceptions being defined, so do not try to detect anything.\n#if !defined(RUST_CXX_NO_EXCEPTIONS) && defined(__cpp_attributes) &&           \\\n    !defined(__cpp_exceptions) && (!defined(_MSC_VER) || defined(__llvm__))\n#define RUST_CXX_NO_EXCEPTIONS\n#endif\n\n#ifdef __GNUC__\n#pragma GCC diagnostic ignored \"-Wmissing-declarations\"\n#pragma GCC diagnostic ignored \"-Wshadow\"\n#endif\n#ifdef __clang__\n#pragma clang diagnostic ignored \"-Wdollar-in-identifier-extension\"\n#endif\n\nextern \"C\" {\nvoid cxxbridge1$cxx_string$init(std::string *s, const std::uint8_t *ptr,\n                                std::size_t len) noexcept {\n  new (s) std::string(reinterpret_cast<const char *>(ptr), len);\n}\n\nvoid cxxbridge1$cxx_string$destroy(std::string *s) noexcept {\n  using std::string;\n  s->~string();\n}\n\nconst char *cxxbridge1$cxx_string$data(const std::string &s) noexcept {\n  return s.data();\n}\n\nstd::size_t cxxbridge1$cxx_string$length(const std::string &s) noexcept {\n  return s.length();\n}\n\nvoid cxxbridge1$cxx_string$clear(std::string &s) noexcept { s.clear(); }\n\nvoid cxxbridge1$cxx_string$reserve_total(std::string &s,\n                                         size_t new_cap) noexcept {\n  s.reserve(new_cap);\n}\n\nvoid cxxbridge1$cxx_string$push(std::string &s, const std::uint8_t *ptr,\n                                std::size_t len) noexcept {\n  s.append(reinterpret_cast<const char *>(ptr), len);\n}\n\n// rust::String\nvoid cxxbridge1$string$new(rust::String *self) noexcept;\nvoid cxxbridge1$string$clone(rust::String *self,\n                             const rust::String &other) noexcept;\nbool cxxbridge1$string$from_utf8(rust::String *self, const char *ptr,\n                                 std::size_t len) noexcept;\nvoid cxxbridge1$string$from_utf8_lossy(rust::String *self, const char *ptr,\n                                       std::size_t len) noexcept;\nbool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr,\n                                  std::size_t len) noexcept;\nvoid cxxbridge1$string$from_utf16_lossy(rust::String *self, const char16_t *ptr,\n                                        std::size_t len) noexcept;\nvoid cxxbridge1$string$drop(rust::String *self) noexcept;\nconst char *cxxbridge1$string$ptr(const rust::String *self) noexcept;\nstd::size_t cxxbridge1$string$len(const rust::String *self) noexcept;\nstd::size_t cxxbridge1$string$capacity(const rust::String *self) noexcept;\nvoid cxxbridge1$string$reserve_additional(rust::String *self,\n                                          size_t additional) noexcept;\nvoid cxxbridge1$string$reserve_total(rust::String *self,\n                                     size_t new_cap) noexcept;\n\n// rust::Str\nvoid cxxbridge1$str$new(rust::Str *self) noexcept;\nvoid cxxbridge1$str$ref(rust::Str *self, const rust::String *string) noexcept;\nbool cxxbridge1$str$from(rust::Str *self, const char *ptr,\n                         std::size_t len) noexcept;\nconst char *cxxbridge1$str$ptr(const rust::Str *self) noexcept;\nstd::size_t cxxbridge1$str$len(const rust::Str *self) noexcept;\n\n// rust::Slice\nvoid cxxbridge1$slice$new(void *self, const void *ptr,\n                          std::size_t len) noexcept;\nvoid *cxxbridge1$slice$ptr(const void *self) noexcept;\nstd::size_t cxxbridge1$slice$len(const void *self) noexcept;\n} // extern \"C\"\n\nnamespace rust {\ninline namespace cxxbridge1 {\n\ntemplate <typename Exception>\nvoid panic [[noreturn]] (const char *msg) {\n#if defined(RUST_CXX_NO_EXCEPTIONS)\n  std::fprintf(stderr, \"Error: %s. Aborting.\\n\", msg);\n  std::abort();\n#else\n  throw Exception(msg);\n#endif\n}\n\ntemplate void panic<std::out_of_range> [[noreturn]] (const char *msg);\n\ntemplate <typename T>\nstatic bool is_aligned(const void *ptr) noexcept {\n  auto iptr = reinterpret_cast<std::uintptr_t>(ptr);\n  return !(iptr % alignof(T));\n}\n\nString::String() noexcept { cxxbridge1$string$new(this); }\n\nString::String(const String &other) noexcept {\n  cxxbridge1$string$clone(this, other);\n}\n\nString::String(String &&other) noexcept : repr(other.repr) {\n  cxxbridge1$string$new(&other);\n}\n\nString::~String() noexcept { cxxbridge1$string$drop(this); }\n\nstatic void initString(String *self, const char *s, std::size_t len) {\n  if (!cxxbridge1$string$from_utf8(self, s, len)) {\n    panic<std::invalid_argument>(\"data for rust::String is not utf-8\");\n  }\n}\n\nstatic void initString(String *self, const char16_t *s, std::size_t len) {\n  if (!cxxbridge1$string$from_utf16(self, s, len)) {\n    panic<std::invalid_argument>(\"data for rust::String is not utf-16\");\n  }\n}\n\nString::String(const std::string &s) { initString(this, s.data(), s.length()); }\n\nString::String(const char *s) {\n  assert(s != nullptr);\n  initString(this, s, std::strlen(s));\n}\n\nString::String(const char *s, std::size_t len) {\n  assert(s != nullptr || len == 0);\n  initString(this,\n             s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,\n             len);\n}\n\n#ifdef __cpp_char8_t\nString::String(const char8_t *s) : String(reinterpret_cast<const char *>(s)) {}\n\nString::String(const char8_t *s, std::size_t len)\n    : String(reinterpret_cast<const char *>(s), len) {}\n#endif\n\nString::String(const char16_t *s) {\n  assert(s != nullptr);\n  assert(is_aligned<char16_t>(s));\n  initString(this, s, std::char_traits<char16_t>::length(s));\n}\n\nString::String(const char16_t *s, std::size_t len) {\n  assert(s != nullptr || len == 0);\n  assert(is_aligned<char16_t>(s));\n  initString(this,\n             s == nullptr && len == 0 ? reinterpret_cast<const char16_t *>(2)\n                                      : s,\n             len);\n}\n\nstruct String::lossy_t {};\n\nString::String(lossy_t, const char *s, std::size_t len) noexcept {\n  cxxbridge1$string$from_utf8_lossy(\n      this, s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,\n      len);\n}\n\nString::String(lossy_t, const char16_t *s, std::size_t len) noexcept {\n  cxxbridge1$string$from_utf16_lossy(\n      this,\n      s == nullptr && len == 0 ? reinterpret_cast<const char16_t *>(2) : s,\n      len);\n}\n\nString String::lossy(const std::string &s) noexcept {\n  return String::lossy(s.data(), s.length());\n}\n\nString String::lossy(const char *s) noexcept {\n  assert(s != nullptr);\n  return String::lossy(s, std::strlen(s));\n}\n\nString String::lossy(const char *s, std::size_t len) noexcept {\n  assert(s != nullptr || len == 0);\n  return String(lossy_t{}, s, len);\n}\n\nString String::lossy(const char16_t *s) noexcept {\n  assert(s != nullptr);\n  assert(is_aligned<char16_t>(s));\n  return String(lossy_t{}, s, std::char_traits<char16_t>::length(s));\n}\n\nString String::lossy(const char16_t *s, std::size_t len) noexcept {\n  assert(s != nullptr || len == 0);\n  assert(is_aligned<char16_t>(s));\n  return String(lossy_t{}, s, len);\n}\n\nString &String::operator=(const String &other) & noexcept {\n  if (this != &other) {\n    cxxbridge1$string$drop(this);\n    cxxbridge1$string$clone(this, other);\n  }\n  return *this;\n}\n\nString &String::operator=(String &&other) & noexcept {\n  cxxbridge1$string$drop(this);\n  this->repr = other.repr;\n  cxxbridge1$string$new(&other);\n  return *this;\n}\n\nString::operator std::string() const {\n  return std::string(this->data(), this->size());\n}\n\nconst char *String::data() const noexcept {\n  return cxxbridge1$string$ptr(this);\n}\n\nstd::size_t String::size() const noexcept {\n  return cxxbridge1$string$len(this);\n}\n\nstd::size_t String::length() const noexcept {\n  return cxxbridge1$string$len(this);\n}\n\nbool String::empty() const noexcept { return this->size() == 0; }\n\nconst char *String::c_str() noexcept {\n  auto len = this->length();\n  cxxbridge1$string$reserve_additional(this, 1);\n  auto ptr = this->data();\n  const_cast<char *>(ptr)[len] = '\\0';\n  return ptr;\n}\n\nstd::size_t String::capacity() const noexcept {\n  return cxxbridge1$string$capacity(this);\n}\n\nvoid String::reserve(std::size_t new_cap) noexcept {\n  cxxbridge1$string$reserve_total(this, new_cap);\n}\n\nString::iterator String::begin() noexcept {\n  return const_cast<char *>(this->data());\n}\n\nString::iterator String::end() noexcept {\n  return const_cast<char *>(this->data()) + this->size();\n}\n\nString::const_iterator String::begin() const noexcept { return this->cbegin(); }\n\nString::const_iterator String::end() const noexcept { return this->cend(); }\n\nString::const_iterator String::cbegin() const noexcept { return this->data(); }\n\nString::const_iterator String::cend() const noexcept {\n  return this->data() + this->size();\n}\n\nbool String::operator==(const String &rhs) const noexcept {\n  return rust::Str(*this) == rust::Str(rhs);\n}\n\nbool String::operator!=(const String &rhs) const noexcept {\n  return rust::Str(*this) != rust::Str(rhs);\n}\n\nbool String::operator<(const String &rhs) const noexcept {\n  return rust::Str(*this) < rust::Str(rhs);\n}\n\nbool String::operator<=(const String &rhs) const noexcept {\n  return rust::Str(*this) <= rust::Str(rhs);\n}\n\nbool String::operator>(const String &rhs) const noexcept {\n  return rust::Str(*this) > rust::Str(rhs);\n}\n\nbool String::operator>=(const String &rhs) const noexcept {\n  return rust::Str(*this) >= rust::Str(rhs);\n}\n\nvoid String::swap(String &rhs) noexcept {\n  using std::swap;\n  swap(this->repr, rhs.repr);\n}\n\nString::String(unsafe_bitcopy_t, const String &bits) noexcept\n    : repr(bits.repr) {}\n\nstd::ostream &operator<<(std::ostream &os, const String &s) {\n  os.write(s.data(), static_cast<std::streamsize>(s.size()));\n  return os;\n}\n\nStr::Str() noexcept { cxxbridge1$str$new(this); }\n\nStr::Str(const String &s) noexcept { cxxbridge1$str$ref(this, &s); }\n\nstatic void initStr(Str *self, const char *ptr, std::size_t len) {\n  if (!cxxbridge1$str$from(self, ptr, len)) {\n    panic<std::invalid_argument>(\"data for rust::Str is not utf-8\");\n  }\n}\n\nStr::Str(const std::string &s) { initStr(this, s.data(), s.length()); }\n\nStr::Str(const char *s) {\n  assert(s != nullptr);\n  initStr(this, s, std::strlen(s));\n}\n\nStr::Str(const char *s, std::size_t len) {\n  assert(s != nullptr || len == 0);\n  initStr(this,\n          s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,\n          len);\n}\n\nStr::operator std::string() const {\n  return std::string(this->data(), this->size());\n}\n\n#if __cplusplus >= 201703L\nStr::operator std::string_view() const {\n  return std::string_view(this->data(), this->size());\n}\n#endif\n\nconst char *Str::data() const noexcept { return cxxbridge1$str$ptr(this); }\n\nstd::size_t Str::size() const noexcept { return cxxbridge1$str$len(this); }\n\nstd::size_t Str::length() const noexcept { return this->size(); }\n\nbool Str::empty() const noexcept { return this->size() == 0; }\n\nStr::const_iterator Str::begin() const noexcept { return this->cbegin(); }\n\nStr::const_iterator Str::end() const noexcept { return this->cend(); }\n\nStr::const_iterator Str::cbegin() const noexcept { return this->data(); }\n\nStr::const_iterator Str::cend() const noexcept {\n  return this->data() + this->size();\n}\n\nbool Str::operator==(const Str &rhs) const noexcept {\n  return this->size() == rhs.size() &&\n         std::equal(this->begin(), this->end(), rhs.begin());\n}\n\nbool Str::operator!=(const Str &rhs) const noexcept { return !(*this == rhs); }\n\nbool Str::operator<(const Str &rhs) const noexcept {\n  return std::lexicographical_compare(this->begin(), this->end(), rhs.begin(),\n                                      rhs.end());\n}\n\nbool Str::operator<=(const Str &rhs) const noexcept {\n  // std::mismatch(this->begin(), this->end(), rhs.begin(), rhs.end()), except\n  // without Undefined Behavior on C++11 if rhs is shorter than *this.\n  const_iterator liter = this->begin(), lend = this->end(), riter = rhs.begin(),\n                 rend = rhs.end();\n  while (liter != lend && riter != rend && *liter == *riter) {\n    ++liter;\n    ++riter;\n  }\n  if (liter == lend) {\n    return true; // equal or *this is a prefix of rhs\n  } else if (riter == rend) {\n    return false; // rhs is a prefix of *this\n  } else {\n    return *liter <= *riter;\n  }\n}\n\nbool Str::operator>(const Str &rhs) const noexcept { return rhs < *this; }\n\nbool Str::operator>=(const Str &rhs) const noexcept { return rhs <= *this; }\n\nvoid Str::swap(Str &rhs) noexcept {\n  using std::swap;\n  swap(this->repr, rhs.repr);\n}\n\nstd::ostream &operator<<(std::ostream &os, const Str &s) {\n  os.write(s.data(), static_cast<std::streamsize>(s.size()));\n  return os;\n}\n\nvoid sliceInit(void *self, const void *ptr, std::size_t len) noexcept {\n  cxxbridge1$slice$new(self, ptr, len);\n}\n\nvoid *slicePtr(const void *self) noexcept { return cxxbridge1$slice$ptr(self); }\n\nstd::size_t sliceLen(const void *self) noexcept {\n  return cxxbridge1$slice$len(self);\n}\n\n// Rust specifies that usize is ABI compatible with C's uintptr_t.\n// https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#isize-and-usize\n// However there is no direct Rust equivalent for size_t. C does not guarantee\n// that size_t and uintptr_t are compatible. In practice though, on all\n// platforms supported by Rust, they are identical for ABI purposes. See the\n// libc crate which unconditionally defines libc::size_t = usize. We expect the\n// same here and these assertions are just here to explicitly document that.\n// *Note that no assumption is made about C++ name mangling of signatures\n// containing these types, not here nor anywhere in CXX.*\nstatic_assert(sizeof(std::size_t) == sizeof(std::uintptr_t),\n              \"unsupported size_t size\");\nstatic_assert(alignof(std::size_t) == alignof(std::uintptr_t),\n              \"unsupported size_t alignment\");\nstatic_assert(sizeof(rust::isize) == sizeof(std::intptr_t),\n              \"unsupported ssize_t size\");\nstatic_assert(alignof(rust::isize) == alignof(std::intptr_t),\n              \"unsupported ssize_t alignment\");\n\n// The C++ standard does not guarantee a particular size, alignment, or bit\n// pattern for bool. In practice on all platforms supported by Rust, it is\n// compatible with Rust's bool. The libc crate freely uses Rust bool in\n// foreign function signatures.\nstatic_assert(sizeof(bool) == 1, \"unsupported bool size\");\nstatic_assert(alignof(bool) == 1, \"unsupported bool alignment\");\n#ifdef __cpp_lib_bit_cast\nstatic_assert(std::bit_cast<std::uint8_t>(false) == 0,\n              \"unsupported bit representation of false\");\nstatic_assert(std::bit_cast<std::uint8_t>(true) == 1,\n              \"unsupported bit representation of true\");\n#endif\n\nstatic_assert(std::is_trivially_copy_constructible<Str>::value,\n              \"trivial Str(const Str &)\");\nstatic_assert(std::is_trivially_copy_assignable<Str>::value,\n              \"trivial operator=(const Str &)\");\nstatic_assert(std::is_trivially_destructible<Str>::value, \"trivial ~Str()\");\n\nstatic_assert(\n    std::is_trivially_copy_constructible<Slice<const std::uint8_t>>::value,\n    \"trivial Slice(const Slice &)\");\nstatic_assert(\n    std::is_trivially_move_constructible<Slice<const std::uint8_t>>::value,\n    \"trivial Slice(Slice &&)\");\nstatic_assert(\n    std::is_trivially_copy_assignable<Slice<const std::uint8_t>>::value,\n    \"trivial Slice::operator=(const Slice &) for const slices\");\nstatic_assert(\n    std::is_trivially_move_assignable<Slice<const std::uint8_t>>::value,\n    \"trivial Slice::operator=(Slice &&)\");\nstatic_assert(std::is_trivially_destructible<Slice<const std::uint8_t>>::value,\n              \"trivial ~Slice()\");\n\nstatic_assert(std::is_trivially_copy_constructible<Slice<std::uint8_t>>::value,\n              \"trivial Slice(const Slice &)\");\nstatic_assert(std::is_trivially_move_constructible<Slice<std::uint8_t>>::value,\n              \"trivial Slice(Slice &&)\");\nstatic_assert(!std::is_copy_assignable<Slice<std::uint8_t>>::value,\n              \"delete Slice::operator=(const Slice &) for mut slices\");\nstatic_assert(std::is_trivially_move_assignable<Slice<std::uint8_t>>::value,\n              \"trivial Slice::operator=(Slice &&)\");\nstatic_assert(std::is_trivially_destructible<Slice<std::uint8_t>>::value,\n              \"trivial ~Slice()\");\n\nstatic_assert(std::is_same<Vec<std::uint8_t>::const_iterator,\n                           Vec<const std::uint8_t>::iterator>::value,\n              \"Vec<T>::const_iterator == Vec<const T>::iterator\");\nstatic_assert(std::is_same<Vec<const std::uint8_t>::const_iterator,\n                           Vec<const std::uint8_t>::iterator>::value,\n              \"Vec<const T>::const_iterator == Vec<const T>::iterator\");\nstatic_assert(!std::is_same<Vec<std::uint8_t>::const_iterator,\n                            Vec<std::uint8_t>::iterator>::value,\n              \"Vec<T>::const_iterator != Vec<T>::iterator\");\n\nstatic const char *errorCopy(const char *ptr, std::size_t len) {\n  char *copy = new char[len + 1];\n  std::memcpy(copy, ptr, len);\n  copy[len] = '\\0';\n  return copy;\n}\n\nextern \"C\" {\nconst char *cxxbridge1$error(const char *ptr, std::size_t len) noexcept {\n  return errorCopy(ptr, len);\n}\n} // extern \"C\"\n\nError::Error(const Error &other)\n    : std::exception(other),\n      msg(other.msg ? errorCopy(other.msg, other.len) : nullptr),\n      len(other.len) {}\n\nError::Error(Error &&other) noexcept\n    : std::exception(std::move(other)), msg(other.msg), len(other.len) {\n  other.msg = nullptr;\n  other.len = 0;\n}\n\nError::~Error() noexcept { delete[] this->msg; }\n\nError &Error::operator=(const Error &other) & {\n  if (this != &other) {\n    std::exception::operator=(other);\n    delete[] this->msg;\n    this->msg = nullptr;\n    if (other.msg) {\n      this->msg = errorCopy(other.msg, other.len);\n      this->len = other.len;\n    }\n  }\n  return *this;\n}\n\nError &Error::operator=(Error &&other) & noexcept {\n  std::exception::operator=(std::move(other));\n  delete[] this->msg;\n  this->msg = other.msg;\n  this->len = other.len;\n  other.msg = nullptr;\n  other.len = 0;\n  return *this;\n}\n\nconst char *Error::what() const noexcept { return this->msg; }\n\nnamespace {\ntemplate <typename T>\nunion MaybeUninit {\n  T value;\n  MaybeUninit() {}\n  ~MaybeUninit() {}\n};\n} // namespace\n\nnamespace repr {\nstruct PtrLen final {\n  void *ptr;\n  std::size_t len;\n};\n} // namespace repr\n\nextern \"C\" {\nrepr::PtrLen cxxbridge1$exception(const char *, std::size_t len) noexcept;\n}\n\nnamespace detail {\n// On some platforms size_t is the same C++ type as one of the sized integer\n// types; on others it is a distinct type. Only in the latter case do we need to\n// define a specialized impl of rust::Vec<size_t>, because in the former case it\n// would collide with one of the other specializations.\nusing usize_if_unique =\n    typename std::conditional<std::is_same<size_t, uint64_t>::value ||\n                                  std::is_same<size_t, uint32_t>::value,\n                              struct usize_ignore, size_t>::type;\nusing isize_if_unique =\n    typename std::conditional<std::is_same<rust::isize, int64_t>::value ||\n                                  std::is_same<rust::isize, int32_t>::value,\n                              struct isize_ignore, rust::isize>::type;\n// Similarly, on some platforms char may just be an alias for [u]int8_t.\nusing char_if_unique =\n    typename std::conditional<std::is_same<char, uint8_t>::value ||\n                                  std::is_same<char, int8_t>::value,\n                              struct char_ignore, char>::type;\n\nclass Fail final {\n  repr::PtrLen &throw$;\n\npublic:\n  Fail(repr::PtrLen &throw$) noexcept : throw$(throw$) {}\n  void operator()(const char *) noexcept;\n  void operator()(const std::string &) noexcept;\n};\n\nvoid Fail::operator()(const char *catch$) noexcept {\n  throw$ = cxxbridge1$exception(catch$, std::strlen(catch$));\n}\n\nvoid Fail::operator()(const std::string &catch$) noexcept {\n  throw$ = cxxbridge1$exception(catch$.data(), catch$.length());\n}\n} // namespace detail\n\n} // namespace cxxbridge1\n} // namespace rust\n\nnamespace {\ntemplate <typename T>\nvoid destroy(T *ptr) {\n  ptr->~T();\n}\n} // namespace\n\nextern \"C\" {\nvoid cxxbridge1$unique_ptr$std$string$null(\n    std::unique_ptr<std::string> *ptr) noexcept {\n  new (ptr) std::unique_ptr<std::string>();\n}\nvoid cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr<std::string> *ptr,\n                                          std::string *raw) noexcept {\n  new (ptr) std::unique_ptr<std::string>(raw);\n}\nconst std::string *cxxbridge1$unique_ptr$std$string$get(\n    const std::unique_ptr<std::string> &ptr) noexcept {\n  return ptr.get();\n}\nstd::string *cxxbridge1$unique_ptr$std$string$release(\n    std::unique_ptr<std::string> &ptr) noexcept {\n  return ptr.release();\n}\nvoid cxxbridge1$unique_ptr$std$string$drop(\n    std::unique_ptr<std::string> *ptr) noexcept {\n  ptr->~unique_ptr();\n}\n} // extern \"C\"\n\nnamespace {\nconst std::size_t kMaxExpectedWordsInString = 8;\nstatic_assert(alignof(std::string) <= alignof(void *),\n              \"unexpectedly large std::string alignment\");\nstatic_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *),\n              \"unexpectedly large std::string size\");\n} // namespace\n\n#define STD_VECTOR_OPS(RUST_TYPE, CXX_TYPE)                                    \\\n  std::vector<CXX_TYPE> *cxxbridge1$std$vector$##RUST_TYPE##$new() noexcept {  \\\n    return new std::vector<CXX_TYPE>();                                        \\\n  }                                                                            \\\n  std::size_t cxxbridge1$std$vector$##RUST_TYPE##$size(                        \\\n      const std::vector<CXX_TYPE> &s) noexcept {                               \\\n    return s.size();                                                           \\\n  }                                                                            \\\n  std::size_t cxxbridge1$std$vector$##RUST_TYPE##$capacity(                    \\\n      const std::vector<CXX_TYPE> &s) noexcept {                               \\\n    return s.capacity();                                                       \\\n  }                                                                            \\\n  CXX_TYPE *cxxbridge1$std$vector$##RUST_TYPE##$get_unchecked(                 \\\n      std::vector<CXX_TYPE> *s, std::size_t pos) noexcept {                    \\\n    return &(*s)[pos];                                                         \\\n  }                                                                            \\\n  void cxxbridge1$std$vector$##RUST_TYPE##$reserve(                            \\\n      std::vector<CXX_TYPE> *s, std::size_t new_cap) noexcept {                \\\n    s->reserve(new_cap);                                                       \\\n  }                                                                            \\\n  void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$null(                    \\\n      std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept {                  \\\n    new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>();                        \\\n  }                                                                            \\\n  void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$raw(                     \\\n      std::unique_ptr<std::vector<CXX_TYPE>> *ptr,                             \\\n      std::vector<CXX_TYPE> *raw) noexcept {                                   \\\n    new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(raw);                     \\\n  }                                                                            \\\n  const std::vector<CXX_TYPE>                                                  \\\n      *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$get(                     \\\n          const std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept {        \\\n    return ptr.get();                                                          \\\n  }                                                                            \\\n  std::vector<CXX_TYPE>                                                        \\\n      *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$release(                 \\\n          std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept {              \\\n    return ptr.release();                                                      \\\n  }                                                                            \\\n  void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$drop(                    \\\n      std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept {                  \\\n    ptr->~unique_ptr();                                                        \\\n  }\n\n#define STD_VECTOR_TRIVIAL_OPS(RUST_TYPE, CXX_TYPE)                            \\\n  void cxxbridge1$std$vector$##RUST_TYPE##$push_back(                          \\\n      std::vector<CXX_TYPE> *v, CXX_TYPE *value) noexcept {                    \\\n    v->push_back(std::move(*value));                                           \\\n    destroy(value);                                                            \\\n  }                                                                            \\\n  void cxxbridge1$std$vector$##RUST_TYPE##$pop_back(std::vector<CXX_TYPE> *v,  \\\n                                                    CXX_TYPE *out) noexcept {  \\\n    new (out) CXX_TYPE(std::move(v->back()));                                  \\\n    v->pop_back();                                                             \\\n  }\n\n#define RUST_VEC_EXTERNS(RUST_TYPE, CXX_TYPE)                                  \\\n  void cxxbridge1$rust_vec$##RUST_TYPE##$new(                                  \\\n      rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \\\n  void cxxbridge1$rust_vec$##RUST_TYPE##$drop(                                 \\\n      rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \\\n  std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$len(                           \\\n      const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \\\n  std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$capacity(                      \\\n      const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \\\n  const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data(                      \\\n      const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \\\n  void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(                        \\\n      rust::Vec<CXX_TYPE> *ptr, std::size_t new_cap) noexcept;                 \\\n  void cxxbridge1$rust_vec$##RUST_TYPE##$set_len(rust::Vec<CXX_TYPE> *ptr,     \\\n                                                 std::size_t len) noexcept;    \\\n  void cxxbridge1$rust_vec$##RUST_TYPE##$truncate(rust::Vec<CXX_TYPE> *ptr,    \\\n                                                  std::size_t len) noexcept;\n\n#define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE)                                      \\\n  template <>                                                                  \\\n  Vec<CXX_TYPE>::Vec() noexcept {                                              \\\n    cxxbridge1$rust_vec$##RUST_TYPE##$new(this);                               \\\n  }                                                                            \\\n  template <>                                                                  \\\n  void Vec<CXX_TYPE>::drop() noexcept {                                        \\\n    return cxxbridge1$rust_vec$##RUST_TYPE##$drop(this);                       \\\n  }                                                                            \\\n  template <>                                                                  \\\n  std::size_t Vec<CXX_TYPE>::size() const noexcept {                           \\\n    return cxxbridge1$rust_vec$##RUST_TYPE##$len(this);                        \\\n  }                                                                            \\\n  template <>                                                                  \\\n  std::size_t Vec<CXX_TYPE>::capacity() const noexcept {                       \\\n    return cxxbridge1$rust_vec$##RUST_TYPE##$capacity(this);                   \\\n  }                                                                            \\\n  template <>                                                                  \\\n  const CXX_TYPE *Vec<CXX_TYPE>::data() const noexcept {                       \\\n    return cxxbridge1$rust_vec$##RUST_TYPE##$data(this);                       \\\n  }                                                                            \\\n  template <>                                                                  \\\n  void Vec<CXX_TYPE>::reserve_total(std::size_t new_cap) noexcept {            \\\n    cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(this, new_cap);            \\\n  }                                                                            \\\n  template <>                                                                  \\\n  void Vec<CXX_TYPE>::set_len(std::size_t len) noexcept {                      \\\n    cxxbridge1$rust_vec$##RUST_TYPE##$set_len(this, len);                      \\\n  }                                                                            \\\n  template <>                                                                  \\\n  void Vec<CXX_TYPE>::truncate(std::size_t len) {                              \\\n    cxxbridge1$rust_vec$##RUST_TYPE##$truncate(this, len);                     \\\n  }\n\n#define SHARED_PTR_OPS(RUST_TYPE, CXX_TYPE)                                    \\\n  static_assert(sizeof(std::shared_ptr<CXX_TYPE>) == 2 * sizeof(void *), \"\");  \\\n  static_assert(alignof(std::shared_ptr<CXX_TYPE>) == alignof(void *), \"\");    \\\n  void cxxbridge1$std$shared_ptr$##RUST_TYPE##$null(                           \\\n      std::shared_ptr<CXX_TYPE> *ptr) noexcept {                               \\\n    new (ptr) std::shared_ptr<CXX_TYPE>();                                     \\\n  }                                                                            \\\n  void cxxbridge1$std$shared_ptr$##RUST_TYPE##$raw(                            \\\n      std::shared_ptr<CXX_TYPE> *ptr, CXX_TYPE *raw) noexcept {                \\\n    new (ptr) std::shared_ptr<CXX_TYPE>(raw);                                  \\\n  }                                                                            \\\n  CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$uninit(                    \\\n      std::shared_ptr<CXX_TYPE> *ptr) noexcept {                               \\\n    CXX_TYPE *uninit =                                                         \\\n        reinterpret_cast<CXX_TYPE *>(new rust::MaybeUninit<CXX_TYPE>);         \\\n    new (ptr) std::shared_ptr<CXX_TYPE>(uninit);                               \\\n    return uninit;                                                             \\\n  }                                                                            \\\n  void cxxbridge1$std$shared_ptr$##RUST_TYPE##$clone(                          \\\n      const std::shared_ptr<CXX_TYPE> &self,                                   \\\n      std::shared_ptr<CXX_TYPE> *ptr) noexcept {                               \\\n    new (ptr) std::shared_ptr<CXX_TYPE>(self);                                 \\\n  }                                                                            \\\n  const CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$get(                 \\\n      const std::shared_ptr<CXX_TYPE> &self) noexcept {                        \\\n    return self.get();                                                         \\\n  }                                                                            \\\n  void cxxbridge1$std$shared_ptr$##RUST_TYPE##$drop(                           \\\n      const std::shared_ptr<CXX_TYPE> *self) noexcept {                        \\\n    self->~shared_ptr();                                                       \\\n  }                                                                            \\\n  static_assert(sizeof(std::weak_ptr<CXX_TYPE>) == 2 * sizeof(void *), \"\");    \\\n  static_assert(alignof(std::weak_ptr<CXX_TYPE>) == alignof(void *), \"\");      \\\n  void cxxbridge1$std$weak_ptr$##RUST_TYPE##$null(                             \\\n      std::weak_ptr<CXX_TYPE> *ptr) noexcept {                                 \\\n    new (ptr) std::weak_ptr<CXX_TYPE>();                                       \\\n  }                                                                            \\\n  void cxxbridge1$std$weak_ptr$##RUST_TYPE##$clone(                            \\\n      const std::weak_ptr<CXX_TYPE> &self,                                     \\\n      std::weak_ptr<CXX_TYPE> *ptr) noexcept {                                 \\\n    new (ptr) std::weak_ptr<CXX_TYPE>(self);                                   \\\n  }                                                                            \\\n  void cxxbridge1$std$weak_ptr$##RUST_TYPE##$downgrade(                        \\\n      const std::shared_ptr<CXX_TYPE> &shared,                                 \\\n      std::weak_ptr<CXX_TYPE> *weak) noexcept {                                \\\n    new (weak) std::weak_ptr<CXX_TYPE>(shared);                                \\\n  }                                                                            \\\n  void cxxbridge1$std$weak_ptr$##RUST_TYPE##$upgrade(                          \\\n      const std::weak_ptr<CXX_TYPE> &weak,                                     \\\n      std::shared_ptr<CXX_TYPE> *shared) noexcept {                            \\\n    new (shared) std::shared_ptr<CXX_TYPE>(weak.lock());                       \\\n  }                                                                            \\\n  void cxxbridge1$std$weak_ptr$##RUST_TYPE##$drop(                             \\\n      const std::weak_ptr<CXX_TYPE> *self) noexcept {                          \\\n    self->~weak_ptr();                                                         \\\n  }\n\n// Usize and isize are the same type as one of the below.\n#define FOR_EACH_NUMERIC(MACRO)                                                \\\n  MACRO(u8, std::uint8_t)                                                      \\\n  MACRO(u16, std::uint16_t)                                                    \\\n  MACRO(u32, std::uint32_t)                                                    \\\n  MACRO(u64, std::uint64_t)                                                    \\\n  MACRO(i8, std::int8_t)                                                       \\\n  MACRO(i16, std::int16_t)                                                     \\\n  MACRO(i32, std::int32_t)                                                     \\\n  MACRO(i64, std::int64_t)                                                     \\\n  MACRO(f32, float)                                                            \\\n  MACRO(f64, double)\n\n#define FOR_EACH_TRIVIAL_STD_VECTOR(MACRO)                                     \\\n  FOR_EACH_NUMERIC(MACRO)                                                      \\\n  MACRO(usize, std::size_t)                                                    \\\n  MACRO(isize, rust::isize)\n\n#define FOR_EACH_STD_VECTOR(MACRO)                                             \\\n  FOR_EACH_TRIVIAL_STD_VECTOR(MACRO)                                           \\\n  MACRO(string, std::string)\n\n#define FOR_EACH_RUST_VEC(MACRO)                                               \\\n  FOR_EACH_NUMERIC(MACRO)                                                      \\\n  MACRO(bool, bool)                                                            \\\n  MACRO(char, rust::detail::char_if_unique)                                    \\\n  MACRO(usize, rust::detail::usize_if_unique)                                  \\\n  MACRO(isize, rust::detail::isize_if_unique)                                  \\\n  MACRO(string, rust::String)                                                  \\\n  MACRO(str, rust::Str)\n\n#define FOR_EACH_SHARED_PTR(MACRO)                                             \\\n  FOR_EACH_NUMERIC(MACRO)                                                      \\\n  MACRO(bool, bool)                                                            \\\n  MACRO(usize, std::size_t)                                                    \\\n  MACRO(isize, rust::isize)                                                    \\\n  MACRO(string, std::string)\n\nextern \"C\" {\nFOR_EACH_STD_VECTOR(STD_VECTOR_OPS)\nFOR_EACH_TRIVIAL_STD_VECTOR(STD_VECTOR_TRIVIAL_OPS)\nFOR_EACH_RUST_VEC(RUST_VEC_EXTERNS)\nFOR_EACH_SHARED_PTR(SHARED_PTR_OPS)\n} // extern \"C\"\n\nnamespace rust {\ninline namespace cxxbridge1 {\nFOR_EACH_RUST_VEC(RUST_VEC_OPS)\n} // namespace cxxbridge1\n} // namespace rust\n"
  },
  {
    "path": "src/cxx_string.rs",
    "content": "use crate::actually_private::Private;\nuse crate::lossy;\n#[cfg(feature = \"alloc\")]\nuse alloc::borrow::Cow;\n#[cfg(feature = \"alloc\")]\nuse alloc::string::String;\nuse core::cmp::Ordering;\nuse core::ffi::{c_char, CStr};\nuse core::fmt::{self, Debug, Display};\nuse core::hash::{Hash, Hasher};\nuse core::marker::{PhantomData, PhantomPinned};\nuse core::mem::MaybeUninit;\nuse core::pin::Pin;\nuse core::slice;\nuse core::str::{self, Utf8Error};\n\nextern \"C\" {\n    #[link_name = \"cxxbridge1$cxx_string$init\"]\n    fn string_init(this: &mut MaybeUninit<CxxString>, ptr: *const u8, len: usize);\n    #[link_name = \"cxxbridge1$cxx_string$destroy\"]\n    fn string_destroy(this: &mut MaybeUninit<CxxString>);\n    #[link_name = \"cxxbridge1$cxx_string$data\"]\n    fn string_data(this: &CxxString) -> *const u8;\n    #[link_name = \"cxxbridge1$cxx_string$length\"]\n    fn string_length(this: &CxxString) -> usize;\n    #[link_name = \"cxxbridge1$cxx_string$clear\"]\n    fn string_clear(this: Pin<&mut CxxString>);\n    #[link_name = \"cxxbridge1$cxx_string$reserve_total\"]\n    fn string_reserve_total(this: Pin<&mut CxxString>, new_cap: usize);\n    #[link_name = \"cxxbridge1$cxx_string$push\"]\n    fn string_push(this: Pin<&mut CxxString>, ptr: *const u8, len: usize);\n}\n\n/// Binding to C++ `std::string`.\n///\n/// # Invariants\n///\n/// As an invariant of this API and the static analysis of the cxx::bridge\n/// macro, in Rust code we can never obtain a `CxxString` by value. C++'s string\n/// requires a move constructor and may hold internal pointers, which is not\n/// compatible with Rust's move behavior. Instead in Rust code we will only ever\n/// look at a CxxString through a reference or smart pointer, as in `&CxxString`\n/// or `UniquePtr<CxxString>`.\n#[repr(C)]\npub struct CxxString {\n    _private: [u8; 0],\n    _pinned: PhantomData<PhantomPinned>,\n}\n\n/// Construct a C++ std::string on the Rust stack.\n///\n/// # Syntax\n///\n/// In statement position:\n///\n/// ```\n/// # use cxx::let_cxx_string;\n/// # let expression = \"\";\n/// let_cxx_string!(var = expression);\n/// ```\n///\n/// The `expression` may have any type that implements `AsRef<[u8]>`. Commonly\n/// it will be a string literal, but for example `&[u8]` and `String` would work\n/// as well.\n///\n/// The macro expands to something resembling `let $var: Pin<&mut CxxString> =\n/// /*???*/;`. The resulting [`Pin`] can be deref'd to `&CxxString` as needed.\n///\n/// # Example\n///\n/// ```\n/// use cxx::{let_cxx_string, CxxString};\n///\n/// fn f(s: &CxxString) {/* ... */}\n///\n/// fn main() {\n///     let_cxx_string!(s = \"example\");\n///     f(&s);\n/// }\n/// ```\n#[macro_export]\nmacro_rules! let_cxx_string {\n    ($var:ident = $value:expr $(,)?) => {\n        let mut cxx_stack_string = $crate::private::StackString::new();\n        #[allow(unused_mut, unused_unsafe)]\n        let mut $var = match $value {\n            let_cxx_string => unsafe { cxx_stack_string.init(let_cxx_string) },\n        };\n    };\n}\n\nimpl CxxString {\n    /// `CxxString` is not constructible via `new`. Instead, use the\n    /// [`let_cxx_string!`] macro.\n    pub fn new<T: Private>() -> Self {\n        unreachable!()\n    }\n\n    /// Returns the length of the string in bytes.\n    ///\n    /// Matches the behavior of C++ [std::string::size][size].\n    ///\n    /// [size]: https://en.cppreference.com/w/cpp/string/basic_string/size\n    pub fn len(&self) -> usize {\n        unsafe { string_length(self) }\n    }\n\n    /// Returns true if `self` has a length of zero bytes.\n    ///\n    /// Matches the behavior of C++ [std::string::empty][empty].\n    ///\n    /// [empty]: https://en.cppreference.com/w/cpp/string/basic_string/empty\n    pub fn is_empty(&self) -> bool {\n        self.len() == 0\n    }\n\n    /// Returns a byte slice of this string's contents.\n    pub fn as_bytes(&self) -> &[u8] {\n        let data = self.as_ptr();\n        let len = self.len();\n        unsafe { slice::from_raw_parts(data, len) }\n    }\n\n    /// Produces a pointer to the first character of the string.\n    ///\n    /// Matches the behavior of C++ [std::string::data][data].\n    ///\n    /// Note that the return type may look like `const char *` but is not a\n    /// `const char *` in the typical C sense, as C++ strings may contain\n    /// internal null bytes. As such, the returned pointer only makes sense as a\n    /// string in combination with the length returned by [`len()`][len].\n    ///\n    /// Modifying the string data through this pointer has undefined behavior.\n    ///\n    /// [data]: https://en.cppreference.com/w/cpp/string/basic_string/data\n    /// [len]: #method.len\n    pub fn as_ptr(&self) -> *const u8 {\n        unsafe { string_data(self) }\n    }\n\n    /// Produces a nul-terminated string view of this string's contents.\n    ///\n    /// Matches the behavior of C++ [std::string::c_str][c_str].\n    ///\n    /// If this string contains no internal '\\0' bytes, then\n    /// `self.as_c_str().count_bytes() == self.len()`. But if it does, the CStr\n    /// only refers to the part of the string up to the first nul byte.\n    ///\n    /// [c_str]: https://en.cppreference.com/w/cpp/string/basic_string/c_str\n    pub fn as_c_str(&self) -> &CStr {\n        // Since C++11, string[string.size()] is guaranteed to be \\0.\n        unsafe { CStr::from_ptr(self.as_ptr().cast::<c_char>()) }\n    }\n\n    /// Validates that the C++ string contains UTF-8 data and produces a view of\n    /// it as a Rust &amp;str, otherwise an error.\n    pub fn to_str(&self) -> Result<&str, Utf8Error> {\n        str::from_utf8(self.as_bytes())\n    }\n\n    /// If the contents of the C++ string are valid UTF-8, this function returns\n    /// a view as a Cow::Borrowed &amp;str. Otherwise replaces any invalid UTF-8\n    /// sequences with the U+FFFD [replacement character] and returns a\n    /// Cow::Owned String.\n    ///\n    /// [replacement character]: char::REPLACEMENT_CHARACTER\n    #[cfg(feature = \"alloc\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"alloc\")))]\n    pub fn to_string_lossy(&self) -> Cow<str> {\n        String::from_utf8_lossy(self.as_bytes())\n    }\n\n    /// Removes all characters from the string.\n    ///\n    /// Matches the behavior of C++ [std::string::clear][clear].\n    ///\n    /// Note: **unlike** the guarantee of Rust's `std::string::String::clear`,\n    /// the C++ standard does not require that capacity is unchanged by this\n    /// operation. In practice existing implementations do not change the\n    /// capacity but all pointers, references, and iterators into the string\n    /// contents are nevertheless invalidated.\n    ///\n    /// [clear]: https://en.cppreference.com/w/cpp/string/basic_string/clear\n    pub fn clear(self: Pin<&mut Self>) {\n        unsafe { string_clear(self) }\n    }\n\n    /// Ensures that this string's capacity is at least `additional` bytes\n    /// larger than its length.\n    ///\n    /// The capacity may be increased by more than `additional` bytes if the\n    /// implementation chooses, to amortize the cost of frequent reallocations.\n    ///\n    /// **The meaning of the argument is not the same as\n    /// [std::string::reserve][reserve] in C++.** The C++ standard library and\n    /// Rust standard library both have a `reserve` method on strings, but in\n    /// C++ code the argument always refers to total capacity, whereas in Rust\n    /// code it always refers to additional capacity. This API on `CxxString`\n    /// follows the Rust convention, the same way that for the length accessor\n    /// we use the Rust conventional `len()` naming and not C++ `size()` or\n    /// `length()`.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the new capacity overflows usize.\n    ///\n    /// [reserve]: https://en.cppreference.com/w/cpp/string/basic_string/reserve\n    pub fn reserve(self: Pin<&mut Self>, additional: usize) {\n        let new_cap = self\n            .len()\n            .checked_add(additional)\n            .expect(\"CxxString capacity overflow\");\n        unsafe { string_reserve_total(self, new_cap) }\n    }\n\n    /// Appends a given string slice onto the end of this C++ string.\n    pub fn push_str(self: Pin<&mut Self>, s: &str) {\n        self.push_bytes(s.as_bytes());\n    }\n\n    /// Appends arbitrary bytes onto the end of this C++ string.\n    pub fn push_bytes(self: Pin<&mut Self>, bytes: &[u8]) {\n        unsafe { string_push(self, bytes.as_ptr(), bytes.len()) }\n    }\n}\n\nimpl Display for CxxString {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        lossy::display(self.as_bytes(), f)\n    }\n}\n\nimpl Debug for CxxString {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        lossy::debug(self.as_bytes(), f)\n    }\n}\n\nimpl PartialEq for CxxString {\n    fn eq(&self, other: &Self) -> bool {\n        self.as_bytes() == other.as_bytes()\n    }\n}\n\nimpl PartialEq<CxxString> for str {\n    fn eq(&self, other: &CxxString) -> bool {\n        self.as_bytes() == other.as_bytes()\n    }\n}\n\nimpl PartialEq<str> for CxxString {\n    fn eq(&self, other: &str) -> bool {\n        self.as_bytes() == other.as_bytes()\n    }\n}\n\nimpl Eq for CxxString {}\n\nimpl PartialOrd for CxxString {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(self.cmp(other))\n    }\n}\n\nimpl Ord for CxxString {\n    fn cmp(&self, other: &Self) -> Ordering {\n        self.as_bytes().cmp(other.as_bytes())\n    }\n}\n\nimpl Hash for CxxString {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        self.as_bytes().hash(state);\n    }\n}\n\nimpl fmt::Write for Pin<&mut CxxString> {\n    fn write_str(&mut self, s: &str) -> fmt::Result {\n        self.as_mut().push_str(s);\n        Ok(())\n    }\n}\n\n#[cfg(feature = \"std\")]\nimpl std::io::Write for Pin<&mut CxxString> {\n    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {\n        self.as_mut().push_bytes(buf);\n        Ok(buf.len())\n    }\n\n    fn flush(&mut self) -> std::io::Result<()> {\n        Ok(())\n    }\n}\n\n#[doc(hidden)]\n#[repr(C)]\npub struct StackString {\n    // Static assertions in cxx.cc validate that this is large enough and\n    // aligned enough.\n    space: MaybeUninit<[usize; 8]>,\n}\n\nimpl StackString {\n    pub fn new() -> Self {\n        StackString {\n            space: MaybeUninit::uninit(),\n        }\n    }\n\n    pub unsafe fn init(&mut self, value: impl AsRef<[u8]>) -> Pin<&mut CxxString> {\n        let value = value.as_ref();\n        unsafe {\n            let this = &mut *self.space.as_mut_ptr().cast::<MaybeUninit<CxxString>>();\n            string_init(this, value.as_ptr(), value.len());\n            Pin::new_unchecked(&mut *this.as_mut_ptr())\n        }\n    }\n}\n\nimpl Drop for StackString {\n    fn drop(&mut self) {\n        unsafe {\n            let this = &mut *self.space.as_mut_ptr().cast::<MaybeUninit<CxxString>>();\n            string_destroy(this);\n        }\n    }\n}\n"
  },
  {
    "path": "src/cxx_vector.rs",
    "content": "//! Less used details of `CxxVector` are exposed in this module. `CxxVector`\n//! itself is exposed at the crate root.\n\nuse crate::extern_type::ExternType;\nuse crate::kind::Trivial;\nuse crate::string::CxxString;\nuse crate::unique_ptr::UniquePtr;\nuse core::ffi::c_void;\nuse core::fmt::{self, Debug};\nuse core::iter::FusedIterator;\nuse core::marker::{PhantomData, PhantomPinned};\nuse core::mem::{self, ManuallyDrop, MaybeUninit};\nuse core::pin::Pin;\nuse core::ptr;\nuse core::slice;\n\n/// Binding to C++ `std::vector<T, std::allocator<T>>`.\n///\n/// # Invariants\n///\n/// As an invariant of this API and the static analysis of the cxx::bridge\n/// macro, in Rust code we can never obtain a `CxxVector` by value. Instead in\n/// Rust code we will only ever look at a vector behind a reference or smart\n/// pointer, as in `&CxxVector<T>` or `UniquePtr<CxxVector<T>>`.\n#[repr(C, packed)]\npub struct CxxVector<T> {\n    // A thing, because repr(C) structs are not allowed to consist exclusively\n    // of PhantomData fields.\n    _void: [c_void; 0],\n    // The conceptual vector elements to ensure that autotraits are propagated\n    // correctly, e.g. CxxVector is UnwindSafe iff T is.\n    _elements: PhantomData<[T]>,\n    // Prevent unpin operation from Pin<&mut CxxVector<T>> to &mut CxxVector<T>.\n    _pinned: PhantomData<PhantomPinned>,\n}\n\nimpl<T> CxxVector<T>\nwhere\n    T: VectorElement,\n{\n    /// Constructs a new heap allocated vector, wrapped by UniquePtr.\n    ///\n    /// The C++ vector is default constructed.\n    pub fn new() -> UniquePtr<Self> {\n        unsafe { UniquePtr::from_raw(T::__vector_new()) }\n    }\n\n    /// Returns the number of elements in the vector.\n    ///\n    /// Matches the behavior of C++ [std::vector\\<T\\>::size][size].\n    ///\n    /// [size]: https://en.cppreference.com/w/cpp/container/vector/size\n    pub fn len(&self) -> usize {\n        T::__vector_size(self)\n    }\n\n    /// Returns the capacity of the vector.\n    ///\n    /// Matches the behavior of C++ [std::vector\\<T\\>::capacity][capacity].\n    ///\n    /// [capacity]: https://en.cppreference.com/w/cpp/container/vector/capacity\n    pub fn capacity(&self) -> usize {\n        T::__vector_capacity(self)\n    }\n\n    /// Returns true if the vector contains no elements.\n    ///\n    /// Matches the behavior of C++ [std::vector\\<T\\>::empty][empty].\n    ///\n    /// [empty]: https://en.cppreference.com/w/cpp/container/vector/empty\n    pub fn is_empty(&self) -> bool {\n        self.len() == 0\n    }\n\n    /// Returns a reference to an element at the given position, or `None` if\n    /// out of bounds.\n    pub fn get(&self, pos: usize) -> Option<&T> {\n        if pos < self.len() {\n            Some(unsafe { self.get_unchecked(pos) })\n        } else {\n            None\n        }\n    }\n\n    /// Returns a pinned mutable reference to an element at the given position,\n    /// or `None` if out of bounds.\n    ///\n    /// This method cannot be named \"get\\_mut\" due to a conflict with\n    /// `Pin::get_mut`.\n    #[doc(alias = \"get_mut\")]\n    pub fn index_mut(self: Pin<&mut Self>, pos: usize) -> Option<Pin<&mut T>> {\n        if pos < self.len() {\n            Some(unsafe { self.index_unchecked_mut(pos) })\n        } else {\n            None\n        }\n    }\n\n    /// Returns a reference to an element without doing bounds checking.\n    ///\n    /// This is generally not recommended, use with caution! Calling this method\n    /// with an out-of-bounds index is undefined behavior even if the resulting\n    /// reference is not used.\n    ///\n    /// Matches the behavior of C++\n    /// [std::vector\\<T\\>::operator\\[\\] const][operator_at].\n    ///\n    /// [operator_at]: https://en.cppreference.com/w/cpp/container/vector/operator_at\n    pub unsafe fn get_unchecked(&self, pos: usize) -> &T {\n        let this = ptr::from_ref::<CxxVector<T>>(self).cast_mut();\n        unsafe {\n            let ptr = T::__get_unchecked(this, pos).cast_const();\n            &*ptr\n        }\n    }\n\n    /// Returns a pinned mutable reference to an element without doing bounds\n    /// checking.\n    ///\n    /// This is generally not recommended, use with caution! Calling this method\n    /// with an out-of-bounds index is undefined behavior even if the resulting\n    /// reference is not used.\n    ///\n    /// Matches the behavior of C++\n    /// [std::vector\\<T\\>::operator\\[\\]][operator_at].\n    ///\n    /// [operator_at]: https://en.cppreference.com/w/cpp/container/vector/operator_at\n    ///\n    /// This method cannot be named \"get\\_unchecked\\_mut\" due to a conflict with\n    /// `Pin::get_unchecked_mut`.\n    #[doc(alias = \"get_unchecked_mut\")]\n    pub unsafe fn index_unchecked_mut(self: Pin<&mut Self>, pos: usize) -> Pin<&mut T> {\n        unsafe {\n            let ptr = T::__get_unchecked(self.get_unchecked_mut(), pos);\n            Pin::new_unchecked(&mut *ptr)\n        }\n    }\n\n    /// Returns a slice to the underlying contiguous array of elements.\n    pub fn as_slice(&self) -> &[T]\n    where\n        T: ExternType<Kind = Trivial>,\n    {\n        let len = self.len();\n        if len == 0 {\n            // The slice::from_raw_parts in the other branch requires a nonnull\n            // and properly aligned data ptr. C++ standard does not guarantee\n            // that data() on a vector with size 0 would return a nonnull\n            // pointer or sufficiently aligned pointer, so using it would be\n            // undefined behavior. Create our own empty slice in Rust instead\n            // which upholds the invariants.\n            &[]\n        } else {\n            let this = ptr::from_ref::<CxxVector<T>>(self).cast_mut();\n            let ptr = unsafe { T::__get_unchecked(this, 0) };\n            unsafe { slice::from_raw_parts(ptr, len) }\n        }\n    }\n\n    /// Returns a slice to the underlying contiguous array of elements by\n    /// mutable reference.\n    pub fn as_mut_slice(self: Pin<&mut Self>) -> &mut [T]\n    where\n        T: ExternType<Kind = Trivial>,\n    {\n        let len = self.len();\n        if len == 0 {\n            &mut []\n        } else {\n            let ptr = unsafe { T::__get_unchecked(self.get_unchecked_mut(), 0) };\n            unsafe { slice::from_raw_parts_mut(ptr, len) }\n        }\n    }\n\n    /// Returns an iterator over elements of type `&T`.\n    pub fn iter(&self) -> Iter<T> {\n        Iter { v: self, index: 0 }\n    }\n\n    /// Returns an iterator over elements of type `Pin<&mut T>`.\n    pub fn iter_mut(self: Pin<&mut Self>) -> IterMut<T> {\n        IterMut { v: self, index: 0 }\n    }\n\n    /// Appends an element to the back of the vector.\n    ///\n    /// Matches the behavior of C++ [std::vector\\<T\\>::push_back][push_back].\n    ///\n    /// [push_back]: https://en.cppreference.com/w/cpp/container/vector/push_back\n    pub fn push(self: Pin<&mut Self>, value: T)\n    where\n        T: ExternType<Kind = Trivial>,\n    {\n        let mut value = ManuallyDrop::new(value);\n        unsafe {\n            // C++ calls move constructor followed by destructor on `value`.\n            T::__push_back(self, &mut value);\n        }\n    }\n\n    /// Removes the last element from a vector and returns it, or `None` if the\n    /// vector is empty.\n    pub fn pop(self: Pin<&mut Self>) -> Option<T>\n    where\n        T: ExternType<Kind = Trivial>,\n    {\n        if self.is_empty() {\n            None\n        } else {\n            let mut value = MaybeUninit::uninit();\n            Some(unsafe {\n                T::__pop_back(self, &mut value);\n                value.assume_init()\n            })\n        }\n    }\n\n    /// Ensures that this vector's capacity is at least `additional` elements\n    /// larger than its length.\n    ///\n    /// The capacity may be increased by more than `additional` elements if the\n    /// implementation chooses, to amortize the cost of frequent reallocations.\n    ///\n    /// **The meaning of the argument is not the same as\n    /// [std::vector\\<T\\>::reserve][reserve] in C++.** The C++ standard library\n    /// and Rust standard library both have a `reserve` method on vectors, but\n    /// in C++ code the argument always refers to total capacity, whereas in\n    /// Rust code it always refers to additional capacity. This API on\n    /// `CxxVector` follows the Rust convention, the same way that for the\n    /// length accessor we use the Rust conventional `len()` naming and not C++\n    /// `size()`.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the new capacity overflows usize, or if `T` is not\n    /// move-constructible in C++.\n    ///\n    /// [reserve]: https://en.cppreference.com/w/cpp/container/vector/reserve.html\n    pub fn reserve(self: Pin<&mut Self>, additional: usize) {\n        let new_cap = self\n            .len()\n            .checked_add(additional)\n            .expect(\"CxxVector capacity overflow\");\n        unsafe { T::__reserve(self, new_cap) }\n    }\n}\n\nimpl<T> Extend<T> for Pin<&mut CxxVector<T>>\nwhere\n    T: ExternType<Kind = Trivial> + VectorElement,\n{\n    fn extend<I>(&mut self, iter: I)\n    where\n        I: IntoIterator<Item = T>,\n    {\n        let iter = iter.into_iter();\n        self.as_mut().reserve(iter.size_hint().0);\n        for element in iter {\n            self.as_mut().push(element);\n        }\n    }\n}\n\n/// Iterator over elements of a `CxxVector` by shared reference.\n///\n/// The iterator element type is `&'a T`.\npub struct Iter<'a, T> {\n    v: &'a CxxVector<T>,\n    index: usize,\n}\n\nimpl<'a, T> IntoIterator for &'a CxxVector<T>\nwhere\n    T: VectorElement,\n{\n    type Item = &'a T;\n    type IntoIter = Iter<'a, T>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        self.iter()\n    }\n}\n\nimpl<'a, T> Iterator for Iter<'a, T>\nwhere\n    T: VectorElement,\n{\n    type Item = &'a T;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let next = self.v.get(self.index)?;\n        self.index += 1;\n        Some(next)\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        let len = self.len();\n        (len, Some(len))\n    }\n}\n\nimpl<'a, T> ExactSizeIterator for Iter<'a, T>\nwhere\n    T: VectorElement,\n{\n    fn len(&self) -> usize {\n        self.v.len() - self.index\n    }\n}\n\nimpl<'a, T> FusedIterator for Iter<'a, T> where T: VectorElement {}\n\n/// Iterator over elements of a `CxxVector` by pinned mutable reference.\n///\n/// The iterator element type is `Pin<&'a mut T>`.\npub struct IterMut<'a, T> {\n    v: Pin<&'a mut CxxVector<T>>,\n    index: usize,\n}\n\nimpl<'a, T> IntoIterator for Pin<&'a mut CxxVector<T>>\nwhere\n    T: VectorElement,\n{\n    type Item = Pin<&'a mut T>;\n    type IntoIter = IterMut<'a, T>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        self.iter_mut()\n    }\n}\n\nimpl<'a, T> Iterator for IterMut<'a, T>\nwhere\n    T: VectorElement,\n{\n    type Item = Pin<&'a mut T>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let next = self.v.as_mut().index_mut(self.index)?;\n        self.index += 1;\n        // Extend lifetime to allow simultaneous holding of nonoverlapping\n        // elements, analogous to slice::split_first_mut.\n        unsafe {\n            let ptr = ptr::from_mut::<T>(Pin::into_inner_unchecked(next));\n            Some(Pin::new_unchecked(&mut *ptr))\n        }\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        let len = self.len();\n        (len, Some(len))\n    }\n}\n\nimpl<'a, T> ExactSizeIterator for IterMut<'a, T>\nwhere\n    T: VectorElement,\n{\n    fn len(&self) -> usize {\n        self.v.len() - self.index\n    }\n}\n\nimpl<'a, T> FusedIterator for IterMut<'a, T> where T: VectorElement {}\n\nimpl<T> Debug for CxxVector<T>\nwhere\n    T: VectorElement + Debug,\n{\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        formatter.debug_list().entries(self).finish()\n    }\n}\n\n/// Trait bound for types which may be used as the `T` inside of a\n/// `CxxVector<T>` in generic code.\n///\n/// This trait has no publicly callable or implementable methods. Implementing\n/// it outside of the CXX codebase requires using [explicit shim trait impls],\n/// adding the line `impl CxxVector<MyType> {}` in the same `cxx::bridge` that\n/// defines `MyType`.\n///\n/// # Example\n///\n/// A bound `T: VectorElement` may be necessary when manipulating [`CxxVector`]\n/// in generic code.\n///\n/// ```\n/// use cxx::vector::{CxxVector, VectorElement};\n/// use std::fmt::Display;\n///\n/// pub fn take_generic_vector<T>(vector: &CxxVector<T>)\n/// where\n///     T: VectorElement + Display,\n/// {\n///     println!(\"the vector elements are:\");\n///     for element in vector {\n///         println!(\"  • {}\", element);\n///     }\n/// }\n/// ```\n///\n/// Writing the same generic function without a `VectorElement` trait bound\n/// would not compile.\n///\n/// [explicit shim trait impls]: https://cxx.rs/extern-c++.html#explicit-shim-trait-impls\npub unsafe trait VectorElement: Sized {\n    #[doc(hidden)]\n    fn __typename(f: &mut fmt::Formatter) -> fmt::Result;\n    #[doc(hidden)]\n    fn __vector_new() -> *mut CxxVector<Self>;\n    #[doc(hidden)]\n    fn __vector_size(v: &CxxVector<Self>) -> usize;\n    #[doc(hidden)]\n    fn __vector_capacity(v: &CxxVector<Self>) -> usize;\n    #[doc(hidden)]\n    unsafe fn __get_unchecked(v: *mut CxxVector<Self>, pos: usize) -> *mut Self;\n    #[doc(hidden)]\n    unsafe fn __reserve(v: Pin<&mut CxxVector<Self>>, new_cap: usize);\n    #[doc(hidden)]\n    unsafe fn __push_back(v: Pin<&mut CxxVector<Self>>, value: &mut ManuallyDrop<Self>) {\n        // Opaque C type vector elements do not get this method because they can\n        // never exist by value on the Rust side of the bridge.\n        let _ = v;\n        let _ = value;\n        unreachable!()\n    }\n    #[doc(hidden)]\n    unsafe fn __pop_back(v: Pin<&mut CxxVector<Self>>, out: &mut MaybeUninit<Self>) {\n        // Opaque C type vector elements do not get this method because they can\n        // never exist by value on the Rust side of the bridge.\n        let _ = v;\n        let _ = out;\n        unreachable!()\n    }\n    #[doc(hidden)]\n    fn __unique_ptr_null() -> MaybeUninit<*mut c_void>;\n    #[doc(hidden)]\n    unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void>;\n    #[doc(hidden)]\n    unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self>;\n    #[doc(hidden)]\n    unsafe fn __unique_ptr_release(repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self>;\n    #[doc(hidden)]\n    unsafe fn __unique_ptr_drop(repr: MaybeUninit<*mut c_void>);\n}\n\nmacro_rules! vector_element_by_value_methods {\n    (opaque, $segment:expr, $ty:ty) => {};\n    (trivial, $segment:expr, $ty:ty) => {\n        unsafe fn __push_back(v: Pin<&mut CxxVector<$ty>>, value: &mut ManuallyDrop<$ty>) {\n            extern \"C\" {\n                #[link_name = concat!(\"cxxbridge1$std$vector$\", $segment, \"$push_back\")]\n                fn __push_back(_: Pin<&mut CxxVector<$ty>>, _: &mut ManuallyDrop<$ty>);\n            }\n            unsafe { __push_back(v, value) }\n        }\n        unsafe fn __pop_back(v: Pin<&mut CxxVector<$ty>>, out: &mut MaybeUninit<$ty>) {\n            extern \"C\" {\n                #[link_name = concat!(\"cxxbridge1$std$vector$\", $segment, \"$pop_back\")]\n                fn __pop_back(_: Pin<&mut CxxVector<$ty>>, _: &mut MaybeUninit<$ty>);\n            }\n            unsafe { __pop_back(v, out) }\n        }\n    };\n}\n\nmacro_rules! impl_vector_element {\n    ($kind:ident, $segment:expr, $name:expr, $ty:ty) => {\n        const_assert_eq!(0, mem::size_of::<CxxVector<$ty>>());\n        const_assert_eq!(1, mem::align_of::<CxxVector<$ty>>());\n\n        unsafe impl VectorElement for $ty {\n            fn __typename(f: &mut fmt::Formatter) -> fmt::Result {\n                f.write_str($name)\n            }\n            fn __vector_new() -> *mut CxxVector<Self> {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$vector$\", $segment, \"$new\")]\n                    fn __vector_new() -> *mut CxxVector<$ty>;\n                }\n                unsafe { __vector_new() }\n            }\n            fn __vector_size(v: &CxxVector<$ty>) -> usize {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$vector$\", $segment, \"$size\")]\n                    fn __vector_size(_: &CxxVector<$ty>) -> usize;\n                }\n                unsafe { __vector_size(v) }\n            }\n            fn __vector_capacity(v: &CxxVector<$ty>) -> usize {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$vector$\", $segment, \"$capacity\")]\n                    fn __vector_capacity(_: &CxxVector<$ty>) -> usize;\n                }\n                unsafe { __vector_capacity(v) }\n            }\n            unsafe fn __get_unchecked(v: *mut CxxVector<$ty>, pos: usize) -> *mut $ty {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$vector$\", $segment, \"$get_unchecked\")]\n                    fn __get_unchecked(_: *mut CxxVector<$ty>, _: usize) -> *mut $ty;\n                }\n                unsafe { __get_unchecked(v, pos) }\n            }\n            unsafe fn __reserve(v: Pin<&mut CxxVector<$ty>>, new_cap: usize) {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$vector$\", $segment, \"$reserve\")]\n                    fn __reserve(_: Pin<&mut CxxVector<$ty>>, _: usize);\n                }\n                unsafe { __reserve(v, new_cap) }\n            }\n            vector_element_by_value_methods!($kind, $segment, $ty);\n            fn __unique_ptr_null() -> MaybeUninit<*mut c_void> {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$unique_ptr$std$vector$\", $segment, \"$null\")]\n                    fn __unique_ptr_null(this: *mut MaybeUninit<*mut c_void>);\n                }\n                let mut repr = MaybeUninit::uninit();\n                unsafe { __unique_ptr_null(&mut repr) }\n                repr\n            }\n            unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void> {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$unique_ptr$std$vector$\", $segment, \"$raw\")]\n                    fn __unique_ptr_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxVector<$ty>);\n                }\n                let mut repr = MaybeUninit::uninit();\n                unsafe { __unique_ptr_raw(&mut repr, raw) }\n                repr\n            }\n            unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self> {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$unique_ptr$std$vector$\", $segment, \"$get\")]\n                    fn __unique_ptr_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxVector<$ty>;\n                }\n                unsafe { __unique_ptr_get(&repr) }\n            }\n            unsafe fn __unique_ptr_release(mut repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self> {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$unique_ptr$std$vector$\", $segment, \"$release\")]\n                    fn __unique_ptr_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxVector<$ty>;\n                }\n                unsafe { __unique_ptr_release(&mut repr) }\n            }\n            unsafe fn __unique_ptr_drop(mut repr: MaybeUninit<*mut c_void>) {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$unique_ptr$std$vector$\", $segment, \"$drop\")]\n                    fn __unique_ptr_drop(this: *mut MaybeUninit<*mut c_void>);\n                }\n                unsafe { __unique_ptr_drop(&mut repr) }\n            }\n        }\n    };\n}\n\nmacro_rules! impl_vector_element_for_primitive {\n    ($ty:ident) => {\n        impl_vector_element!(trivial, stringify!($ty), stringify!($ty), $ty);\n    };\n}\n\nimpl_vector_element_for_primitive!(u8);\nimpl_vector_element_for_primitive!(u16);\nimpl_vector_element_for_primitive!(u32);\nimpl_vector_element_for_primitive!(u64);\nimpl_vector_element_for_primitive!(usize);\nimpl_vector_element_for_primitive!(i8);\nimpl_vector_element_for_primitive!(i16);\nimpl_vector_element_for_primitive!(i32);\nimpl_vector_element_for_primitive!(i64);\nimpl_vector_element_for_primitive!(isize);\nimpl_vector_element_for_primitive!(f32);\nimpl_vector_element_for_primitive!(f64);\n\nimpl_vector_element!(opaque, \"string\", \"CxxString\", CxxString);\n"
  },
  {
    "path": "src/exception.rs",
    "content": "#![cfg(feature = \"alloc\")]\n\nuse alloc::boxed::Box;\nuse core::fmt::{self, Display};\n\nuse core::error::Error as StdError;\n\n/// Exception thrown from an `extern \"C++\"` function.\n#[cfg_attr(docsrs, doc(cfg(feature = \"alloc\")))]\n#[derive(Debug)]\npub struct Exception {\n    pub(crate) what: Box<str>,\n}\n\nimpl Display for Exception {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.write_str(&self.what)\n    }\n}\n\nimpl StdError for Exception {}\n\nimpl Exception {\n    #[allow(missing_docs)]\n    pub fn what(&self) -> &str {\n        &self.what\n    }\n}\n"
  },
  {
    "path": "src/extern_type.rs",
    "content": "use self::kind::{Kind, Opaque, Trivial};\nuse crate::string::CxxString;\n#[cfg(feature = \"alloc\")]\nuse alloc::string::String;\n\n/// A type for which the layout is determined by its C++ definition.\n///\n/// This trait serves the following two related purposes.\n///\n/// <br>\n///\n/// ## Safely unifying occurrences of the same extern type\n///\n/// `ExternType` makes it possible for CXX to safely share a consistent Rust\n/// type across multiple #\\[cxx::bridge\\] invocations that refer to a common\n/// extern C++ type.\n///\n/// In the following snippet, two #\\[cxx::bridge\\] invocations in different\n/// files (possibly different crates) both contain function signatures involving\n/// the same C++ type `example::Demo`. If both were written just containing\n/// `type Demo;`, then both macro expansions would produce their own separate\n/// Rust type called `Demo` and thus the compiler wouldn't allow us to take the\n/// `Demo` returned by `file1::ffi::create_demo` and pass it as the `Demo`\n/// argument accepted by `file2::ffi::take_ref_demo`. Instead, one of the two\n/// `Demo`s has been defined as an extern type alias of the other, making them\n/// the same type in Rust. The CXX code generator will use an automatically\n/// generated `ExternType` impl emitted in file1 to statically verify that in\n/// file2 `crate::file1::ffi::Demo` really does refer to the C++ type\n/// `example::Demo` as expected in file2.\n///\n/// ```no_run\n/// // file1.rs\n/// # mod file1 {\n/// #[cxx::bridge(namespace = \"example\")]\n/// pub mod ffi {\n///     unsafe extern \"C++\" {\n///         type Demo;\n///\n///         fn create_demo() -> UniquePtr<Demo>;\n///     }\n/// }\n/// # }\n///\n/// // file2.rs\n/// #[cxx::bridge(namespace = \"example\")]\n/// pub mod ffi {\n///     unsafe extern \"C++\" {\n///         type Demo = crate::file1::ffi::Demo;\n///\n///         fn take_ref_demo(demo: &Demo);\n///     }\n/// }\n/// #\n/// # fn main() {}\n/// ```\n///\n/// <br><br>\n///\n/// ## Integrating with bindgen-generated types\n///\n/// Handwritten `ExternType` impls make it possible to plug in a data structure\n/// emitted by bindgen as the definition of a C++ type emitted by CXX.\n///\n/// By writing the unsafe `ExternType` impl, the programmer asserts that the C++\n/// namespace and type name given in the type id refers to a C++ type that is\n/// equivalent to Rust type that is the `Self` type of the impl.\n///\n/// ```no_run\n/// # const _: &str = stringify! {\n/// mod folly_sys;  // the bindgen-generated bindings\n/// # };\n/// # mod folly_sys {\n/// #     #[repr(transparent)]\n/// #     pub struct StringPiece([usize; 2]);\n/// # }\n///\n/// use cxx::{type_id, ExternType};\n///\n/// unsafe impl ExternType for folly_sys::StringPiece {\n///     type Id = type_id!(\"folly::StringPiece\");\n///     type Kind = cxx::kind::Opaque;\n/// }\n///\n/// #[cxx::bridge(namespace = \"folly\")]\n/// pub mod ffi {\n///     unsafe extern \"C++\" {\n///         include!(\"rust_cxx_bindings.h\");\n///\n///         type StringPiece = crate::folly_sys::StringPiece;\n///\n///         fn print_string_piece(s: &StringPiece);\n///     }\n/// }\n///\n/// // Now if we construct a StringPiece or obtain one through one\n/// // of the bindgen-generated signatures, we are able to pass it\n/// // along to ffi::print_string_piece.\n/// #\n/// # fn main() {}\n/// ```\npub unsafe trait ExternType {\n    /// A type-level representation of the type's C++ namespace and type name.\n    ///\n    /// This will always be defined using `type_id!` in the following form:\n    ///\n    /// ```\n    /// # struct TypeName;\n    /// # unsafe impl cxx::ExternType for TypeName {\n    /// type Id = cxx::type_id!(\"name::space::of::TypeName\");\n    /// #     type Kind = cxx::kind::Opaque;\n    /// # }\n    /// ```\n    type Id;\n\n    /// Either [`cxx::kind::Opaque`] or [`cxx::kind::Trivial`].\n    ///\n    /// [`cxx::kind::Opaque`]: kind::Opaque\n    /// [`cxx::kind::Trivial`]: kind::Trivial\n    ///\n    /// A C++ type is only okay to hold and pass around by value in Rust if its\n    /// [move constructor is trivial] and it has no destructor. In CXX, these\n    /// are called Trivial extern C++ types, while types with nontrivial move\n    /// behavior or a destructor must be considered Opaque and handled by Rust\n    /// only behind an indirection, such as a reference or UniquePtr.\n    ///\n    /// [move constructor is trivial]: https://en.cppreference.com/w/cpp/types/is_move_constructible\n    ///\n    /// If you believe your C++ type reflected by this ExternType impl is indeed\n    /// fine to hold by value and move in Rust, you can specify:\n    ///\n    /// ```\n    /// # struct TypeName;\n    /// # unsafe impl cxx::ExternType for TypeName {\n    /// #     type Id = cxx::type_id!(\"name::space::of::TypeName\");\n    /// type Kind = cxx::kind::Trivial;\n    /// # }\n    /// ```\n    ///\n    /// which will enable you to pass it into C++ functions by value, return it\n    /// by value, and include it in `struct`s that you have declared to\n    /// `cxx::bridge`. Your claim about the triviality of the C++ type will be\n    /// checked by a `static_assert` in the generated C++ side of the binding.\n    type Kind: Kind;\n}\n\n/// Marker types identifying Rust's knowledge about an extern C++ type.\n///\n/// These markers are used in the [`Kind`][ExternType::Kind] associated type in\n/// impls of the `ExternType` trait. Refer to the documentation of `Kind` for an\n/// overview of their purpose.\npub mod kind {\n    use super::private;\n\n    /// An opaque type which cannot be passed or held by value within Rust.\n    ///\n    /// Rust's move semantics are such that every move is equivalent to a\n    /// memcpy. This is incompatible in general with C++'s constructor-based\n    /// move semantics, so a C++ type which has a destructor or nontrivial move\n    /// constructor must never exist by value in Rust. In CXX, such types are\n    /// called opaque C++ types.\n    ///\n    /// When passed across an FFI boundary, an opaque C++ type must be behind an\n    /// indirection such as a reference or UniquePtr.\n    pub enum Opaque {}\n\n    /// A type with trivial move constructor and no destructor, which can\n    /// therefore be owned and moved around in Rust code without requiring\n    /// indirection.\n    pub enum Trivial {}\n\n    #[allow(missing_docs)]\n    pub trait Kind: private::Sealed {}\n    impl Kind for Opaque {}\n    impl Kind for Trivial {}\n}\n\nmod private {\n    pub trait Sealed {}\n    impl Sealed for super::Opaque {}\n    impl Sealed for super::Trivial {}\n}\n\n#[doc(hidden)]\npub fn verify_extern_type<T: ExternType<Id = Id>, Id>() {}\n\n#[doc(hidden)]\npub fn verify_extern_kind<T: ExternType<Kind = Kind>, Kind: self::Kind>() {}\n\nmacro_rules! impl_extern_type {\n    ($([$kind:ident] $($(#[$($attr:tt)*])* $ty:path = $cxxpath:literal)*)*) => {\n        $($(\n            $(#[$($attr)*])*\n            unsafe impl ExternType for $ty {\n                #[doc(hidden)]\n                type Id = crate::type_id!($cxxpath);\n                type Kind = $kind;\n            }\n        )*)*\n    };\n}\n\nimpl_extern_type! {\n    [Trivial]\n    bool = \"bool\"\n    u8 = \"std::uint8_t\"\n    u16 = \"std::uint16_t\"\n    u32 = \"std::uint32_t\"\n    u64 = \"std::uint64_t\"\n    usize = \"size_t\"\n    i8 = \"std::int8_t\"\n    i16 = \"std::int16_t\"\n    i32 = \"std::int32_t\"\n    i64 = \"std::int64_t\"\n    isize = \"rust::isize\"\n    f32 = \"float\"\n    f64 = \"double\"\n\n    #[cfg(feature = \"alloc\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"alloc\")))]\n    String = \"rust::String\"\n\n    [Opaque]\n    CxxString = \"std::string\"\n}\n"
  },
  {
    "path": "src/fmt.rs",
    "content": "use core::fmt::{self, Display};\n\npub(crate) fn display(fmt: impl Fn(&mut fmt::Formatter) -> fmt::Result) -> impl Display {\n    DisplayInvoke(fmt)\n}\n\nstruct DisplayInvoke<T>(T);\n\nimpl<T> Display for DisplayInvoke<T>\nwhere\n    T: Fn(&mut fmt::Formatter) -> fmt::Result,\n{\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        (self.0)(formatter)\n    }\n}\n"
  },
  {
    "path": "src/function.rs",
    "content": "#![allow(missing_docs)]\n\nuse core::ffi::c_void;\n\n#[repr(C)]\npub struct FatFunction {\n    pub trampoline: *const c_void,\n    pub ptr: *const c_void,\n}\n"
  },
  {
    "path": "src/hash.rs",
    "content": "use core::hash::{BuildHasher as _, Hash};\n\n#[doc(hidden)]\npub fn hash<V: Hash>(value: &V) -> usize {\n    foldhash::quality::FixedState::default().hash_one(value) as usize\n}\n"
  },
  {
    "path": "src/lib.rs",
    "content": "//! [![github]](https://github.com/dtolnay/cxx)&ensp;[![crates-io]](https://crates.io/crates/cxx)&ensp;[![docs-rs]](https://docs.rs/cxx)\n//!\n//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github\n//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust\n//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs\n//!\n//! <br>\n//!\n//! This library provides a **safe** mechanism for calling C++ code from Rust\n//! and Rust code from C++, not subject to the many ways that things can go\n//! wrong when using bindgen or cbindgen to generate unsafe C-style bindings.\n//!\n//! This doesn't change the fact that 100% of C++ code is unsafe. When auditing\n//! a project, you would be on the hook for auditing all the unsafe Rust code\n//! and *all* the C++ code. The core safety claim under this new model is that\n//! auditing just the C++ side would be sufficient to catch all problems, i.e.\n//! the Rust side can be 100% safe.\n//!\n//! <br>\n//!\n//! *Compiler support: requires rustc 1.85+ and c++11 or newer*<br>\n//! *[Release notes](https://github.com/dtolnay/cxx/releases)*\n//!\n//! <br>\n//!\n//! # Guide\n//!\n//! Please see **<https://cxx.rs>** for a tutorial, reference material, and\n//! example code.\n//!\n//! <br>\n//!\n//! # Overview\n//!\n//! The idea is that we define the signatures of both sides of our FFI boundary\n//! embedded together in one Rust module (the next section shows an example).\n//! From this, CXX receives a complete picture of the boundary to perform static\n//! analyses against the types and function signatures to uphold both Rust's and\n//! C++'s invariants and requirements.\n//!\n//! If everything checks out statically, then CXX uses a pair of code generators\n//! to emit the relevant `extern \"C\"` signatures on both sides together with any\n//! necessary static assertions for later in the build process to verify\n//! correctness. On the Rust side this code generator is simply an attribute\n//! procedural macro. On the C++ side it can be a small Cargo build script if\n//! your build is managed by Cargo, or for other build systems like Bazel or\n//! Buck we provide a command line tool which generates the header and source\n//! file and should be easy to integrate.\n//!\n//! The resulting FFI bridge operates at zero or negligible overhead, i.e. no\n//! copying, no serialization, no memory allocation, no runtime checks needed.\n//!\n//! The FFI signatures are able to use native types from whichever side they\n//! please, such as Rust's `String` or C++'s `std::string`, Rust's `Box` or\n//! C++'s `std::unique_ptr`, Rust's `Vec` or C++'s `std::vector`, etc in any\n//! combination. CXX guarantees an ABI-compatible signature that both sides\n//! understand, based on builtin bindings for key standard library types to\n//! expose an idiomatic API on those types to the other language. For example\n//! when manipulating a C++ string from Rust, its `len()` method becomes a call\n//! of the `size()` member function defined by C++; when manipulation a Rust\n//! string from C++, its `size()` member function calls Rust's `len()`.\n//!\n//! <br>\n//!\n//! # Example\n//!\n//! In this example we are writing a Rust application that wishes to take\n//! advantage of an existing C++ client for a large-file blobstore service. The\n//! blobstore supports a `put` operation for a discontiguous buffer upload. For\n//! example we might be uploading snapshots of a circular buffer which would\n//! tend to consist of 2 chunks, or fragments of a file spread across memory for\n//! some other reason.\n//!\n//! A runnable version of this example is provided under the *demo* directory of\n//! <https://github.com/dtolnay/cxx>. To try it out, run `cargo run` from that\n//! directory.\n//!\n//! ```no_run\n//! #[cxx::bridge]\n//! mod ffi {\n//!     // Any shared structs, whose fields will be visible to both languages.\n//!     struct BlobMetadata {\n//!         size: usize,\n//!         tags: Vec<String>,\n//!     }\n//!\n//!     extern \"Rust\" {\n//!         // Zero or more opaque types which both languages can pass around but\n//!         // only Rust can see the fields.\n//!         type MultiBuf;\n//!\n//!         // Functions implemented in Rust.\n//!         fn next_chunk(buf: &mut MultiBuf) -> &[u8];\n//!     }\n//!\n//!     unsafe extern \"C++\" {\n//!         // One or more headers with the matching C++ declarations. Our code\n//!         // generators don't read it but it gets #include'd and used in static\n//!         // assertions to ensure our picture of the FFI boundary is accurate.\n//!         include!(\"demo/include/blobstore.h\");\n//!\n//!         // Zero or more opaque types which both languages can pass around but\n//!         // only C++ can see the fields.\n//!         type BlobstoreClient;\n//!\n//!         // Functions implemented in C++.\n//!         fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;\n//!         fn put(&self, parts: &mut MultiBuf) -> u64;\n//!         fn tag(&self, blobid: u64, tag: &str);\n//!         fn metadata(&self, blobid: u64) -> BlobMetadata;\n//!     }\n//! }\n//! #\n//! # pub struct MultiBuf;\n//! #\n//! # fn next_chunk(_buf: &mut MultiBuf) -> &[u8] {\n//! #     unimplemented!()\n//! # }\n//! #\n//! # fn main() {}\n//! ```\n//!\n//! Now we simply provide Rust definitions of all the things in the `extern\n//! \"Rust\"` block and C++ definitions of all the things in the `extern \"C++\"`\n//! block, and get to call back and forth safely.\n//!\n//! Here are links to the complete set of source files involved in the demo:\n//!\n//! - [demo/src/main.rs](https://github.com/dtolnay/cxx/blob/master/demo/src/main.rs)\n//! - [demo/build.rs](https://github.com/dtolnay/cxx/blob/master/demo/build.rs)\n//! - [demo/include/blobstore.h](https://github.com/dtolnay/cxx/blob/master/demo/include/blobstore.h)\n//! - [demo/src/blobstore.cc](https://github.com/dtolnay/cxx/blob/master/demo/src/blobstore.cc)\n//!\n//! To look at the code generated in both languages for the example by the CXX\n//! code generators:\n//!\n//! ```console\n//!    # run Rust code generator and print to stdout\n//!    # (requires https://github.com/dtolnay/cargo-expand)\n//! $ cargo expand --manifest-path demo/Cargo.toml\n//!\n//!    # run C++ code generator and print to stdout\n//! $ cargo run --manifest-path gen/cmd/Cargo.toml -- demo/src/main.rs\n//! ```\n//!\n//! <br>\n//!\n//! # Details\n//!\n//! As seen in the example, the language of the FFI boundary involves 3 kinds of\n//! items:\n//!\n//! - **Shared structs** &mdash; their fields are made visible to both\n//!   languages. The definition written within cxx::bridge is the single source\n//!   of truth.\n//!\n//! - **Opaque types** &mdash; their fields are secret from the other language.\n//!   These cannot be passed across the FFI by value but only behind an\n//!   indirection, such as a reference `&`, a Rust `Box`, or a `UniquePtr`. Can\n//!   be a type alias for an arbitrarily complicated generic language-specific\n//!   type depending on your use case.\n//!\n//! - **Functions** &mdash; implemented in either language, callable from the\n//!   other language.\n//!\n//! Within the `extern \"Rust\"` part of the CXX bridge we list the types and\n//! functions for which Rust is the source of truth. These all implicitly refer\n//! to the `super` module, the parent module of the CXX bridge. You can think of\n//! the two items listed in the example above as being like `use\n//! super::MultiBuf` and `use super::next_chunk` except re-exported to C++. The\n//! parent module will either contain the definitions directly for simple\n//! things, or contain the relevant `use` statements to bring them into scope\n//! from elsewhere.\n//!\n//! Within the `extern \"C++\"` part, we list types and functions for which C++ is\n//! the source of truth, as well as the header(s) that declare those APIs. In\n//! the future it's possible that this section could be generated bindgen-style\n//! from the headers but for now we need the signatures written out; static\n//! assertions will verify that they are accurate.\n//!\n//! Your function implementations themselves, whether in C++ or Rust, *do not*\n//! need to be defined as `extern \"C\"` ABI or no\\_mangle. CXX will put in the\n//! right shims where necessary to make it all work.\n//!\n//! <br>\n//!\n//! # Comparison vs bindgen and cbindgen\n//!\n//! Notice that with CXX there is repetition of all the function signatures:\n//! they are typed out once where the implementation is defined (in C++ or Rust)\n//! and again inside the cxx::bridge module, though compile-time assertions\n//! guarantee these are kept in sync. This is different from [bindgen] and\n//! [cbindgen] where function signatures are typed by a human once and the tool\n//! consumes them in one language and emits them in the other language.\n//!\n//! [bindgen]: https://github.com/rust-lang/rust-bindgen\n//! [cbindgen]: https://github.com/eqrion/cbindgen/\n//!\n//! This is because CXX fills a somewhat different role. It is a lower level\n//! tool than bindgen or cbindgen in a sense; you can think of it as being a\n//! replacement for the concept of `extern \"C\"` signatures as we know them,\n//! rather than a replacement for a bindgen. It would be reasonable to build a\n//! higher level bindgen-like tool on top of CXX which consumes a C++ header\n//! and/or Rust module (and/or IDL like Thrift) as source of truth and generates\n//! the cxx::bridge, eliminating the repetition while leveraging the static\n//! analysis safety guarantees of CXX.\n//!\n//! But note in other ways CXX is higher level than the bindgens, with rich\n//! support for common standard library types. Frequently with bindgen when we\n//! are dealing with an idiomatic C++ API we would end up manually wrapping that\n//! API in C-style raw pointer functions, applying bindgen to get unsafe raw\n//! pointer Rust functions, and replicating the API again to expose those\n//! idiomatically in Rust. That's a much worse form of repetition because it is\n//! unsafe all the way through.\n//!\n//! By using a CXX bridge as the shared understanding between the languages,\n//! rather than `extern \"C\"` C-style signatures as the shared understanding,\n//! common FFI use cases become expressible using 100% safe code.\n//!\n//! It would also be reasonable to mix and match, using CXX bridge for the 95%\n//! of your FFI that is straightforward and doing the remaining few oddball\n//! signatures the old fashioned way with bindgen and cbindgen, if for some\n//! reason CXX's static restrictions get in the way. Please file an issue if you\n//! end up taking this approach so that we know what ways it would be worthwhile\n//! to make the tool more expressive.\n//!\n//! <br>\n//!\n//! # Cargo-based setup\n//!\n//! For builds that are orchestrated by Cargo, you will use a build script that\n//! runs CXX's C++ code generator and compiles the resulting C++ code along with\n//! any other C++ code for your crate.\n//!\n//! The canonical build script is as follows. The indicated line returns a\n//! [`cc::Build`] instance (from the usual widely used `cc` crate) on which you\n//! can set up any additional source files and compiler flags as normal.\n//!\n//! [`cc::Build`]: https://docs.rs/cc/1.0/cc/struct.Build.html\n//!\n//! ```toml\n//! # Cargo.toml\n//!\n//! [build-dependencies]\n//! cxx-build = \"1.0\"\n//! ```\n//!\n//! ```no_run\n//! // build.rs\n//!\n//! fn main() {\n//!     cxx_build::bridge(\"src/main.rs\")  // returns a cc::Build\n//!         .file(\"src/demo.cc\")\n//!         .std(\"c++11\")\n//!         .compile(\"cxxbridge-demo\");\n//!\n//!     println!(\"cargo:rerun-if-changed=src/demo.cc\");\n//!     println!(\"cargo:rerun-if-changed=include/demo.h\");\n//! }\n//! ```\n//!\n//! <br><br>\n//!\n//! # Non-Cargo setup\n//!\n//! For use in non-Cargo builds like Bazel or Buck, CXX provides an alternate\n//! way of invoking the C++ code generator as a standalone command line tool.\n//! The tool is packaged as the `cxxbridge-cmd` crate on crates.io or can be\n//! built from the *gen/cmd* directory of <https://github.com/dtolnay/cxx>.\n//!\n//! ```bash\n//! $ cargo install cxxbridge-cmd\n//!\n//! $ cxxbridge src/main.rs --header > path/to/mybridge.h\n//! $ cxxbridge src/main.rs > path/to/mybridge.cc\n//! ```\n//!\n//! <br>\n//!\n//! # Safety\n//!\n//! Be aware that the design of this library is intentionally restrictive and\n//! opinionated! It isn't a goal to be powerful enough to handle arbitrary\n//! signatures in either language. Instead this project is about carving out a\n//! reasonably expressive set of functionality about which we can make useful\n//! safety guarantees today and maybe extend over time. You may find that it\n//! takes some practice to use CXX bridge effectively as it won't work in all\n//! the ways that you are used to.\n//!\n//! Some of the considerations that go into ensuring safety are:\n//!\n//! - By design, our paired code generators work together to control both sides\n//!   of the FFI boundary. Ordinarily in Rust writing your own `extern \"C\"`\n//!   blocks is unsafe because the Rust compiler has no way to know whether the\n//!   signatures you've written actually match the signatures implemented in the\n//!   other language. With CXX we achieve that visibility and know what's on the\n//!   other side.\n//!\n//! - Our static analysis detects and prevents passing types by value that\n//!   shouldn't be passed by value from C++ to Rust, for example because they\n//!   may contain internal pointers that would be screwed up by Rust's move\n//!   behavior.\n//!\n//! - To many people's surprise, it is possible to have a struct in Rust and a\n//!   struct in C++ with exactly the same layout / fields / alignment /\n//!   everything, and still not the same ABI when passed by value. This is a\n//!   longstanding bindgen bug that leads to segfaults in absolutely\n//!   correct-looking code ([rust-lang/rust-bindgen#778]). CXX knows about this\n//!   and can insert the necessary zero-cost workaround transparently where\n//!   needed, so go ahead and pass your structs by value without worries. This\n//!   is made possible by owning both sides of the boundary rather than just\n//!   one.\n//!\n//! - Template instantiations: for example in order to expose a UniquePtr\\<T\\>\n//!   type in Rust backed by a real C++ unique\\_ptr, we have a way of using a\n//!   Rust trait to connect the behavior back to the template instantiations\n//!   performed by the other language.\n//!\n//! [rust-lang/rust-bindgen#778]: https://github.com/rust-lang/rust-bindgen/issues/778\n//!\n//! <br>\n//!\n//! # Builtin types\n//!\n//! In addition to all the primitive types (i32 &lt;=&gt; int32_t), the\n//! following common types may be used in the fields of shared structs and the\n//! arguments and returns of functions.\n//!\n//! <table>\n//! <tr><th>name in Rust</th><th>name in C++</th><th>restrictions</th></tr>\n//! <tr><td>String</td><td>rust::String</td><td></td></tr>\n//! <tr><td>&amp;str</td><td>rust::Str</td><td></td></tr>\n//! <tr><td>&amp;[T]</td><td>rust::Slice&lt;const T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n//! <tr><td>&amp;mut [T]</td><td>rust::Slice&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n//! <tr><td><a href=\"struct.CxxString.html\">CxxString</a></td><td>std::string</td><td><sup><i>cannot be passed by value</i></sup></td></tr>\n//! <tr><td>Box&lt;T&gt;</td><td>rust::Box&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n//! <tr><td><a href=\"struct.UniquePtr.html\">UniquePtr&lt;T&gt;</a></td><td>std::unique_ptr&lt;T&gt;</td><td><sup><i>cannot hold opaque Rust type</i></sup></td></tr>\n//! <tr><td><a href=\"struct.SharedPtr.html\">SharedPtr&lt;T&gt;</a></td><td>std::shared_ptr&lt;T&gt;</td><td><sup><i>cannot hold opaque Rust type</i></sup></td></tr>\n//! <tr><td>[T; N]</td><td>std::array&lt;T, N&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n//! <tr><td>Vec&lt;T&gt;</td><td>rust::Vec&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>\n//! <tr><td><a href=\"struct.CxxVector.html\">CxxVector&lt;T&gt;</a></td><td>std::vector&lt;T&gt;</td><td><sup><i>cannot be passed by value, cannot hold opaque Rust type</i></sup></td></tr>\n//! <tr><td>*mut T, *const T</td><td>T*, const T*</td><td><sup><i>fn with a raw pointer argument must be declared unsafe to call</i></sup></td></tr>\n//! <tr><td>fn(T, U) -&gt; V</td><td>rust::Fn&lt;V(T, U)&gt;</td><td><sup><i>only passing from Rust to C++ is implemented so far</i></sup></td></tr>\n//! <tr><td>Result&lt;T&gt;</td><td>throw/catch</td><td><sup><i>allowed as return type only</i></sup></td></tr>\n//! </table>\n//!\n//! The C++ API of the `rust` namespace is defined by the *include/cxx.h* file\n//! in <https://github.com/dtolnay/cxx>. You will need to include this header in\n//! your C++ code when working with those types.\n//!\n//! The following types are intended to be supported \"soon\" but are just not\n//! implemented yet. I don't expect any of these to be hard to make work but\n//! it's a matter of designing a nice API for each in its non-native language.\n//!\n//! <table>\n//! <tr><th>name in Rust</th><th>name in C++</th></tr>\n//! <tr><td>BTreeMap&lt;K, V&gt;</td><td><sup><i>tbd</i></sup></td></tr>\n//! <tr><td>HashMap&lt;K, V&gt;</td><td><sup><i>tbd</i></sup></td></tr>\n//! <tr><td>Arc&lt;T&gt;</td><td><sup><i>tbd</i></sup></td></tr>\n//! <tr><td>Option&lt;T&gt;</td><td><sup><i>tbd</i></sup></td></tr>\n//! <tr><td><sup><i>tbd</i></sup></td><td>std::map&lt;K, V&gt;</td></tr>\n//! <tr><td><sup><i>tbd</i></sup></td><td>std::unordered_map&lt;K, V&gt;</td></tr>\n//! </table>\n\n#![no_std]\n#![doc(html_root_url = \"https://docs.rs/cxx/1.0.194\")]\n#![cfg_attr(docsrs, feature(doc_cfg))]\n#![deny(\n    improper_ctypes,\n    improper_ctypes_definitions,\n    missing_docs,\n    unsafe_op_in_unsafe_fn\n)]\n#![warn(\n    clippy::alloc_instead_of_core,\n    clippy::std_instead_of_alloc,\n    clippy::std_instead_of_core\n)]\n#![expect(non_camel_case_types)]\n#![allow(\n    clippy::cast_possible_truncation,\n    clippy::doc_markdown,\n    clippy::elidable_lifetime_names,\n    clippy::items_after_statements,\n    clippy::len_without_is_empty,\n    clippy::missing_errors_doc,\n    clippy::missing_safety_doc,\n    clippy::must_use_candidate,\n    clippy::needless_doctest_main,\n    clippy::needless_lifetimes,\n    clippy::needless_pass_by_value,\n    clippy::new_without_default,\n    clippy::uninlined_format_args\n)]\n#![allow(unknown_lints, mismatched_lifetime_syntaxes)]\n\n#[cfg(built_with_cargo)]\nextern crate link_cplusplus;\n\nextern crate self as cxx;\n\n#[doc(hidden)]\npub extern crate core;\n\n#[cfg(feature = \"alloc\")]\n#[doc(hidden)]\npub extern crate alloc;\n\n#[cfg(not(feature = \"alloc\"))]\nextern crate core as alloc;\n\n#[cfg(feature = \"std\")]\n#[doc(hidden)]\npub extern crate std;\n\n// Block inadvertent use of items from libstd, which does not otherwise produce\n// a compile-time error on edition 2018+.\n#[cfg(not(feature = \"std\"))]\nextern crate core as std;\n\n#[cfg(not(any(feature = \"alloc\", cxx_experimental_no_alloc)))]\ncompile_error! {\n    r#\"cxx support for no_alloc is incomplete and semver exempt; you must build with at least one of feature=\"std\", feature=\"alloc\", or RUSTFLAGS='--cfg cxx_experimental_no_alloc'\"#\n}\n\n#[cfg(all(compile_error_if_alloc, feature = \"alloc\"))]\ncompile_error! {\n    r#\"feature=\"alloc\" is unexpectedly enabled\"#\n}\n\n#[cfg(all(compile_error_if_std, feature = \"std\"))]\ncompile_error! {\n    r#\"feature=\"std\" is unexpectedly enabled\"#\n}\n\n#[macro_use]\nmod macros;\n\nmod cxx_vector;\nmod exception;\nmod extern_type;\nmod fmt;\nmod function;\nmod hash;\nmod lossy;\npub mod memory;\nmod opaque;\nmod result;\nmod rust_slice;\nmod rust_str;\nmod rust_string;\nmod rust_type;\nmod rust_vec;\nmod shared_ptr;\n#[path = \"cxx_string.rs\"]\nmod string;\nmod symbols;\nmod type_id;\nmod unique_ptr;\nmod unwind;\npub mod vector;\nmod weak_ptr;\n\npub use crate::cxx_vector::CxxVector;\n#[cfg(feature = \"alloc\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"alloc\")))]\npub use crate::exception::Exception;\npub use crate::extern_type::{kind, ExternType};\npub use crate::shared_ptr::SharedPtr;\npub use crate::string::CxxString;\npub use crate::unique_ptr::UniquePtr;\npub use crate::weak_ptr::WeakPtr;\npub use cxxbridge_macro::bridge;\n\n/// Synonym for `CxxString`.\n///\n/// To avoid confusion with Rust's standard library string you probably\n/// shouldn't import this type with `use`. Instead, write `cxx::String`, or\n/// import and use `CxxString`.\npub type String = CxxString;\n\n/// Synonym for `CxxVector`.\n///\n/// To avoid confusion with Rust's standard library vector you probably\n/// shouldn't import this type with `use`. Instead, write `cxx::Vector<T>`, or\n/// import and use `CxxVector`.\npub type Vector<T> = CxxVector<T>;\n\n// Not public API.\n#[doc(hidden)]\npub mod private {\n    pub use crate::extern_type::{verify_extern_kind, verify_extern_type};\n    pub use crate::function::FatFunction;\n    pub use crate::hash::hash;\n    pub use crate::opaque::Opaque;\n    #[cfg(feature = \"alloc\")]\n    pub use crate::result::{r#try, Result};\n    pub use crate::rust_slice::RustSlice;\n    pub use crate::rust_str::RustStr;\n    #[cfg(feature = \"alloc\")]\n    pub use crate::rust_string::RustString;\n    pub use crate::rust_type::{\n        require_box, require_unpin, require_vec, with, ImplBox, ImplVec, RustType, Without,\n    };\n    #[cfg(feature = \"alloc\")]\n    pub use crate::rust_vec::RustVec;\n    pub use crate::string::StackString;\n    pub use crate::unwind::prevent_unwind;\n    pub use cxxbridge_macro::type_id;\n}\n\nmod actually_private {\n    pub trait Private {}\n}\n\nmacro_rules! chars {\n    ($($ch:ident)*) => {\n        $(\n            #[doc(hidden)]\n            pub enum $ch {}\n        )*\n    };\n}\n\nchars! {\n    _0 _1 _2 _3 _4 _5 _6 _7 _8 _9\n    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z\n    a b c d e f g h i j k l m n o p q r s t u v w x y z\n    __ // underscore\n}\n\n#[repr(transparent)]\nstruct void(core::ffi::c_void);\n"
  },
  {
    "path": "src/lossy.rs",
    "content": "use core::char;\nuse core::fmt::{self, Write as _};\nuse core::str;\n\npub(crate) fn display(mut bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {\n    loop {\n        match str::from_utf8(bytes) {\n            Ok(valid) => return f.write_str(valid),\n            Err(utf8_error) => {\n                let valid_up_to = utf8_error.valid_up_to();\n                let valid = unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) };\n                f.write_str(valid)?;\n                f.write_char(char::REPLACEMENT_CHARACTER)?;\n                if let Some(error_len) = utf8_error.error_len() {\n                    bytes = &bytes[valid_up_to + error_len..];\n                } else {\n                    return Ok(());\n                }\n            }\n        }\n    }\n}\n\npub(crate) fn debug(mut bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {\n    f.write_char('\"')?;\n\n    while !bytes.is_empty() {\n        let from_utf8_result = str::from_utf8(bytes);\n        let valid = match from_utf8_result {\n            Ok(valid) => valid,\n            Err(utf8_error) => {\n                let valid_up_to = utf8_error.valid_up_to();\n                unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) }\n            }\n        };\n\n        let mut written = 0;\n        for (i, ch) in valid.char_indices() {\n            let esc = ch.escape_debug();\n            if esc.len() != 1 && ch != '\\'' {\n                f.write_str(&valid[written..i])?;\n                for ch in esc {\n                    f.write_char(ch)?;\n                }\n                written = i + ch.len_utf8();\n            }\n        }\n        f.write_str(&valid[written..])?;\n\n        match from_utf8_result {\n            Ok(_valid) => break,\n            Err(utf8_error) => {\n                let end_of_broken = if let Some(error_len) = utf8_error.error_len() {\n                    valid.len() + error_len\n                } else {\n                    bytes.len()\n                };\n                for b in &bytes[valid.len()..end_of_broken] {\n                    write!(f, \"\\\\x{:02x}\", b)?;\n                }\n                bytes = &bytes[end_of_broken..];\n            }\n        }\n    }\n\n    f.write_char('\"')\n}\n"
  },
  {
    "path": "src/macros/assert.rs",
    "content": "#[macro_export]\n#[doc(hidden)]\nmacro_rules! const_assert_eq {\n    ($left:expr, $right:expr $(,)?) => {\n        const _: [(); $left] = [(); $right];\n    };\n}\n"
  },
  {
    "path": "src/macros/mod.rs",
    "content": "#[macro_use]\nmod assert;\n"
  },
  {
    "path": "src/memory.rs",
    "content": "//! Less used details of `UniquePtr` and `SharedPtr`.\n//!\n//! The pointer types themselves are exposed at the crate root.\n\npub use crate::shared_ptr::SharedPtrTarget;\npub use crate::unique_ptr::UniquePtrTarget;\npub use crate::weak_ptr::WeakPtrTarget;\n#[doc(no_inline)]\npub use cxx::{SharedPtr, UniquePtr};\n"
  },
  {
    "path": "src/opaque.rs",
    "content": "#![allow(missing_docs)]\n\nuse crate::void;\nuse core::cell::UnsafeCell;\nuse core::marker::{PhantomData, PhantomPinned};\nuse core::mem;\nuse core::panic::RefUnwindSafe;\n\n// . size = 0\n// . align = 1\n// . ffi-safe\n// . !Send\n// . !Sync\n// . !Unpin\n// . not readonly\n// . unwind-safe\n#[repr(C, packed)]\npub struct Opaque {\n    _private: [*const void; 0],\n    _pinned: PhantomData<PhantomPinned>,\n    _mutable: SyncUnsafeCell<PhantomData<()>>,\n}\n\nimpl RefUnwindSafe for Opaque {}\n\n// TODO: https://github.com/rust-lang/rust/issues/95439\n#[repr(transparent)]\nstruct SyncUnsafeCell<T>(UnsafeCell<T>);\n\nunsafe impl<T> Sync for SyncUnsafeCell<T> {}\n\nconst_assert_eq!(0, mem::size_of::<Opaque>());\nconst_assert_eq!(1, mem::align_of::<Opaque>());\n"
  },
  {
    "path": "src/result.rs",
    "content": "#![cfg(feature = \"alloc\")]\n#![allow(missing_docs)]\n\nuse crate::exception::Exception;\nuse alloc::boxed::Box;\nuse alloc::string::{String, ToString};\nuse core::fmt::Display;\nuse core::ptr::{self, NonNull};\nuse core::result::Result as StdResult;\nuse core::slice;\nuse core::str;\n\n#[repr(C)]\n#[derive(Copy, Clone)]\npub(crate) struct PtrLen {\n    pub ptr: NonNull<u8>,\n    pub len: usize,\n}\n\n#[repr(C)]\npub union Result {\n    err: PtrLen,\n    ok: *const u8, // null\n}\n\npub unsafe fn r#try<T, E>(ret: *mut T, result: StdResult<T, E>) -> Result\nwhere\n    E: Display,\n{\n    match result {\n        Ok(ok) => {\n            unsafe { ptr::write(ret, ok) }\n            Result { ok: ptr::null() }\n        }\n        Err(err) => unsafe { to_c_error(err.to_string()) },\n    }\n}\n\nunsafe fn to_c_error(msg: String) -> Result {\n    let ptr = msg.as_ptr();\n    let len = msg.len();\n\n    extern \"C\" {\n        #[link_name = \"cxxbridge1$error\"]\n        fn error(ptr: *const u8, len: usize) -> NonNull<u8>;\n    }\n\n    let copy = unsafe { error(ptr, len) };\n    let err = PtrLen { ptr: copy, len };\n    Result { err }\n}\n\nimpl Result {\n    pub unsafe fn exception(self) -> StdResult<(), Exception> {\n        unsafe {\n            if self.ok.is_null() {\n                Ok(())\n            } else {\n                let err = self.err;\n                let slice = slice::from_raw_parts_mut(err.ptr.as_ptr(), err.len);\n                let s = str::from_utf8_unchecked_mut(slice);\n                Err(Exception {\n                    what: Box::from_raw(s),\n                })\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/rust_slice.rs",
    "content": "#![allow(missing_docs)]\n\nuse core::mem::{self, MaybeUninit};\nuse core::ptr::{self, NonNull};\nuse core::slice;\n\n// ABI compatible with C++ rust::Slice<T> (not necessarily &[T]).\n#[repr(C)]\npub struct RustSlice {\n    repr: [MaybeUninit<usize>; mem::size_of::<NonNull<[()]>>() / mem::size_of::<usize>()],\n}\n\nimpl RustSlice {\n    pub fn from_ref<T>(slice: &[T]) -> Self {\n        let ptr = NonNull::from(slice).cast::<T>();\n        let len = slice.len();\n        Self::from_raw_parts(ptr, len)\n    }\n\n    pub fn from_mut<T>(slice: &mut [T]) -> Self {\n        let ptr = NonNull::from(&mut *slice).cast::<T>();\n        let len = slice.len();\n        Self::from_raw_parts(ptr, len)\n    }\n\n    pub unsafe fn as_slice<'a, T>(self) -> &'a [T] {\n        let ptr = self.as_non_null_ptr().as_ptr();\n        let len = self.len();\n        unsafe { slice::from_raw_parts(ptr, len) }\n    }\n\n    pub unsafe fn as_mut_slice<'a, T>(self) -> &'a mut [T] {\n        let ptr = self.as_non_null_ptr().as_ptr();\n        let len = self.len();\n        unsafe { slice::from_raw_parts_mut(ptr, len) }\n    }\n\n    pub(crate) fn from_raw_parts<T>(ptr: NonNull<T>, len: usize) -> Self {\n        // TODO: use NonNull::from_raw_parts(ptr.cast(), len) when stable.\n        // https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.from_raw_parts\n        // https://github.com/rust-lang/rust/issues/81513\n        let ptr = ptr::slice_from_raw_parts_mut(ptr.as_ptr().cast(), len);\n        unsafe { mem::transmute::<NonNull<[()]>, RustSlice>(NonNull::new_unchecked(ptr)) }\n    }\n\n    pub(crate) fn as_non_null_ptr<T>(&self) -> NonNull<T> {\n        let rust_slice = RustSlice { repr: self.repr };\n        let repr = unsafe { mem::transmute::<RustSlice, NonNull<[()]>>(rust_slice) };\n        repr.cast()\n    }\n\n    pub(crate) fn len(&self) -> usize {\n        let rust_slice = RustSlice { repr: self.repr };\n        let repr = unsafe { mem::transmute::<RustSlice, NonNull<[()]>>(rust_slice) };\n        // TODO: use repr.len() when stable.\n        // https://doc.rust-lang.org/nightly/std/ptr/struct.NonNull.html#method.len\n        // https://github.com/rust-lang/rust/issues/71146\n        unsafe { repr.as_ref() }.len()\n    }\n}\n\nconst_assert_eq!(mem::size_of::<NonNull<[()]>>(), mem::size_of::<RustSlice>());\nconst_assert_eq!(\n    mem::align_of::<NonNull<[()]>>(),\n    mem::align_of::<RustSlice>(),\n);\n"
  },
  {
    "path": "src/rust_str.rs",
    "content": "#![allow(missing_docs)]\n\nuse core::mem::{self, MaybeUninit};\nuse core::ptr::NonNull;\nuse core::str;\n\n// ABI compatible with C++ rust::Str (not necessarily &str).\n#[repr(C)]\npub struct RustStr {\n    repr: [MaybeUninit<usize>; mem::size_of::<NonNull<str>>() / mem::size_of::<usize>()],\n}\n\nimpl RustStr {\n    pub fn from(repr: &str) -> Self {\n        let repr = NonNull::from(repr);\n        unsafe { mem::transmute::<NonNull<str>, RustStr>(repr) }\n    }\n\n    pub unsafe fn as_str<'a>(self) -> &'a str {\n        unsafe {\n            let repr = mem::transmute::<RustStr, NonNull<str>>(self);\n            &*repr.as_ptr()\n        }\n    }\n}\n\nconst_assert_eq!(mem::size_of::<NonNull<str>>(), mem::size_of::<RustStr>());\nconst_assert_eq!(mem::align_of::<NonNull<str>>(), mem::align_of::<RustStr>());\n"
  },
  {
    "path": "src/rust_string.rs",
    "content": "#![cfg(feature = \"alloc\")]\n#![allow(missing_docs)]\n\nuse alloc::string::String;\nuse core::mem::{self, MaybeUninit};\nuse core::ptr;\n\n// ABI compatible with C++ rust::String (not necessarily alloc::string::String).\n#[repr(C)]\npub struct RustString {\n    repr: [MaybeUninit<usize>; mem::size_of::<String>() / mem::size_of::<usize>()],\n}\n\nimpl RustString {\n    pub fn from(s: String) -> Self {\n        unsafe { mem::transmute::<String, RustString>(s) }\n    }\n\n    pub fn from_ref(s: &String) -> &Self {\n        unsafe { &*(ptr::from_ref::<String>(s).cast::<RustString>()) }\n    }\n\n    pub fn from_mut(s: &mut String) -> &mut Self {\n        unsafe { &mut *(ptr::from_mut::<String>(s).cast::<RustString>()) }\n    }\n\n    pub fn into_string(self) -> String {\n        unsafe { mem::transmute::<RustString, String>(self) }\n    }\n\n    pub fn as_string(&self) -> &String {\n        unsafe { &*(ptr::from_ref::<RustString>(self).cast::<String>()) }\n    }\n\n    pub fn as_mut_string(&mut self) -> &mut String {\n        unsafe { &mut *(ptr::from_mut::<RustString>(self).cast::<String>()) }\n    }\n}\n\nimpl Drop for RustString {\n    fn drop(&mut self) {\n        unsafe { ptr::drop_in_place(self.as_mut_string()) }\n    }\n}\n\nconst_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<RustString>());\nconst_assert_eq!(mem::size_of::<String>(), mem::size_of::<RustString>());\nconst_assert_eq!(mem::align_of::<String>(), mem::align_of::<RustString>());\n"
  },
  {
    "path": "src/rust_type.rs",
    "content": "#![allow(missing_docs)]\n\nuse crate::extern_type::ExternType;\nuse crate::kind::Trivial;\nuse core::marker::{PhantomData, Unpin};\nuse core::ops::Deref;\n\npub unsafe trait RustType {}\npub unsafe trait ImplBox {}\npub unsafe trait ImplVec {}\n\n// Opaque Rust types are required to be Unpin.\npub fn require_unpin<T: ?Sized + Unpin>() {}\n\npub fn require_box<T: ImplBox>() {}\npub fn require_vec<T: ImplVec>() {}\n\npub struct With<T: ?Sized>(PhantomData<T>);\npub struct Without;\n\npub const fn with<T: ?Sized>() -> With<T> {\n    With(PhantomData)\n}\n\nimpl<T: ?Sized + RustType> With<T> {\n    #[allow(clippy::unused_self)]\n    pub const fn check_slice<U>(&self) {}\n}\n\nimpl<T: ?Sized> Deref for With<T> {\n    type Target = Without;\n    fn deref(&self) -> &Self::Target {\n        &Without\n    }\n}\n\npub trait SliceOfExternType {\n    type Kind;\n}\nimpl<T: ExternType> SliceOfExternType for &[T] {\n    type Kind = T::Kind;\n}\nimpl<T: ExternType> SliceOfExternType for &mut [T] {\n    type Kind = T::Kind;\n}\n\nimpl Without {\n    #[allow(clippy::unused_self)]\n    pub const fn check_slice<U: SliceOfExternType<Kind = Trivial>>(&self) {}\n}\n"
  },
  {
    "path": "src/rust_vec.rs",
    "content": "#![cfg(feature = \"alloc\")]\n#![allow(missing_docs)]\n\nuse alloc::vec::Vec;\nuse core::ffi::c_void;\nuse core::marker::PhantomData;\nuse core::mem::{self, MaybeUninit};\nuse core::ptr;\n\n// ABI compatible with C++ rust::Vec<T> (not necessarily alloc::vec::Vec<T>).\n#[repr(C)]\npub struct RustVec<T> {\n    repr: [MaybeUninit<usize>; mem::size_of::<Vec<c_void>>() / mem::size_of::<usize>()],\n    marker: PhantomData<Vec<T>>,\n}\n\nimpl<T> RustVec<T> {\n    pub fn new() -> Self {\n        Self::from(Vec::new())\n    }\n\n    pub fn from(v: Vec<T>) -> Self {\n        unsafe { mem::transmute::<Vec<T>, RustVec<T>>(v) }\n    }\n\n    pub fn from_ref(v: &Vec<T>) -> &Self {\n        unsafe { &*(ptr::from_ref::<Vec<T>>(v).cast::<RustVec<T>>()) }\n    }\n\n    pub fn from_mut(v: &mut Vec<T>) -> &mut Self {\n        unsafe { &mut *(ptr::from_mut::<Vec<T>>(v).cast::<RustVec<T>>()) }\n    }\n\n    pub fn into_vec(self) -> Vec<T> {\n        unsafe { mem::transmute::<RustVec<T>, Vec<T>>(self) }\n    }\n\n    pub fn as_vec(&self) -> &Vec<T> {\n        unsafe { &*(ptr::from_ref::<RustVec<T>>(self).cast::<Vec<T>>()) }\n    }\n\n    pub fn as_mut_vec(&mut self) -> &mut Vec<T> {\n        unsafe { &mut *(ptr::from_mut::<RustVec<T>>(self).cast::<Vec<T>>()) }\n    }\n\n    pub fn len(&self) -> usize {\n        self.as_vec().len()\n    }\n\n    pub fn capacity(&self) -> usize {\n        self.as_vec().capacity()\n    }\n\n    pub fn as_ptr(&self) -> *const T {\n        self.as_vec().as_ptr()\n    }\n\n    pub fn reserve_total(&mut self, new_cap: usize) {\n        let vec = self.as_mut_vec();\n        if new_cap > vec.capacity() {\n            let additional = new_cap - vec.len();\n            vec.reserve(additional);\n        }\n    }\n\n    pub unsafe fn set_len(&mut self, len: usize) {\n        unsafe { self.as_mut_vec().set_len(len) }\n    }\n\n    pub fn truncate(&mut self, len: usize) {\n        self.as_mut_vec().truncate(len);\n    }\n}\n\nimpl<T> Drop for RustVec<T> {\n    fn drop(&mut self) {\n        unsafe { ptr::drop_in_place(self.as_mut_vec()) }\n    }\n}\n"
  },
  {
    "path": "src/shared_ptr.rs",
    "content": "use crate::extern_type::ExternType;\nuse crate::fmt::display;\nuse crate::kind::Trivial;\nuse crate::string::CxxString;\nuse crate::unique_ptr::{UniquePtr, UniquePtrTarget};\nuse crate::weak_ptr::{WeakPtr, WeakPtrTarget};\nuse core::cmp::Ordering;\nuse core::ffi::c_void;\nuse core::fmt::{self, Debug, Display};\nuse core::hash::{Hash, Hasher};\nuse core::marker::PhantomData;\nuse core::mem::MaybeUninit;\nuse core::ops::Deref;\nuse core::pin::Pin;\nuse core::ptr;\n\n/// Binding to C++ `std::shared_ptr<T>`.\n///\n/// <div class=\"warning\">\n///\n/// **WARNING:** Unlike Rust's `Arc<T>`, a C++ shared pointer manipulates\n/// pointers to 2 separate objects in general.\n///\n/// 1. One is the **managed** pointer, and its identity is associated with\n///    shared ownership of a strong and weak count shared by other SharedPtr and\n///    WeakPtr instances having the same managed pointer.\n///\n/// 2. The other is the **stored** pointer, which is commonly either the same as\n///    the managed pointer, or is a pointer into some member of the managed\n///    object, but can be any unrelated pointer in general.\n///\n/// The managed pointer is the one passed to a deleter upon the strong count\n/// reaching zero, but the stored pointer is the one accessed by deref\n/// operations and methods such as `is_null`.\n///\n/// A shared pointer is considered **empty** if the strong count is zero,\n/// meaning the managed pointer has been deleted or is about to be deleted. A\n/// shared pointer is considered **null** if the stored pointer is the null\n/// pointer. All combinations are possible. To be explicit, a shared pointer can\n/// be nonempty and nonnull, or nonempty and null, or empty and nonnull, or\n/// empty and null. In general all of these cases need to be considered when\n/// handling a SharedPtr.\n///\n/// </div>\n#[repr(C)]\npub struct SharedPtr<T>\nwhere\n    T: SharedPtrTarget,\n{\n    repr: [MaybeUninit<*mut c_void>; 2],\n    ty: PhantomData<T>,\n}\n\nimpl<T> SharedPtr<T>\nwhere\n    T: SharedPtrTarget,\n{\n    /// Makes a new SharedPtr that is both **empty** and **null**.\n    ///\n    /// Matches the behavior of default-constructing a std::shared\\_ptr.\n    pub fn null() -> Self {\n        let mut shared_ptr = MaybeUninit::<SharedPtr<T>>::uninit();\n        let new = shared_ptr.as_mut_ptr().cast();\n        unsafe {\n            T::__null(new);\n            shared_ptr.assume_init()\n        }\n    }\n\n    /// Allocates memory on the heap and makes a SharedPtr owner for it.\n    ///\n    /// The shared pointer will be **nonempty** and **nonnull**.\n    pub fn new(value: T) -> Self\n    where\n        T: ExternType<Kind = Trivial>,\n    {\n        let mut shared_ptr = MaybeUninit::<SharedPtr<T>>::uninit();\n        let new = shared_ptr.as_mut_ptr().cast();\n        unsafe {\n            T::__new(value, new);\n            shared_ptr.assume_init()\n        }\n    }\n\n    /// Creates a shared pointer from a C++ heap-allocated pointer.\n    ///\n    /// Matches the behavior of std::shared\\_ptr's constructor `explicit shared_ptr(T*)`.\n    ///\n    /// The SharedPtr gains ownership of the pointer and will call\n    /// `std::default_delete` on it when the refcount goes to zero.\n    ///\n    /// The object pointed to by the input pointer is not relocated by this\n    /// operation, so any pointers into this data structure elsewhere in the\n    /// program continue to be valid.\n    ///\n    /// The resulting shared pointer is **nonempty** regardless of whether the\n    /// input pointer is null, but may be either **null** or **nonnull**.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `T` is an incomplete type (including `void`) or is not\n    /// destructible.\n    ///\n    /// # Safety\n    ///\n    /// Pointer must either be null or point to a valid instance of T\n    /// heap-allocated in C++ by `new`.\n    #[track_caller]\n    pub unsafe fn from_raw(raw: *mut T) -> Self {\n        let mut shared_ptr = MaybeUninit::<SharedPtr<T>>::uninit();\n        let new = shared_ptr.as_mut_ptr().cast();\n        unsafe {\n            T::__raw(new, raw);\n            shared_ptr.assume_init()\n        }\n    }\n\n    /// Checks whether the SharedPtr holds a null stored pointer.\n    ///\n    /// This is the opposite of [std::shared_ptr\\<T\\>::operator bool](https://en.cppreference.com/w/cpp/memory/shared_ptr/operator_bool).\n    ///\n    /// <div class=\"warning\">\n    ///\n    /// This method is unrelated to the state of the reference count. It is\n    /// possible to have a SharedPtr that is nonnull but empty (has a refcount\n    /// of 0), typically from having been constructed using the alias\n    /// constructors in C++. Inversely, it is also possible to be null and\n    /// nonempty.\n    ///\n    /// </div>\n    pub fn is_null(&self) -> bool {\n        let this = ptr::from_ref::<Self>(self).cast::<c_void>();\n        let ptr = unsafe { T::__get(this) };\n        ptr.is_null()\n    }\n\n    /// Returns a reference to the object pointed to by the stored pointer if\n    /// nonnull, otherwise None.\n    ///\n    /// <div class=\"warning\">\n    ///\n    /// The shared pointer's managed object may or may not already have been\n    /// destroyed.\n    ///\n    /// </div>\n    pub fn as_ref(&self) -> Option<&T> {\n        let ptr = self.as_ptr();\n        unsafe { ptr.as_ref() }\n    }\n\n    /// Returns a mutable pinned reference to the object pointed to by the\n    /// stored pointer.\n    ///\n    /// <div class=\"warning\">\n    ///\n    /// The shared pointer's managed object may or may not already have been\n    /// destroyed.\n    ///\n    /// </div>\n    ///\n    /// # Panics\n    ///\n    /// Panics if the SharedPtr holds a null stored pointer.\n    ///\n    /// # Safety\n    ///\n    /// This method makes no attempt to ascertain the state of the reference\n    /// count. In particular, unlike `Arc::get_mut`, we do not enforce absence\n    /// of other SharedPtr and WeakPtr referring to the same data as this one.\n    /// As always, it is Undefined Behavior to have simultaneous references to\n    /// the same value while a Rust exclusive reference to it exists anywhere in\n    /// the program.\n    ///\n    /// For the special case of CXX [opaque C++ types], this method can be used\n    /// to safely call thread-safe non-const member functions on a C++ object\n    /// without regard for whether the reference is exclusive. This capability\n    /// applies only to opaque types `extern \"C++\" { type T; }`. It does not\n    /// apply to extern types defined with a non-opaque Rust representation\n    /// `extern \"C++\" { type T = ...; }`.\n    ///\n    /// [opaque C++ types]: https://cxx.rs/extern-c++.html#opaque-c-types\n    pub unsafe fn pin_mut_unchecked(&mut self) -> Pin<&mut T> {\n        let ptr = self.as_mut_ptr();\n        match unsafe { ptr.as_mut() } {\n            Some(target) => unsafe { Pin::new_unchecked(target) },\n            None => panic!(\n                \"called pin_mut_unchecked on a null SharedPtr<{}>\",\n                display(T::__typename),\n            ),\n        }\n    }\n\n    /// Returns the SharedPtr's stored pointer as a raw const pointer.\n    pub fn as_ptr(&self) -> *const T {\n        let this = ptr::from_ref::<Self>(self).cast::<c_void>();\n        unsafe { T::__get(this) }\n    }\n\n    /// Returns the SharedPtr's stored pointer as a raw mutable pointer.\n    ///\n    /// As with [std::shared_ptr\\<T\\>::get](https://en.cppreference.com/w/cpp/memory/shared_ptr/get),\n    /// this doesn't require that you hold an exclusive reference to the\n    /// SharedPtr. This differs from Rust norms, so extra care should be taken\n    /// in the way the pointer is used.\n    pub fn as_mut_ptr(&self) -> *mut T {\n        self.as_ptr().cast_mut()\n    }\n\n    /// Constructs new WeakPtr as a non-owning reference to the object managed\n    /// by `self`. If `self` manages no object, the WeakPtr manages no object\n    /// too.\n    ///\n    /// Matches the behavior of [std::weak_ptr\\<T\\>::weak_ptr(const std::shared_ptr\\<T\\> \\&)](https://en.cppreference.com/w/cpp/memory/weak_ptr/weak_ptr).\n    pub fn downgrade(&self) -> WeakPtr<T>\n    where\n        T: WeakPtrTarget,\n    {\n        let this = ptr::from_ref::<Self>(self).cast::<c_void>();\n        let mut weak_ptr = MaybeUninit::<WeakPtr<T>>::uninit();\n        let new = weak_ptr.as_mut_ptr().cast();\n        unsafe {\n            T::__downgrade(this, new);\n            weak_ptr.assume_init()\n        }\n    }\n}\n\nunsafe impl<T> Send for SharedPtr<T> where T: Send + Sync + SharedPtrTarget {}\nunsafe impl<T> Sync for SharedPtr<T> where T: Send + Sync + SharedPtrTarget {}\n\nimpl<T> Clone for SharedPtr<T>\nwhere\n    T: SharedPtrTarget,\n{\n    fn clone(&self) -> Self {\n        let mut shared_ptr = MaybeUninit::<SharedPtr<T>>::uninit();\n        let new = shared_ptr.as_mut_ptr().cast();\n        let this = ptr::from_ref::<Self>(self).cast::<c_void>();\n        unsafe {\n            T::__clone(this, new);\n            shared_ptr.assume_init()\n        }\n    }\n}\n\n// SharedPtr is not a self-referential type and is safe to move out of a Pin,\n// regardless whether the pointer's target is Unpin.\nimpl<T> Unpin for SharedPtr<T> where T: SharedPtrTarget {}\n\nimpl<T> Drop for SharedPtr<T>\nwhere\n    T: SharedPtrTarget,\n{\n    fn drop(&mut self) {\n        let this = ptr::from_mut::<Self>(self).cast::<c_void>();\n        unsafe { T::__drop(this) }\n    }\n}\n\nimpl<T> Deref for SharedPtr<T>\nwhere\n    T: SharedPtrTarget,\n{\n    type Target = T;\n\n    fn deref(&self) -> &Self::Target {\n        match self.as_ref() {\n            Some(target) => target,\n            None => panic!(\n                \"called deref on a null SharedPtr<{}>\",\n                display(T::__typename),\n            ),\n        }\n    }\n}\n\nimpl<T> Debug for SharedPtr<T>\nwhere\n    T: Debug + SharedPtrTarget,\n{\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        match self.as_ref() {\n            None => formatter.write_str(\"nullptr\"),\n            Some(value) => Debug::fmt(value, formatter),\n        }\n    }\n}\n\nimpl<T> Display for SharedPtr<T>\nwhere\n    T: Display + SharedPtrTarget,\n{\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        match self.as_ref() {\n            None => formatter.write_str(\"nullptr\"),\n            Some(value) => Display::fmt(value, formatter),\n        }\n    }\n}\n\nimpl<T> PartialEq for SharedPtr<T>\nwhere\n    T: PartialEq + SharedPtrTarget,\n{\n    fn eq(&self, other: &Self) -> bool {\n        self.as_ref() == other.as_ref()\n    }\n}\n\nimpl<T> Eq for SharedPtr<T> where T: Eq + SharedPtrTarget {}\n\nimpl<T> PartialOrd for SharedPtr<T>\nwhere\n    T: PartialOrd + SharedPtrTarget,\n{\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        PartialOrd::partial_cmp(&self.as_ref(), &other.as_ref())\n    }\n}\n\nimpl<T> Ord for SharedPtr<T>\nwhere\n    T: Ord + SharedPtrTarget,\n{\n    fn cmp(&self, other: &Self) -> Ordering {\n        Ord::cmp(&self.as_ref(), &other.as_ref())\n    }\n}\n\nimpl<T> Hash for SharedPtr<T>\nwhere\n    T: Hash + SharedPtrTarget,\n{\n    fn hash<H>(&self, hasher: &mut H)\n    where\n        H: Hasher,\n    {\n        self.as_ref().hash(hasher);\n    }\n}\n\nimpl<T> From<UniquePtr<T>> for SharedPtr<T>\nwhere\n    T: UniquePtrTarget + SharedPtrTarget,\n{\n    fn from(unique: UniquePtr<T>) -> Self {\n        unsafe { SharedPtr::from_raw(UniquePtr::into_raw(unique)) }\n    }\n}\n\n/// Trait bound for types which may be used as the `T` inside of a\n/// `SharedPtr<T>` in generic code.\n///\n/// This trait has no publicly callable or implementable methods. Implementing\n/// it outside of the CXX codebase is not supported.\n///\n/// # Example\n///\n/// A bound `T: SharedPtrTarget` may be necessary when manipulating\n/// [`SharedPtr`] in generic code.\n///\n/// ```\n/// use cxx::memory::{SharedPtr, SharedPtrTarget};\n/// use std::fmt::Display;\n///\n/// pub fn take_generic_ptr<T>(ptr: SharedPtr<T>)\n/// where\n///     T: SharedPtrTarget + Display,\n/// {\n///     println!(\"the shared_ptr points to: {}\", *ptr);\n/// }\n/// ```\n///\n/// Writing the same generic function without a `SharedPtrTarget` trait bound\n/// would not compile.\npub unsafe trait SharedPtrTarget {\n    #[doc(hidden)]\n    fn __typename(f: &mut fmt::Formatter) -> fmt::Result;\n    #[doc(hidden)]\n    unsafe fn __null(new: *mut c_void);\n    #[doc(hidden)]\n    unsafe fn __new(value: Self, new: *mut c_void)\n    where\n        Self: Sized,\n    {\n        // Opaque C types do not get this method because they can never exist by\n        // value on the Rust side of the bridge.\n        let _ = value;\n        let _ = new;\n        unreachable!()\n    }\n    #[doc(hidden)]\n    unsafe fn __raw(new: *mut c_void, raw: *mut Self);\n    #[doc(hidden)]\n    unsafe fn __clone(this: *const c_void, new: *mut c_void);\n    #[doc(hidden)]\n    unsafe fn __get(this: *const c_void) -> *const Self;\n    #[doc(hidden)]\n    unsafe fn __drop(this: *mut c_void);\n}\n\nmacro_rules! impl_shared_ptr_target {\n    ($segment:expr, $name:expr, $ty:ty) => {\n        unsafe impl SharedPtrTarget for $ty {\n            fn __typename(f: &mut fmt::Formatter) -> fmt::Result {\n                f.write_str($name)\n            }\n            unsafe fn __null(new: *mut c_void) {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$shared_ptr$\", $segment, \"$null\")]\n                    fn __null(new: *mut c_void);\n                }\n                unsafe { __null(new) }\n            }\n            unsafe fn __new(value: Self, new: *mut c_void) {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$shared_ptr$\", $segment, \"$uninit\")]\n                    fn __uninit(new: *mut c_void) -> *mut c_void;\n                }\n                unsafe { __uninit(new).cast::<$ty>().write(value) }\n            }\n            unsafe fn __raw(new: *mut c_void, raw: *mut Self) {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$shared_ptr$\", $segment, \"$raw\")]\n                    fn __raw(new: *mut c_void, raw: *mut c_void);\n                }\n                unsafe { __raw(new, raw.cast::<c_void>()) }\n            }\n            unsafe fn __clone(this: *const c_void, new: *mut c_void) {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$shared_ptr$\", $segment, \"$clone\")]\n                    fn __clone(this: *const c_void, new: *mut c_void);\n                }\n                unsafe { __clone(this, new) }\n            }\n            unsafe fn __get(this: *const c_void) -> *const Self {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$shared_ptr$\", $segment, \"$get\")]\n                    fn __get(this: *const c_void) -> *const c_void;\n                }\n                unsafe { __get(this) }.cast()\n            }\n            unsafe fn __drop(this: *mut c_void) {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$shared_ptr$\", $segment, \"$drop\")]\n                    fn __drop(this: *mut c_void);\n                }\n                unsafe { __drop(this) }\n            }\n        }\n    };\n}\n\nmacro_rules! impl_shared_ptr_target_for_primitive {\n    ($ty:ident) => {\n        impl_shared_ptr_target!(stringify!($ty), stringify!($ty), $ty);\n    };\n}\n\nimpl_shared_ptr_target_for_primitive!(bool);\nimpl_shared_ptr_target_for_primitive!(u8);\nimpl_shared_ptr_target_for_primitive!(u16);\nimpl_shared_ptr_target_for_primitive!(u32);\nimpl_shared_ptr_target_for_primitive!(u64);\nimpl_shared_ptr_target_for_primitive!(usize);\nimpl_shared_ptr_target_for_primitive!(i8);\nimpl_shared_ptr_target_for_primitive!(i16);\nimpl_shared_ptr_target_for_primitive!(i32);\nimpl_shared_ptr_target_for_primitive!(i64);\nimpl_shared_ptr_target_for_primitive!(isize);\nimpl_shared_ptr_target_for_primitive!(f32);\nimpl_shared_ptr_target_for_primitive!(f64);\n\nimpl_shared_ptr_target!(\"string\", \"CxxString\", CxxString);\n"
  },
  {
    "path": "src/symbols/exception.rs",
    "content": "#![cfg(feature = \"alloc\")]\n\nuse crate::result::PtrLen;\nuse alloc::boxed::Box;\nuse alloc::string::String;\nuse core::ptr::NonNull;\nuse core::slice;\n\n#[export_name = \"cxxbridge1$exception\"]\nunsafe extern \"C\" fn exception(ptr: *const u8, len: usize) -> PtrLen {\n    let slice = unsafe { slice::from_raw_parts(ptr, len) };\n    let string = String::from_utf8_lossy(slice);\n    let len = string.len();\n    let raw_str = Box::into_raw(string.into_owned().into_boxed_str());\n    let raw_u8 = raw_str.cast::<u8>();\n    let nonnull = unsafe { NonNull::new_unchecked(raw_u8) };\n    PtrLen { ptr: nonnull, len }\n}\n"
  },
  {
    "path": "src/symbols/mod.rs",
    "content": "mod exception;\nmod rust_slice;\nmod rust_str;\nmod rust_string;\nmod rust_vec;\n"
  },
  {
    "path": "src/symbols/rust_slice.rs",
    "content": "use crate::rust_slice::RustSlice;\nuse core::mem::MaybeUninit;\nuse core::ptr::{self, NonNull};\n\n#[export_name = \"cxxbridge1$slice$new\"]\nunsafe extern \"C\" fn slice_new(this: &mut MaybeUninit<RustSlice>, ptr: NonNull<()>, len: usize) {\n    let this = this.as_mut_ptr();\n    let rust_slice = RustSlice::from_raw_parts(ptr, len);\n    unsafe { ptr::write(this, rust_slice) }\n}\n\n#[export_name = \"cxxbridge1$slice$ptr\"]\nunsafe extern \"C\" fn slice_ptr(this: &RustSlice) -> NonNull<()> {\n    this.as_non_null_ptr()\n}\n\n#[export_name = \"cxxbridge1$slice$len\"]\nunsafe extern \"C\" fn slice_len(this: &RustSlice) -> usize {\n    this.len()\n}\n"
  },
  {
    "path": "src/symbols/rust_str.rs",
    "content": "#[cfg(feature = \"alloc\")]\nuse alloc::string::String;\nuse core::mem::MaybeUninit;\nuse core::ptr;\nuse core::slice;\nuse core::str;\n\n#[export_name = \"cxxbridge1$str$new\"]\nunsafe extern \"C\" fn str_new(this: &mut MaybeUninit<&str>) {\n    let this = this.as_mut_ptr();\n    unsafe { ptr::write(this, \"\") }\n}\n\n#[cfg(feature = \"alloc\")]\n#[export_name = \"cxxbridge1$str$ref\"]\nunsafe extern \"C\" fn str_ref<'a>(this: &mut MaybeUninit<&'a str>, string: &'a String) {\n    let this = this.as_mut_ptr();\n    let s = string.as_str();\n    unsafe { ptr::write(this, s) }\n}\n\n#[export_name = \"cxxbridge1$str$from\"]\nunsafe extern \"C\" fn str_from(this: &mut MaybeUninit<&str>, ptr: *const u8, len: usize) -> bool {\n    let slice = unsafe { slice::from_raw_parts(ptr, len) };\n    match str::from_utf8(slice) {\n        Ok(s) => {\n            let this = this.as_mut_ptr();\n            unsafe { ptr::write(this, s) }\n            true\n        }\n        Err(_) => false,\n    }\n}\n\n#[export_name = \"cxxbridge1$str$ptr\"]\nunsafe extern \"C\" fn str_ptr(this: &&str) -> *const u8 {\n    this.as_ptr()\n}\n\n#[export_name = \"cxxbridge1$str$len\"]\nunsafe extern \"C\" fn str_len(this: &&str) -> usize {\n    this.len()\n}\n"
  },
  {
    "path": "src/symbols/rust_string.rs",
    "content": "#![cfg(feature = \"alloc\")]\n\nuse alloc::borrow::ToOwned;\nuse alloc::string::String;\nuse core::mem::{ManuallyDrop, MaybeUninit};\nuse core::ptr;\nuse core::slice;\nuse core::str;\n\n#[export_name = \"cxxbridge1$string$new\"]\nunsafe extern \"C\" fn string_new(this: &mut MaybeUninit<String>) {\n    let this = this.as_mut_ptr();\n    let new = String::new();\n    unsafe { ptr::write(this, new) }\n}\n\n#[export_name = \"cxxbridge1$string$clone\"]\nunsafe extern \"C\" fn string_clone(this: &mut MaybeUninit<String>, other: &String) {\n    let this = this.as_mut_ptr();\n    let clone = other.clone();\n    unsafe { ptr::write(this, clone) }\n}\n\n#[export_name = \"cxxbridge1$string$from_utf8\"]\nunsafe extern \"C\" fn string_from_utf8(\n    this: &mut MaybeUninit<String>,\n    ptr: *const u8,\n    len: usize,\n) -> bool {\n    let slice = unsafe { slice::from_raw_parts(ptr, len) };\n    match str::from_utf8(slice) {\n        Ok(s) => {\n            let this = this.as_mut_ptr();\n            let owned = s.to_owned();\n            unsafe { ptr::write(this, owned) }\n            true\n        }\n        Err(_) => false,\n    }\n}\n\n#[export_name = \"cxxbridge1$string$from_utf8_lossy\"]\nunsafe extern \"C\" fn string_from_utf8_lossy(\n    this: &mut MaybeUninit<String>,\n    ptr: *const u8,\n    len: usize,\n) {\n    let slice = unsafe { slice::from_raw_parts(ptr, len) };\n    let owned = String::from_utf8_lossy(slice).into_owned();\n    let this = this.as_mut_ptr();\n    unsafe { ptr::write(this, owned) }\n}\n\n#[export_name = \"cxxbridge1$string$from_utf16\"]\nunsafe extern \"C\" fn string_from_utf16(\n    this: &mut MaybeUninit<String>,\n    ptr: *const u16,\n    len: usize,\n) -> bool {\n    let slice = unsafe { slice::from_raw_parts(ptr, len) };\n    match String::from_utf16(slice) {\n        Ok(s) => {\n            let this = this.as_mut_ptr();\n            unsafe { ptr::write(this, s) }\n            true\n        }\n        Err(_) => false,\n    }\n}\n\n#[export_name = \"cxxbridge1$string$from_utf16_lossy\"]\nunsafe extern \"C\" fn string_from_utf16_lossy(\n    this: &mut MaybeUninit<String>,\n    ptr: *const u16,\n    len: usize,\n) {\n    let slice = unsafe { slice::from_raw_parts(ptr, len) };\n    let owned = String::from_utf16_lossy(slice);\n    let this = this.as_mut_ptr();\n    unsafe { ptr::write(this, owned) }\n}\n\n#[export_name = \"cxxbridge1$string$drop\"]\nunsafe extern \"C\" fn string_drop(this: &mut ManuallyDrop<String>) {\n    unsafe { ManuallyDrop::drop(this) }\n}\n\n#[export_name = \"cxxbridge1$string$ptr\"]\nunsafe extern \"C\" fn string_ptr(this: &String) -> *const u8 {\n    this.as_ptr()\n}\n\n#[export_name = \"cxxbridge1$string$len\"]\nunsafe extern \"C\" fn string_len(this: &String) -> usize {\n    this.len()\n}\n\n#[export_name = \"cxxbridge1$string$capacity\"]\nunsafe extern \"C\" fn string_capacity(this: &String) -> usize {\n    this.capacity()\n}\n\n#[export_name = \"cxxbridge1$string$reserve_additional\"]\nunsafe extern \"C\" fn string_reserve_additional(this: &mut String, additional: usize) {\n    this.reserve(additional);\n}\n\n#[export_name = \"cxxbridge1$string$reserve_total\"]\nunsafe extern \"C\" fn string_reserve_total(this: &mut String, new_cap: usize) {\n    if new_cap > this.capacity() {\n        let additional = new_cap - this.len();\n        this.reserve(additional);\n    }\n}\n"
  },
  {
    "path": "src/symbols/rust_vec.rs",
    "content": "#![cfg(feature = \"alloc\")]\n\nuse crate::rust_string::RustString;\nuse crate::rust_vec::RustVec;\nuse alloc::vec::Vec;\nuse core::ffi::c_char;\nuse core::mem;\nuse core::ptr;\n\nmacro_rules! rust_vec_shims {\n    ($segment:expr, $ty:ty) => {\n        const_assert_eq!(mem::size_of::<[usize; 3]>(), mem::size_of::<RustVec<$ty>>());\n        const_assert_eq!(mem::size_of::<Vec<$ty>>(), mem::size_of::<RustVec<$ty>>());\n        const_assert_eq!(mem::align_of::<Vec<$ty>>(), mem::align_of::<RustVec<$ty>>());\n\n        const _: () = {\n            #[export_name = concat!(\"cxxbridge1$rust_vec$\", $segment, \"$new\")]\n            unsafe extern \"C\" fn __new(this: *mut RustVec<$ty>) {\n                unsafe { ptr::write(this, RustVec::new()) }\n            }\n            #[export_name = concat!(\"cxxbridge1$rust_vec$\", $segment, \"$drop\")]\n            unsafe extern \"C\" fn __drop(this: *mut RustVec<$ty>) {\n                unsafe { ptr::drop_in_place(this) }\n            }\n            #[export_name = concat!(\"cxxbridge1$rust_vec$\", $segment, \"$len\")]\n            unsafe extern \"C\" fn __len(this: *const RustVec<$ty>) -> usize {\n                unsafe { &*this }.len()\n            }\n            #[export_name = concat!(\"cxxbridge1$rust_vec$\", $segment, \"$capacity\")]\n            unsafe extern \"C\" fn __capacity(this: *const RustVec<$ty>) -> usize {\n                unsafe { &*this }.capacity()\n            }\n            #[export_name = concat!(\"cxxbridge1$rust_vec$\", $segment, \"$data\")]\n            unsafe extern \"C\" fn __data(this: *const RustVec<$ty>) -> *const $ty {\n                unsafe { &*this }.as_ptr()\n            }\n            #[export_name = concat!(\"cxxbridge1$rust_vec$\", $segment, \"$reserve_total\")]\n            unsafe extern \"C\" fn __reserve_total(this: *mut RustVec<$ty>, new_cap: usize) {\n                unsafe { &mut *this }.reserve_total(new_cap);\n            }\n            #[export_name = concat!(\"cxxbridge1$rust_vec$\", $segment, \"$set_len\")]\n            unsafe extern \"C\" fn __set_len(this: *mut RustVec<$ty>, len: usize) {\n                unsafe { (*this).set_len(len) }\n            }\n            #[export_name = concat!(\"cxxbridge1$rust_vec$\", $segment, \"$truncate\")]\n            unsafe extern \"C\" fn __truncate(this: *mut RustVec<$ty>, len: usize) {\n                unsafe { (*this).truncate(len) }\n            }\n        };\n    };\n}\n\nmacro_rules! rust_vec_shims_for_primitive {\n    ($ty:ident) => {\n        rust_vec_shims!(stringify!($ty), $ty);\n    };\n}\n\nrust_vec_shims_for_primitive!(bool);\nrust_vec_shims_for_primitive!(u8);\nrust_vec_shims_for_primitive!(u16);\nrust_vec_shims_for_primitive!(u32);\nrust_vec_shims_for_primitive!(u64);\nrust_vec_shims_for_primitive!(usize);\nrust_vec_shims_for_primitive!(i8);\nrust_vec_shims_for_primitive!(i16);\nrust_vec_shims_for_primitive!(i32);\nrust_vec_shims_for_primitive!(i64);\nrust_vec_shims_for_primitive!(isize);\nrust_vec_shims_for_primitive!(f32);\nrust_vec_shims_for_primitive!(f64);\n\nrust_vec_shims!(\"char\", c_char);\nrust_vec_shims!(\"string\", RustString);\nrust_vec_shims!(\"str\", &str);\n"
  },
  {
    "path": "src/type_id.rs",
    "content": "/// For use in impls of the `ExternType` trait. See [`ExternType`].\n///\n/// [`ExternType`]: crate::ExternType\n#[macro_export]\nmacro_rules! type_id {\n    ($($path:tt)*) => {\n        $crate::private::type_id! { $crate $($path)* }\n    };\n}\n"
  },
  {
    "path": "src/unique_ptr.rs",
    "content": "use crate::cxx_vector::{CxxVector, VectorElement};\nuse crate::extern_type::ExternType;\nuse crate::fmt::display;\nuse crate::kind::Trivial;\nuse crate::string::CxxString;\n#[cfg(feature = \"std\")]\nuse alloc::string::String;\n#[cfg(feature = \"std\")]\nuse alloc::vec::Vec;\nuse core::cmp::Ordering;\nuse core::ffi::c_void;\nuse core::fmt::{self, Debug, Display};\nuse core::hash::{Hash, Hasher};\nuse core::marker::PhantomData;\nuse core::mem::{self, MaybeUninit};\nuse core::ops::{Deref, DerefMut};\nuse core::pin::Pin;\n#[cfg(feature = \"std\")]\nuse std::io::{self, IoSlice, Read, Seek, SeekFrom, Write};\n\n/// Binding to C++ `std::unique_ptr<T, std::default_delete<T>>`.\n#[repr(C)]\npub struct UniquePtr<T>\nwhere\n    T: UniquePtrTarget,\n{\n    repr: MaybeUninit<*mut c_void>,\n    ty: PhantomData<T>,\n}\n\nimpl<T> UniquePtr<T>\nwhere\n    T: UniquePtrTarget,\n{\n    /// Makes a new UniquePtr wrapping a null pointer.\n    ///\n    /// Matches the behavior of default-constructing a std::unique\\_ptr.\n    pub fn null() -> Self {\n        UniquePtr {\n            repr: T::__null(),\n            ty: PhantomData,\n        }\n    }\n\n    /// Allocates memory on the heap and makes a UniquePtr pointing to it.\n    pub fn new(value: T) -> Self\n    where\n        T: ExternType<Kind = Trivial>,\n    {\n        UniquePtr {\n            repr: T::__new(value),\n            ty: PhantomData,\n        }\n    }\n\n    /// Checks whether the UniquePtr does not own an object.\n    ///\n    /// This is the opposite of [std::unique_ptr\\<T\\>::operator bool](https://en.cppreference.com/w/cpp/memory/unique_ptr/operator_bool).\n    pub fn is_null(&self) -> bool {\n        self.as_ptr().is_null()\n    }\n\n    /// Returns a reference to the object owned by this UniquePtr if any,\n    /// otherwise None.\n    pub fn as_ref(&self) -> Option<&T> {\n        let ptr = self.as_ptr();\n        unsafe { ptr.as_ref() }\n    }\n\n    /// Returns a mutable pinned reference to the object owned by this UniquePtr\n    /// if any, otherwise None.\n    pub fn as_mut(&mut self) -> Option<Pin<&mut T>> {\n        let ptr = self.as_mut_ptr();\n        unsafe {\n            let mut_reference = ptr.as_mut()?;\n            Some(Pin::new_unchecked(mut_reference))\n        }\n    }\n\n    /// Returns a mutable pinned reference to the object owned by this\n    /// UniquePtr.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the UniquePtr holds a null pointer.\n    pub fn pin_mut(&mut self) -> Pin<&mut T> {\n        match self.as_mut() {\n            Some(target) => target,\n            None => panic!(\n                \"called pin_mut on a null UniquePtr<{}>\",\n                display(T::__typename),\n            ),\n        }\n    }\n\n    /// Returns a raw const pointer to the object owned by this UniquePtr if\n    /// any, otherwise the null pointer.\n    pub fn as_ptr(&self) -> *const T {\n        unsafe { T::__get(self.repr) }\n    }\n\n    /// Returns a raw mutable pointer to the object owned by this UniquePtr if\n    /// any, otherwise the null pointer.\n    ///\n    /// As with [std::unique_ptr\\<T\\>::get](https://en.cppreference.com/w/cpp/memory/unique_ptr/get),\n    /// this doesn't require that you hold an exclusive reference to the\n    /// UniquePtr. This differs from Rust norms, so extra care should be taken\n    /// in the way the pointer is used.\n    pub fn as_mut_ptr(&self) -> *mut T {\n        self.as_ptr().cast_mut()\n    }\n\n    /// Consumes the UniquePtr, releasing its ownership of the heap-allocated T.\n    ///\n    /// Matches the behavior of [std::unique_ptr\\<T\\>::release](https://en.cppreference.com/w/cpp/memory/unique_ptr/release).\n    pub fn into_raw(self) -> *mut T {\n        let ptr = unsafe { T::__release(self.repr) };\n        mem::forget(self);\n        ptr\n    }\n\n    /// Constructs a UniquePtr retaking ownership of a pointer previously\n    /// obtained from `into_raw`.\n    ///\n    /// # Safety\n    ///\n    /// This function is unsafe because improper use may lead to memory\n    /// problems. For example a double-free may occur if the function is called\n    /// twice on the same raw pointer.\n    pub unsafe fn from_raw(raw: *mut T) -> Self {\n        UniquePtr {\n            repr: unsafe { T::__raw(raw) },\n            ty: PhantomData,\n        }\n    }\n}\n\nunsafe impl<T> Send for UniquePtr<T> where T: Send + UniquePtrTarget {}\nunsafe impl<T> Sync for UniquePtr<T> where T: Sync + UniquePtrTarget {}\n\n// UniquePtr is not a self-referential type and is safe to move out of a Pin,\n// regardless whether the pointer's target is Unpin.\nimpl<T> Unpin for UniquePtr<T> where T: UniquePtrTarget {}\n\nimpl<T> Drop for UniquePtr<T>\nwhere\n    T: UniquePtrTarget,\n{\n    fn drop(&mut self) {\n        unsafe { T::__drop(self.repr) }\n    }\n}\n\nimpl<T> Deref for UniquePtr<T>\nwhere\n    T: UniquePtrTarget,\n{\n    type Target = T;\n\n    fn deref(&self) -> &Self::Target {\n        match self.as_ref() {\n            Some(target) => target,\n            None => panic!(\n                \"called deref on a null UniquePtr<{}>\",\n                display(T::__typename),\n            ),\n        }\n    }\n}\n\nimpl<T> DerefMut for UniquePtr<T>\nwhere\n    T: UniquePtrTarget + Unpin,\n{\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        match self.as_mut() {\n            Some(target) => Pin::into_inner(target),\n            None => panic!(\n                \"called deref_mut on a null UniquePtr<{}>\",\n                display(T::__typename),\n            ),\n        }\n    }\n}\n\nimpl<T> Debug for UniquePtr<T>\nwhere\n    T: Debug + UniquePtrTarget,\n{\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        match self.as_ref() {\n            None => formatter.write_str(\"nullptr\"),\n            Some(value) => Debug::fmt(value, formatter),\n        }\n    }\n}\n\nimpl<T> Display for UniquePtr<T>\nwhere\n    T: Display + UniquePtrTarget,\n{\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        match self.as_ref() {\n            None => formatter.write_str(\"nullptr\"),\n            Some(value) => Display::fmt(value, formatter),\n        }\n    }\n}\n\nimpl<T> PartialEq for UniquePtr<T>\nwhere\n    T: PartialEq + UniquePtrTarget,\n{\n    fn eq(&self, other: &Self) -> bool {\n        self.as_ref() == other.as_ref()\n    }\n}\n\nimpl<T> Eq for UniquePtr<T> where T: Eq + UniquePtrTarget {}\n\nimpl<T> PartialOrd for UniquePtr<T>\nwhere\n    T: PartialOrd + UniquePtrTarget,\n{\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        PartialOrd::partial_cmp(&self.as_ref(), &other.as_ref())\n    }\n}\n\nimpl<T> Ord for UniquePtr<T>\nwhere\n    T: Ord + UniquePtrTarget,\n{\n    fn cmp(&self, other: &Self) -> Ordering {\n        Ord::cmp(&self.as_ref(), &other.as_ref())\n    }\n}\n\nimpl<T> Hash for UniquePtr<T>\nwhere\n    T: Hash + UniquePtrTarget,\n{\n    fn hash<H>(&self, hasher: &mut H)\n    where\n        H: Hasher,\n    {\n        self.as_ref().hash(hasher);\n    }\n}\n\n/// Forwarding `Read` trait implementation in a manner similar to `Box<T>`.\n///\n/// Note that the implementation will panic for null `UniquePtr<T>`.\n#[cfg(feature = \"std\")]\nimpl<T> Read for UniquePtr<T>\nwhere\n    for<'a> Pin<&'a mut T>: Read,\n    T: UniquePtrTarget,\n{\n    #[inline]\n    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {\n        self.pin_mut().read(buf)\n    }\n\n    #[inline]\n    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {\n        self.pin_mut().read_to_end(buf)\n    }\n\n    #[inline]\n    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {\n        self.pin_mut().read_to_string(buf)\n    }\n\n    #[inline]\n    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {\n        self.pin_mut().read_exact(buf)\n    }\n\n    // TODO: Foward other `Read` trait methods when they get stabilized (e.g.\n    // `read_buf` and/or `is_read_vectored`).\n}\n\n/// Forwarding `Seek` trait implementation in a manner similar to `Box<T>`.\n///\n/// Note that the implementation will panic for null `UniquePtr<T>`.\n#[cfg(feature = \"std\")]\nimpl<T> Seek for UniquePtr<T>\nwhere\n    for<'a> Pin<&'a mut T>: Seek,\n    T: UniquePtrTarget,\n{\n    #[inline]\n    fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {\n        self.pin_mut().seek(pos)\n    }\n\n    #[inline]\n    fn rewind(&mut self) -> io::Result<()> {\n        self.pin_mut().rewind()\n    }\n\n    #[inline]\n    fn stream_position(&mut self) -> io::Result<u64> {\n        self.pin_mut().stream_position()\n    }\n\n    #[inline]\n    fn seek_relative(&mut self, offset: i64) -> io::Result<()> {\n        self.pin_mut().seek_relative(offset)\n    }\n\n    // TODO: Foward other `Seek` trait methods if/when possible:\n    // * `stream_len`: If/when stabilized\n}\n\n/// Forwarding `Write` trait implementation in a manner similar to `Box<T>`.\n///\n/// Note that the implementation will panic for null `UniquePtr<T>`.\n#[cfg(feature = \"std\")]\nimpl<T> Write for UniquePtr<T>\nwhere\n    for<'a> Pin<&'a mut T>: Write,\n    T: UniquePtrTarget,\n{\n    #[inline]\n    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n        self.pin_mut().write(buf)\n    }\n\n    #[inline]\n    fn write_vectored(&mut self, bufs: &[IoSlice]) -> io::Result<usize> {\n        self.pin_mut().write_vectored(bufs)\n    }\n\n    #[inline]\n    fn flush(&mut self) -> io::Result<()> {\n        self.pin_mut().flush()\n    }\n\n    #[inline]\n    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {\n        self.pin_mut().write_all(buf)\n    }\n\n    #[inline]\n    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {\n        self.pin_mut().write_fmt(fmt)\n    }\n\n    // TODO: Foward other `Write` trait methods when they get stabilized (e.g.\n    // `write_all_vectored` and/or `is_write_vectored`).\n}\n\n/// Trait bound for types which may be used as the `T` inside of a\n/// `UniquePtr<T>` in generic code.\n///\n/// This trait has no publicly callable or implementable methods. Implementing\n/// it outside of the CXX codebase is not supported.\n///\n/// # Example\n///\n/// A bound `T: UniquePtrTarget` may be necessary when manipulating\n/// [`UniquePtr`] in generic code.\n///\n/// ```\n/// use cxx::memory::{UniquePtr, UniquePtrTarget};\n/// use std::fmt::Display;\n///\n/// pub fn take_generic_ptr<T>(ptr: UniquePtr<T>)\n/// where\n///     T: UniquePtrTarget + Display,\n/// {\n///     println!(\"the unique_ptr points to: {}\", *ptr);\n/// }\n/// ```\n///\n/// Writing the same generic function without a `UniquePtrTarget` trait bound\n/// would not compile.\npub unsafe trait UniquePtrTarget {\n    #[doc(hidden)]\n    fn __typename(f: &mut fmt::Formatter) -> fmt::Result;\n    #[doc(hidden)]\n    fn __null() -> MaybeUninit<*mut c_void>;\n    #[doc(hidden)]\n    fn __new(value: Self) -> MaybeUninit<*mut c_void>\n    where\n        Self: Sized,\n    {\n        // Opaque C types do not get this method because they can never exist by\n        // value on the Rust side of the bridge.\n        let _ = value;\n        unreachable!()\n    }\n    #[doc(hidden)]\n    unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void>;\n    #[doc(hidden)]\n    unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self;\n    #[doc(hidden)]\n    unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self;\n    #[doc(hidden)]\n    unsafe fn __drop(repr: MaybeUninit<*mut c_void>);\n}\n\nextern \"C\" {\n    #[link_name = \"cxxbridge1$unique_ptr$std$string$null\"]\n    fn unique_ptr_std_string_null(this: *mut MaybeUninit<*mut c_void>);\n    #[link_name = \"cxxbridge1$unique_ptr$std$string$raw\"]\n    fn unique_ptr_std_string_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxString);\n    #[link_name = \"cxxbridge1$unique_ptr$std$string$get\"]\n    fn unique_ptr_std_string_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxString;\n    #[link_name = \"cxxbridge1$unique_ptr$std$string$release\"]\n    fn unique_ptr_std_string_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxString;\n    #[link_name = \"cxxbridge1$unique_ptr$std$string$drop\"]\n    fn unique_ptr_std_string_drop(this: *mut MaybeUninit<*mut c_void>);\n}\n\nunsafe impl UniquePtrTarget for CxxString {\n    fn __typename(f: &mut fmt::Formatter) -> fmt::Result {\n        f.write_str(\"CxxString\")\n    }\n    fn __null() -> MaybeUninit<*mut c_void> {\n        let mut repr = MaybeUninit::uninit();\n        unsafe {\n            unique_ptr_std_string_null(&raw mut repr);\n        }\n        repr\n    }\n    unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {\n        let mut repr = MaybeUninit::uninit();\n        unsafe { unique_ptr_std_string_raw(&raw mut repr, raw) }\n        repr\n    }\n    unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {\n        unsafe { unique_ptr_std_string_get(&raw const repr) }\n    }\n    unsafe fn __release(mut repr: MaybeUninit<*mut c_void>) -> *mut Self {\n        unsafe { unique_ptr_std_string_release(&raw mut repr) }\n    }\n    unsafe fn __drop(mut repr: MaybeUninit<*mut c_void>) {\n        unsafe { unique_ptr_std_string_drop(&raw mut repr) }\n    }\n}\n\nunsafe impl<T> UniquePtrTarget for CxxVector<T>\nwhere\n    T: VectorElement,\n{\n    fn __typename(f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"CxxVector<{}>\", display(T::__typename))\n    }\n    fn __null() -> MaybeUninit<*mut c_void> {\n        T::__unique_ptr_null()\n    }\n    unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {\n        unsafe { T::__unique_ptr_raw(raw) }\n    }\n    unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {\n        unsafe { T::__unique_ptr_get(repr) }\n    }\n    unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self {\n        unsafe { T::__unique_ptr_release(repr) }\n    }\n    unsafe fn __drop(repr: MaybeUninit<*mut c_void>) {\n        unsafe { T::__unique_ptr_drop(repr) }\n    }\n}\n"
  },
  {
    "path": "src/unwind.rs",
    "content": "#![allow(missing_docs)]\n\nuse core::mem;\n\npub fn prevent_unwind<F, R>(label: &'static str, foreign_call: F) -> R\nwhere\n    F: FnOnce() -> R,\n{\n    // Goal is to make it impossible to propagate a panic across the C interface\n    // of an extern \"Rust\" function, which would be Undefined Behavior. We\n    // transform such panicks into a deterministic abort instead. When cxx is\n    // built in an application using panic=abort, this guard object is compiled\n    // out because its destructor is statically unreachable. When built with\n    // panic=unwind, an unwind from the foreign call will attempt to drop the\n    // guard object leading to a double panic, which is defined by Rust to\n    // abort. In no_std programs, on most platforms the current mechanism for\n    // this is for core::intrinsics::abort to invoke an invalid instruction. On\n    // Unix, the process will probably terminate with a signal like SIGABRT,\n    // SIGILL, SIGTRAP, SIGSEGV or SIGBUS. The precise behaviour is not\n    // guaranteed and not stable, but is safe.\n    let guard = Guard { label };\n\n    let ret = foreign_call();\n\n    // If we made it here, no uncaught panic occurred during the foreign call.\n    mem::forget(guard);\n    ret\n}\n\nstruct Guard {\n    label: &'static str,\n}\n\nimpl Drop for Guard {\n    #[cold]\n    fn drop(&mut self) {\n        panic!(\"panic in ffi function {}, aborting.\", self.label);\n    }\n}\n"
  },
  {
    "path": "src/vector.rs",
    "content": "//! Less used details of `CxxVector`.\n//!\n//! `CxxVector` itself is exposed at the crate root.\n\npub use crate::cxx_vector::{Iter, IterMut, VectorElement};\n#[doc(inline)]\npub use crate::Vector;\n#[doc(no_inline)]\npub use cxx::CxxVector;\n"
  },
  {
    "path": "src/weak_ptr.rs",
    "content": "use crate::shared_ptr::{SharedPtr, SharedPtrTarget};\nuse crate::string::CxxString;\nuse core::ffi::c_void;\nuse core::fmt::{self, Debug};\nuse core::marker::PhantomData;\nuse core::mem::MaybeUninit;\nuse core::ptr;\n\n/// Binding to C++ `std::weak_ptr<T>`.\n///\n/// The typical way to construct a WeakPtr from Rust is by [downgrading] from a\n/// SharedPtr.\n///\n/// [downgrading]: crate::SharedPtr::downgrade\n#[repr(C)]\npub struct WeakPtr<T>\nwhere\n    T: WeakPtrTarget,\n{\n    repr: [MaybeUninit<*mut c_void>; 2],\n    ty: PhantomData<T>,\n}\n\nimpl<T> WeakPtr<T>\nwhere\n    T: WeakPtrTarget,\n{\n    /// Makes a new WeakPtr wrapping a null pointer.\n    ///\n    /// Matches the behavior of default-constructing a std::weak\\_ptr.\n    pub fn null() -> Self {\n        let mut weak_ptr = MaybeUninit::<WeakPtr<T>>::uninit();\n        let new = weak_ptr.as_mut_ptr().cast();\n        unsafe {\n            T::__null(new);\n            weak_ptr.assume_init()\n        }\n    }\n\n    /// Upgrades a non-owning reference into an owning reference if possible,\n    /// otherwise to a null reference.\n    ///\n    /// Matches the behavior of [std::weak_ptr\\<T\\>::lock](https://en.cppreference.com/w/cpp/memory/weak_ptr/lock).\n    pub fn upgrade(&self) -> SharedPtr<T>\n    where\n        T: SharedPtrTarget,\n    {\n        let this = ptr::from_ref::<Self>(self).cast::<c_void>();\n        let mut shared_ptr = MaybeUninit::<SharedPtr<T>>::uninit();\n        let new = shared_ptr.as_mut_ptr().cast();\n        unsafe {\n            T::__upgrade(this, new);\n            shared_ptr.assume_init()\n        }\n    }\n}\n\nunsafe impl<T> Send for WeakPtr<T> where T: Send + Sync + WeakPtrTarget {}\nunsafe impl<T> Sync for WeakPtr<T> where T: Send + Sync + WeakPtrTarget {}\n\nimpl<T> Clone for WeakPtr<T>\nwhere\n    T: WeakPtrTarget,\n{\n    fn clone(&self) -> Self {\n        let mut weak_ptr = MaybeUninit::<WeakPtr<T>>::uninit();\n        let new = weak_ptr.as_mut_ptr().cast();\n        let this = ptr::from_ref::<Self>(self).cast::<c_void>();\n        unsafe {\n            T::__clone(this, new);\n            weak_ptr.assume_init()\n        }\n    }\n}\n\nimpl<T> Drop for WeakPtr<T>\nwhere\n    T: WeakPtrTarget,\n{\n    fn drop(&mut self) {\n        let this = ptr::from_mut::<Self>(self).cast::<c_void>();\n        unsafe { T::__drop(this) }\n    }\n}\n\nimpl<T> Debug for WeakPtr<T>\nwhere\n    T: Debug + WeakPtrTarget + SharedPtrTarget,\n{\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        Debug::fmt(&self.upgrade(), formatter)\n    }\n}\n\n/// Trait bound for types which may be used as the `T` inside of a `WeakPtr<T>`\n/// in generic code.\n///\n/// This trait has no publicly callable or implementable methods. Implementing\n/// it outside of the CXX codebase is not supported.\npub unsafe trait WeakPtrTarget {\n    #[doc(hidden)]\n    fn __typename(f: &mut fmt::Formatter) -> fmt::Result;\n    #[doc(hidden)]\n    unsafe fn __null(new: *mut c_void);\n    #[doc(hidden)]\n    unsafe fn __clone(this: *const c_void, new: *mut c_void);\n    #[doc(hidden)]\n    unsafe fn __downgrade(shared: *const c_void, new: *mut c_void);\n    #[doc(hidden)]\n    unsafe fn __upgrade(weak: *const c_void, shared: *mut c_void);\n    #[doc(hidden)]\n    unsafe fn __drop(this: *mut c_void);\n}\n\nmacro_rules! impl_weak_ptr_target {\n    ($segment:expr, $name:expr, $ty:ty) => {\n        unsafe impl WeakPtrTarget for $ty {\n            fn __typename(f: &mut fmt::Formatter) -> fmt::Result {\n                f.write_str($name)\n            }\n            unsafe fn __null(new: *mut c_void) {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$weak_ptr$\", $segment, \"$null\")]\n                    fn __null(new: *mut c_void);\n                }\n                unsafe { __null(new) }\n            }\n            unsafe fn __clone(this: *const c_void, new: *mut c_void) {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$weak_ptr$\", $segment, \"$clone\")]\n                    fn __clone(this: *const c_void, new: *mut c_void);\n                }\n                unsafe { __clone(this, new) }\n            }\n            unsafe fn __downgrade(shared: *const c_void, weak: *mut c_void) {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$weak_ptr$\", $segment, \"$downgrade\")]\n                    fn __downgrade(shared: *const c_void, weak: *mut c_void);\n                }\n                unsafe { __downgrade(shared, weak) }\n            }\n            unsafe fn __upgrade(weak: *const c_void, shared: *mut c_void) {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$weak_ptr$\", $segment, \"$upgrade\")]\n                    fn __upgrade(weak: *const c_void, shared: *mut c_void);\n                }\n                unsafe { __upgrade(weak, shared) }\n            }\n            unsafe fn __drop(this: *mut c_void) {\n                extern \"C\" {\n                    #[link_name = concat!(\"cxxbridge1$std$weak_ptr$\", $segment, \"$drop\")]\n                    fn __drop(this: *mut c_void);\n                }\n                unsafe { __drop(this) }\n            }\n        }\n    };\n}\n\nmacro_rules! impl_weak_ptr_target_for_primitive {\n    ($ty:ident) => {\n        impl_weak_ptr_target!(stringify!($ty), stringify!($ty), $ty);\n    };\n}\n\nimpl_weak_ptr_target_for_primitive!(bool);\nimpl_weak_ptr_target_for_primitive!(u8);\nimpl_weak_ptr_target_for_primitive!(u16);\nimpl_weak_ptr_target_for_primitive!(u32);\nimpl_weak_ptr_target_for_primitive!(u64);\nimpl_weak_ptr_target_for_primitive!(usize);\nimpl_weak_ptr_target_for_primitive!(i8);\nimpl_weak_ptr_target_for_primitive!(i16);\nimpl_weak_ptr_target_for_primitive!(i32);\nimpl_weak_ptr_target_for_primitive!(i64);\nimpl_weak_ptr_target_for_primitive!(isize);\nimpl_weak_ptr_target_for_primitive!(f32);\nimpl_weak_ptr_target_for_primitive!(f64);\n\nimpl_weak_ptr_target!(\"string\", \"CxxString\", CxxString);\n"
  },
  {
    "path": "syntax/atom.rs",
    "content": "use crate::syntax::Type;\nuse proc_macro2::Ident;\nuse std::fmt::{self, Display};\n\n#[derive(Copy, Clone, PartialEq)]\npub(crate) enum Atom {\n    Bool,\n    Char, // C char, not Rust char\n    U8,\n    U16,\n    U32,\n    U64,\n    Usize,\n    I8,\n    I16,\n    I32,\n    I64,\n    Isize,\n    F32,\n    F64,\n    CxxString,\n    RustString,\n}\n\nimpl Atom {\n    pub(crate) fn from(ident: &Ident) -> Option<Self> {\n        Self::from_str(ident.to_string().as_str())\n    }\n\n    pub(crate) fn from_str(s: &str) -> Option<Self> {\n        use self::Atom::*;\n        match s {\n            \"bool\" => Some(Bool),\n            \"c_char\" => Some(Char),\n            \"u8\" => Some(U8),\n            \"u16\" => Some(U16),\n            \"u32\" => Some(U32),\n            \"u64\" => Some(U64),\n            \"usize\" => Some(Usize),\n            \"i8\" => Some(I8),\n            \"i16\" => Some(I16),\n            \"i32\" => Some(I32),\n            \"i64\" => Some(I64),\n            \"isize\" => Some(Isize),\n            \"f32\" => Some(F32),\n            \"f64\" => Some(F64),\n            \"CxxString\" => Some(CxxString),\n            \"String\" => Some(RustString),\n            _ => None,\n        }\n    }\n}\n\nimpl Display for Atom {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        formatter.write_str(self.as_ref())\n    }\n}\n\nimpl AsRef<str> for Atom {\n    fn as_ref(&self) -> &str {\n        use self::Atom::*;\n        match self {\n            Bool => \"bool\",\n            Char => \"c_char\",\n            U8 => \"u8\",\n            U16 => \"u16\",\n            U32 => \"u32\",\n            U64 => \"u64\",\n            Usize => \"usize\",\n            I8 => \"i8\",\n            I16 => \"i16\",\n            I32 => \"i32\",\n            I64 => \"i64\",\n            Isize => \"isize\",\n            F32 => \"f32\",\n            F64 => \"f64\",\n            CxxString => \"CxxString\",\n            RustString => \"String\",\n        }\n    }\n}\n\nimpl PartialEq<Atom> for Type {\n    fn eq(&self, atom: &Atom) -> bool {\n        match self {\n            Type::Ident(ident) => ident.rust == atom,\n            _ => false,\n        }\n    }\n}\n\nimpl PartialEq<Atom> for &Ident {\n    fn eq(&self, atom: &Atom) -> bool {\n        *self == atom\n    }\n}\n\nimpl PartialEq<Atom> for &Type {\n    fn eq(&self, atom: &Atom) -> bool {\n        *self == atom\n    }\n}\n"
  },
  {
    "path": "syntax/attrs.rs",
    "content": "use crate::syntax::cfg::CfgExpr;\nuse crate::syntax::namespace::Namespace;\nuse crate::syntax::report::Errors;\nuse crate::syntax::repr::Repr;\nuse crate::syntax::{cfg, Derive, Doc, ForeignName};\nuse proc_macro2::Ident;\nuse syn::parse::ParseStream;\nuse syn::{Attribute, Error, Expr, Lit, LitStr, Meta, Path, Result, Token};\n\n// Intended usage:\n//\n//     let mut doc = Doc::new();\n//     let mut cxx_name = None;\n//     let mut rust_name = None;\n//     /* ... */\n//     let attrs = attrs::parse(\n//         cx,\n//         item.attrs,\n//         attrs::Parser {\n//             doc: Some(&mut doc),\n//             cxx_name: Some(&mut cxx_name),\n//             rust_name: Some(&mut rust_name),\n//             /* ... */\n//             ..Default::default()\n//         },\n//     );\n//\n#[derive(Default)]\npub(crate) struct Parser<'a> {\n    pub cfg: Option<&'a mut CfgExpr>,\n    pub doc: Option<&'a mut Doc>,\n    pub derives: Option<&'a mut Vec<Derive>>,\n    pub repr: Option<&'a mut Option<Repr>>,\n    pub default: Option<&'a mut bool>,\n    pub namespace: Option<&'a mut Namespace>,\n    pub cxx_name: Option<&'a mut Option<ForeignName>>,\n    pub rust_name: Option<&'a mut Option<Ident>>,\n    pub self_type: Option<&'a mut Option<Ident>>,\n    pub ignore_unrecognized: bool,\n\n    // Suppress clippy needless_update lint (\"struct update has no effect, all\n    // the fields in the struct have already been specified\") when preemptively\n    // writing `..Default::default()`.\n    pub(crate) _more: (),\n}\n\n#[must_use]\npub(crate) fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser) -> OtherAttrs {\n    let mut other_attrs = OtherAttrs::new();\n    for attr in attrs {\n        let attr_path = attr.path();\n        if attr_path.is_ident(\"doc\") {\n            match parse_doc_attribute(&attr.meta) {\n                Ok(attr) => {\n                    if let Some(doc) = &mut parser.doc {\n                        match attr {\n                            DocAttribute::Doc(lit) => doc.push(lit),\n                            DocAttribute::Hidden => doc.hidden = true,\n                        }\n                        continue;\n                    }\n                }\n                Err(err) => {\n                    cx.push(err);\n                    break;\n                }\n            }\n        } else if attr_path.is_ident(\"derive\") {\n            match attr.parse_args_with(|attr: ParseStream| parse_derive_attribute(cx, attr)) {\n                Ok(attr) => {\n                    if let Some(derives) = &mut parser.derives {\n                        derives.extend(attr);\n                        continue;\n                    }\n                }\n                Err(err) => {\n                    cx.push(err);\n                    break;\n                }\n            }\n        } else if attr_path.is_ident(\"repr\") {\n            match attr.parse_args::<Repr>() {\n                Ok(attr) => {\n                    if let Some(repr) = &mut parser.repr {\n                        **repr = Some(attr);\n                        continue;\n                    }\n                }\n                Err(err) => {\n                    cx.push(err);\n                    break;\n                }\n            }\n        } else if attr_path.is_ident(\"default\") {\n            match parse_default_attribute(&attr.meta) {\n                Ok(()) => {\n                    if let Some(default) = &mut parser.default {\n                        **default = true;\n                        continue;\n                    }\n                }\n                Err(err) => {\n                    cx.push(err);\n                    break;\n                }\n            }\n        } else if attr_path.is_ident(\"namespace\") {\n            match Namespace::parse_meta(&attr.meta) {\n                Ok(attr) => {\n                    if let Some(namespace) = &mut parser.namespace {\n                        **namespace = attr;\n                        continue;\n                    }\n                }\n                Err(err) => {\n                    cx.push(err);\n                    break;\n                }\n            }\n        } else if attr_path.is_ident(\"cxx_name\") {\n            match parse_cxx_name_attribute(&attr.meta) {\n                Ok(attr) => {\n                    if let Some(cxx_name) = &mut parser.cxx_name {\n                        **cxx_name = Some(attr);\n                        continue;\n                    }\n                }\n                Err(err) => {\n                    cx.push(err);\n                    break;\n                }\n            }\n        } else if attr_path.is_ident(\"rust_name\") {\n            match parse_rust_ident_attribute(&attr.meta) {\n                Ok(attr) => {\n                    if let Some(rust_name) = &mut parser.rust_name {\n                        **rust_name = Some(attr);\n                        continue;\n                    }\n                }\n                Err(err) => {\n                    cx.push(err);\n                    break;\n                }\n            }\n        } else if attr_path.is_ident(\"Self\") {\n            match parse_rust_ident_attribute(&attr.meta) {\n                Ok(attr) => {\n                    if let Some(self_type) = &mut parser.self_type {\n                        **self_type = Some(attr);\n                        continue;\n                    }\n                }\n                Err(err) => {\n                    cx.push(err);\n                    break;\n                }\n            }\n        } else if attr_path.is_ident(\"cfg\") {\n            match cfg::parse_attribute(&attr) {\n                Ok(cfg_expr) => {\n                    if let Some(cfg) = &mut parser.cfg {\n                        cfg.merge_and(cfg_expr);\n                        other_attrs.cfg.push(attr);\n                        continue;\n                    }\n                }\n                Err(err) => {\n                    cx.push(err);\n                    break;\n                }\n            }\n        } else if attr_path.is_ident(\"allow\")\n            || attr_path.is_ident(\"warn\")\n            || attr_path.is_ident(\"deny\")\n            || attr_path.is_ident(\"forbid\")\n        {\n            other_attrs.lint.push(attr);\n            continue;\n        } else if attr_path.is_ident(\"deprecated\")\n            || attr_path.is_ident(\"must_use\")\n            || attr_path.is_ident(\"serde\")\n        {\n            other_attrs.passthrough.push(attr);\n            continue;\n        } else if attr_path.segments.len() > 1 {\n            let tool = &attr_path.segments.first().unwrap().ident;\n            if tool == \"rustfmt\" {\n                // Skip, rustfmt only needs to find it in the pre-expansion source file.\n                continue;\n            } else if tool == \"clippy\" {\n                other_attrs.lint.push(attr);\n                continue;\n            }\n        }\n        if !parser.ignore_unrecognized {\n            cx.error(attr, \"unsupported attribute\");\n            break;\n        }\n    }\n    other_attrs\n}\n\nenum DocAttribute {\n    Doc(LitStr),\n    Hidden,\n}\n\nmod kw {\n    syn::custom_keyword!(hidden);\n}\n\nfn parse_doc_attribute(meta: &Meta) -> Result<DocAttribute> {\n    match meta {\n        Meta::NameValue(meta) => {\n            if let Expr::Lit(expr) = &meta.value {\n                if let Lit::Str(lit) = &expr.lit {\n                    return Ok(DocAttribute::Doc(lit.clone()));\n                }\n            }\n        }\n        Meta::List(meta) => {\n            meta.parse_args::<kw::hidden>()?;\n            return Ok(DocAttribute::Hidden);\n        }\n        Meta::Path(_) => {}\n    }\n    Err(Error::new_spanned(meta, \"unsupported doc attribute\"))\n}\n\nfn parse_derive_attribute(cx: &mut Errors, input: ParseStream) -> Result<Vec<Derive>> {\n    let paths = input.parse_terminated(Path::parse_mod_style, Token![,])?;\n\n    let mut derives = Vec::new();\n    for path in paths {\n        if let Some(ident) = path.get_ident() {\n            if let Some(derive) = Derive::from(ident) {\n                derives.push(derive);\n                continue;\n            }\n        }\n        cx.error(path, \"unsupported derive\");\n    }\n    Ok(derives)\n}\n\nfn parse_default_attribute(meta: &Meta) -> Result<()> {\n    let error_span = match meta {\n        Meta::Path(_) => return Ok(()),\n        Meta::List(meta) => meta.delimiter.span().open(),\n        Meta::NameValue(meta) => meta.eq_token.span,\n    };\n    Err(Error::new(\n        error_span,\n        \"#[default] attribute does not accept an argument\",\n    ))\n}\n\nfn parse_cxx_name_attribute(meta: &Meta) -> Result<ForeignName> {\n    if let Meta::NameValue(meta) = meta {\n        match &meta.value {\n            Expr::Lit(expr) => {\n                if let Lit::Str(lit) = &expr.lit {\n                    return ForeignName::parse(&lit.value(), lit.span());\n                }\n            }\n            Expr::Path(expr) => {\n                if let Some(ident) = expr.path.get_ident() {\n                    return ForeignName::parse(&ident.to_string(), ident.span());\n                }\n            }\n            _ => {}\n        }\n    }\n    Err(Error::new_spanned(meta, \"unsupported cxx_name attribute\"))\n}\n\nfn parse_rust_ident_attribute(meta: &Meta) -> Result<Ident> {\n    if let Meta::NameValue(meta) = meta {\n        match &meta.value {\n            Expr::Lit(expr) => {\n                if let Lit::Str(lit) = &expr.lit {\n                    return lit.parse();\n                }\n            }\n            Expr::Path(expr) => {\n                if let Some(ident) = expr.path.get_ident() {\n                    return Ok(ident.clone());\n                }\n            }\n            _ => {}\n        }\n    }\n    Err(Error::new_spanned(\n        meta,\n        format!(\n            \"unsupported `{}` attribute\",\n            meta.path().get_ident().unwrap(),\n        ),\n    ))\n}\n\n#[derive(Clone)]\npub(crate) struct OtherAttrs {\n    pub cfg: Vec<Attribute>,\n    pub lint: Vec<Attribute>,\n    pub passthrough: Vec<Attribute>,\n}\n\nimpl OtherAttrs {\n    pub(crate) fn new() -> Self {\n        OtherAttrs {\n            cfg: Vec::new(),\n            lint: Vec::new(),\n            passthrough: Vec::new(),\n        }\n    }\n\n    pub(crate) fn extend(&mut self, other: Self) {\n        self.cfg.extend(other.cfg);\n        self.lint.extend(other.lint);\n        self.passthrough.extend(other.passthrough);\n    }\n}\n"
  },
  {
    "path": "syntax/cfg.rs",
    "content": "use indexmap::{indexset as set, IndexSet as Set};\nuse proc_macro2::Ident;\nuse std::hash::{Hash, Hasher};\nuse std::iter;\nuse std::mem;\nuse syn::parse::{Error, ParseStream, Result};\nuse syn::{parenthesized, token, Attribute, LitStr, Token};\n\n#[derive(Clone)]\npub(crate) enum CfgExpr {\n    Unconditional,\n    Eq(Ident, Option<LitStr>),\n    All(Vec<CfgExpr>),\n    Any(Vec<CfgExpr>),\n    Not(Box<CfgExpr>),\n}\n\n#[derive(Clone)]\npub(crate) enum ComputedCfg<'a> {\n    Leaf(&'a CfgExpr),\n    All(Set<&'a CfgExpr>),\n    Any(Set<ComputedCfg<'a>>),\n}\n\nimpl CfgExpr {\n    pub(crate) fn merge_and(&mut self, expr: CfgExpr) {\n        if let CfgExpr::Unconditional = self {\n            *self = expr;\n        } else if let CfgExpr::Unconditional = expr {\n            // drop\n        } else if let CfgExpr::All(list) = self {\n            list.push(expr);\n        } else {\n            let prev = mem::replace(self, CfgExpr::Unconditional);\n            *self = CfgExpr::All(vec![prev, expr]);\n        }\n    }\n}\n\nimpl<'a> ComputedCfg<'a> {\n    pub(crate) fn all(one: &'a CfgExpr, two: &'a CfgExpr) -> Self {\n        if let (cfg, CfgExpr::Unconditional) | (CfgExpr::Unconditional, cfg) = (one, two) {\n            ComputedCfg::Leaf(cfg)\n        } else if one == two {\n            ComputedCfg::Leaf(one)\n        } else {\n            ComputedCfg::All(set![one, two])\n        }\n    }\n\n    pub(crate) fn merge_or(&mut self, other: impl Into<ComputedCfg<'a>>) {\n        let other = other.into();\n        if let ComputedCfg::Leaf(CfgExpr::Unconditional) = self {\n            // drop\n        } else if let ComputedCfg::Leaf(CfgExpr::Unconditional) = other {\n            *self = other;\n        } else if *self == other {\n            // drop\n        } else if let ComputedCfg::Any(list) = self {\n            list.insert(other);\n        } else {\n            let prev = mem::replace(self, ComputedCfg::Any(Set::new()));\n            let ComputedCfg::Any(list) = self else {\n                unreachable!();\n            };\n            list.extend([prev, other]);\n        }\n    }\n}\n\nimpl<'a> From<&'a CfgExpr> for ComputedCfg<'a> {\n    fn from(cfg: &'a CfgExpr) -> Self {\n        ComputedCfg::Leaf(cfg)\n    }\n}\n\nimpl Eq for CfgExpr {}\n\nimpl PartialEq for CfgExpr {\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (CfgExpr::Unconditional, CfgExpr::Unconditional) => true,\n            (CfgExpr::Eq(this_ident, None), CfgExpr::Eq(other_ident, None)) => {\n                this_ident == other_ident\n            }\n            (\n                CfgExpr::Eq(this_ident, Some(this_value)),\n                CfgExpr::Eq(other_ident, Some(other_value)),\n            ) => {\n                this_ident == other_ident\n                    && this_value.token().to_string() == other_value.token().to_string()\n            }\n            (CfgExpr::All(this), CfgExpr::All(other))\n            | (CfgExpr::Any(this), CfgExpr::Any(other)) => this == other,\n            (CfgExpr::Not(this), CfgExpr::Not(other)) => this == other,\n            (_, _) => false,\n        }\n    }\n}\n\nimpl Hash for CfgExpr {\n    fn hash<H: Hasher>(&self, hasher: &mut H) {\n        mem::discriminant(self).hash(hasher);\n        match self {\n            CfgExpr::Unconditional => {}\n            CfgExpr::Eq(ident, value) => {\n                ident.hash(hasher);\n                // syn::LitStr does not have its own Hash impl\n                value.as_ref().map(LitStr::value).hash(hasher);\n            }\n            CfgExpr::All(inner) | CfgExpr::Any(inner) => inner.hash(hasher),\n            CfgExpr::Not(inner) => inner.hash(hasher),\n        }\n    }\n}\n\nimpl<'a> Eq for ComputedCfg<'a> {}\n\nimpl<'a> PartialEq for ComputedCfg<'a> {\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (ComputedCfg::Leaf(this), ComputedCfg::Leaf(other)) => this == other,\n            // For the purpose of deduplicating the contents of an `all` or\n            // `any`, we only consider sets equal if they contain the same cfgs\n            // in the same order.\n            (ComputedCfg::All(this), ComputedCfg::All(other)) => {\n                this.len() == other.len()\n                    && iter::zip(this, other).all(|(this, other)| this == other)\n            }\n            (ComputedCfg::Any(this), ComputedCfg::Any(other)) => {\n                this.len() == other.len()\n                    && iter::zip(this, other).all(|(this, other)| this == other)\n            }\n            (_, _) => false,\n        }\n    }\n}\n\nimpl<'a> Hash for ComputedCfg<'a> {\n    fn hash<H: Hasher>(&self, hasher: &mut H) {\n        mem::discriminant(self).hash(hasher);\n        match self {\n            ComputedCfg::Leaf(cfg) => cfg.hash(hasher),\n            ComputedCfg::All(inner) => inner.iter().for_each(|cfg| cfg.hash(hasher)),\n            ComputedCfg::Any(inner) => inner.iter().for_each(|cfg| cfg.hash(hasher)),\n        }\n    }\n}\n\npub(crate) fn parse_attribute(attr: &Attribute) -> Result<CfgExpr> {\n    attr.parse_args_with(|input: ParseStream| {\n        let cfg_expr = input.call(parse_single)?;\n        input.parse::<Option<Token![,]>>()?;\n        Ok(cfg_expr)\n    })\n}\n\nfn parse_single(input: ParseStream) -> Result<CfgExpr> {\n    let ident: Ident = input.parse()?;\n    let lookahead = input.lookahead1();\n    if input.peek(token::Paren) {\n        let content;\n        parenthesized!(content in input);\n        if ident == \"all\" {\n            let list = content.call(parse_multiple)?;\n            Ok(CfgExpr::All(list))\n        } else if ident == \"any\" {\n            let list = content.call(parse_multiple)?;\n            Ok(CfgExpr::Any(list))\n        } else if ident == \"not\" {\n            let expr = content.call(parse_single)?;\n            content.parse::<Option<Token![,]>>()?;\n            Ok(CfgExpr::Not(Box::new(expr)))\n        } else {\n            Err(Error::new(ident.span(), \"unrecognized cfg expression\"))\n        }\n    } else if lookahead.peek(Token![=]) {\n        input.parse::<Token![=]>()?;\n        let string: LitStr = input.parse()?;\n        Ok(CfgExpr::Eq(ident, Some(string)))\n    } else if lookahead.peek(Token![,]) || input.is_empty() {\n        Ok(CfgExpr::Eq(ident, None))\n    } else {\n        Err(lookahead.error())\n    }\n}\n\nfn parse_multiple(input: ParseStream) -> Result<Vec<CfgExpr>> {\n    let mut vec = Vec::new();\n    while !input.is_empty() {\n        let expr = input.call(parse_single)?;\n        vec.push(expr);\n        if input.is_empty() {\n            break;\n        }\n        input.parse::<Token![,]>()?;\n    }\n    Ok(vec)\n}\n"
  },
  {
    "path": "syntax/check.rs",
    "content": "use crate::syntax::atom::Atom::{self, *};\nuse crate::syntax::message::Message;\nuse crate::syntax::report::Errors;\nuse crate::syntax::visit::{self, Visit};\nuse crate::syntax::{\n    error, ident, trivial, Api, Array, Enum, ExternFn, ExternType, FnKind, Impl, Lang, Lifetimes,\n    NamedType, Ptr, Receiver, Ref, Signature, SliceRef, Struct, Trait, Ty1, Type, TypeAlias, Types,\n};\nuse proc_macro2::{Delimiter, Group, Ident, TokenStream};\nuse quote::{quote, ToTokens};\nuse std::fmt::Display;\nuse syn::{GenericParam, Generics, Lifetime};\n\npub(crate) struct Check<'a> {\n    apis: &'a [Api],\n    types: &'a Types<'a>,\n    errors: &'a mut Errors,\n    generator: Generator,\n}\n\npub(crate) enum Generator {\n    // cxx-build crate, cxxbridge cli, cxx-gen.\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    Build,\n    // cxxbridge-macro. This is relevant in that the macro output is going to\n    // get fed straight to rustc, so for errors that rustc already contains\n    // logic to catch (probably with a better diagnostic than what the proc\n    // macro API is able to produce), we avoid duplicating them in our own\n    // diagnostics.\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    Macro,\n}\n\npub(crate) fn typecheck(cx: &mut Errors, apis: &[Api], types: &Types, generator: Generator) {\n    do_typecheck(&mut Check {\n        apis,\n        types,\n        errors: cx,\n        generator,\n    });\n}\n\nfn do_typecheck(cx: &mut Check) {\n    ident::check_all(cx, cx.apis);\n\n    for ty in cx.types {\n        match ty {\n            Type::Ident(ident) => check_type_ident(cx, ident),\n            Type::RustBox(ptr) => check_type_box(cx, ptr),\n            Type::RustVec(ty) => check_type_rust_vec(cx, ty),\n            Type::UniquePtr(ptr) => check_type_unique_ptr(cx, ptr),\n            Type::SharedPtr(ptr) => check_type_shared_ptr(cx, ptr),\n            Type::WeakPtr(ptr) => check_type_weak_ptr(cx, ptr),\n            Type::CxxVector(ptr) => check_type_cxx_vector(cx, ptr),\n            Type::Ref(ty) => check_type_ref(cx, ty),\n            Type::Ptr(ty) => check_type_ptr(cx, ty),\n            Type::Array(array) => check_type_array(cx, array),\n            Type::Fn(ty) => check_type_fn(cx, ty),\n            Type::SliceRef(ty) => check_type_slice_ref(cx, ty),\n            Type::Str(_) | Type::Void(_) => {}\n        }\n    }\n\n    for api in cx.apis {\n        match api {\n            Api::Include(_) => {}\n            Api::Struct(strct) => check_api_struct(cx, strct),\n            Api::Enum(enm) => check_api_enum(cx, enm),\n            Api::CxxType(ety) | Api::RustType(ety) => check_api_type(cx, ety),\n            Api::CxxFunction(efn) | Api::RustFunction(efn) => check_api_fn(cx, efn),\n            Api::TypeAlias(alias) => check_api_type_alias(cx, alias),\n            Api::Impl(imp) => check_api_impl(cx, imp),\n        }\n    }\n}\n\nimpl Check<'_> {\n    pub(crate) fn error(&mut self, sp: impl ToTokens, msg: impl Display) {\n        self.errors.error(sp, msg);\n    }\n}\n\nfn check_type_ident(cx: &mut Check, name: &NamedType) {\n    let ident = &name.rust;\n    if Atom::from(ident).is_none()\n        && !cx.types.structs.contains_key(ident)\n        && !cx.types.enums.contains_key(ident)\n        && !cx.types.cxx.contains(ident)\n        && !cx.types.rust.contains(ident)\n    {\n        let msg = format!(\"unsupported type: {}\", ident);\n        cx.error(ident, msg);\n    }\n}\n\nfn check_type_box(cx: &mut Check, ptr: &Ty1) {\n    if let Type::Ident(ident) = &ptr.inner {\n        if cx.types.cxx.contains(&ident.rust)\n            && !cx.types.aliases.contains_key(&ident.rust)\n            && !cx.types.structs.contains_key(&ident.rust)\n            && !cx.types.enums.contains_key(&ident.rust)\n        {\n            cx.error(ptr, error::BOX_CXX_TYPE.msg);\n        }\n\n        if Atom::from(&ident.rust).is_none() {\n            return;\n        }\n    }\n\n    cx.error(ptr, \"unsupported target type of Box\");\n}\n\nfn check_type_rust_vec(cx: &mut Check, ty: &Ty1) {\n    match &ty.inner {\n        Type::Ident(ident) => {\n            if cx.types.cxx.contains(&ident.rust)\n                && !cx.types.aliases.contains_key(&ident.rust)\n                && !cx.types.structs.contains_key(&ident.rust)\n                && !cx.types.enums.contains_key(&ident.rust)\n            {\n                cx.error(ty, \"Rust Vec containing C++ type is not supported yet\");\n                return;\n            }\n\n            match Atom::from(&ident.rust) {\n                None\n                | Some(\n                    Bool | Char | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32\n                    | F64 | RustString,\n                ) => return,\n                Some(CxxString) => {}\n            }\n        }\n        Type::Str(_) => return,\n        Type::RustBox(ty1) => {\n            check_type_box(cx, ty1);\n            return;\n        }\n        _ => {}\n    }\n\n    cx.error(ty, \"unsupported element type of Vec\");\n}\n\nfn check_type_unique_ptr(cx: &mut Check, ptr: &Ty1) {\n    if let Type::Ident(ident) = &ptr.inner {\n        if cx.types.rust.contains(&ident.rust) {\n            cx.error(ptr, \"unique_ptr of a Rust type is not supported yet\");\n            return;\n        }\n\n        match Atom::from(&ident.rust) {\n            None | Some(CxxString) => return,\n            _ => {}\n        }\n    } else if let Type::CxxVector(_) = &ptr.inner {\n        return;\n    }\n\n    cx.error(ptr, \"unsupported unique_ptr target type\");\n}\n\nfn check_type_shared_ptr(cx: &mut Check, ptr: &Ty1) {\n    if let Type::Ident(ident) = &ptr.inner {\n        if cx.types.rust.contains(&ident.rust) {\n            cx.error(ptr, \"shared_ptr of a Rust type is not supported yet\");\n            return;\n        }\n\n        match Atom::from(&ident.rust) {\n            None\n            | Some(\n                Bool | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32 | F64\n                | CxxString,\n            ) => return,\n            Some(Char | RustString) => {}\n        }\n    } else if let Type::CxxVector(_) = &ptr.inner {\n        cx.error(ptr, \"std::shared_ptr<std::vector> is not supported yet\");\n        return;\n    }\n\n    cx.error(ptr, \"unsupported shared_ptr target type\");\n}\n\nfn check_type_weak_ptr(cx: &mut Check, ptr: &Ty1) {\n    if let Type::Ident(ident) = &ptr.inner {\n        if cx.types.rust.contains(&ident.rust) {\n            cx.error(ptr, \"weak_ptr of a Rust type is not supported yet\");\n            return;\n        }\n\n        match Atom::from(&ident.rust) {\n            None\n            | Some(\n                Bool | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32 | F64\n                | CxxString,\n            ) => return,\n            Some(Char | RustString) => {}\n        }\n    } else if let Type::CxxVector(_) = &ptr.inner {\n        cx.error(ptr, \"std::weak_ptr<std::vector> is not supported yet\");\n        return;\n    }\n\n    cx.error(ptr, \"unsupported weak_ptr target type\");\n}\n\nfn check_type_cxx_vector(cx: &mut Check, ptr: &Ty1) {\n    if let Type::Ident(ident) = &ptr.inner {\n        if cx.types.rust.contains(&ident.rust) {\n            cx.error(\n                ptr,\n                \"C++ vector containing a Rust type is not supported yet\",\n            );\n            return;\n        }\n\n        match Atom::from(&ident.rust) {\n            None\n            | Some(\n                U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32 | F64 | CxxString,\n            ) => return,\n            Some(Char) => { /* todo */ }\n            Some(Bool | RustString) => {}\n        }\n    }\n\n    cx.error(ptr, \"unsupported vector element type\");\n}\n\nfn check_type_ref(cx: &mut Check, ty: &Ref) {\n    if ty.mutable && !ty.pinned {\n        if let Some(requires_pin) = match &ty.inner {\n            Type::Ident(ident)\n                if ident.rust == CxxString\n                    || (cx.types.cxx.contains(&ident.rust)\n                        && !cx.types.structs.contains_key(&ident.rust)\n                        && !cx.types.enums.contains_key(&ident.rust)\n                        && !cx.types.aliases.contains_key(&ident.rust)) =>\n            {\n                Some(ident.rust.to_string())\n            }\n            Type::CxxVector(_) => Some(\"CxxVector<...>\".to_owned()),\n            _ => None,\n        } {\n            cx.error(\n                ty,\n                format!(\n                    \"mutable reference to C++ type requires a pin -- use Pin<&mut {}>\",\n                    requires_pin,\n                ),\n            );\n        }\n    }\n\n    match ty.inner {\n        Type::Fn(_) | Type::Void(_) => {}\n        Type::Ref(_) => {\n            cx.error(ty, \"C++ does not allow references to references\");\n            return;\n        }\n        _ => return,\n    }\n\n    cx.error(ty, \"unsupported reference type\");\n}\n\nfn check_type_ptr(cx: &mut Check, ty: &Ptr) {\n    match ty.inner {\n        Type::Fn(_) | Type::Void(_) => {}\n        Type::Ref(_) => {\n            cx.error(ty, \"C++ does not allow pointer to reference as a type\");\n            return;\n        }\n        _ => return,\n    }\n\n    cx.error(ty, \"unsupported pointer type\");\n}\n\nfn check_type_slice_ref(cx: &mut Check, ty: &SliceRef) {\n    let supported = !is_unsized(cx.types, &ty.inner)\n        || match &ty.inner {\n            Type::Ident(ident) => {\n                cx.types.rust.contains(&ident.rust) || cx.types.aliases.contains_key(&ident.rust)\n            }\n            _ => false,\n        };\n\n    if !supported {\n        let mutable = if ty.mutable { \"mut \" } else { \"\" };\n        let mut msg = format!(\"unsupported &{}[T] element type\", mutable);\n        if let Type::Ident(ident) = &ty.inner {\n            if cx.types.cxx.contains(&ident.rust)\n                && !cx.types.structs.contains_key(&ident.rust)\n                && !cx.types.enums.contains_key(&ident.rust)\n            {\n                msg += \": opaque C++ type is not supported yet\";\n            }\n        }\n        cx.error(ty, msg);\n    }\n}\n\nfn check_type_array(cx: &mut Check, ty: &Array) {\n    let supported = !is_unsized(cx.types, &ty.inner);\n\n    if !supported {\n        cx.error(ty, \"unsupported array element type\");\n    }\n}\n\nfn check_type_fn(cx: &mut Check, ty: &Signature) {\n    if ty.throws {\n        cx.error(ty, \"function pointer returning Result is not supported yet\");\n    }\n\n    for arg in &ty.args {\n        if let Type::Ptr(_) = arg.ty {\n            if ty.unsafety.is_none() {\n                cx.error(\n                    arg,\n                    \"pointer argument requires that the function pointer be marked unsafe\",\n                );\n            }\n        }\n    }\n}\n\nfn check_api_struct(cx: &mut Check, strct: &Struct) {\n    let name = &strct.name;\n    check_reserved_name(cx, &name.rust);\n    check_lifetimes(cx, &strct.generics);\n\n    if strct.fields.is_empty() {\n        let span = span_for_struct_error(strct);\n        cx.error(span, \"structs without any fields are not supported\");\n    }\n\n    if cx.types.cxx.contains(&name.rust) {\n        if let Some(ety) = cx.types.untrusted.get(&name.rust) {\n            let msg = \"extern shared struct must be declared in an `unsafe extern` block\";\n            cx.error(ety, msg);\n        }\n    }\n\n    for derive in &strct.derives {\n        match derive.what {\n            Trait::Clone\n            | Trait::Copy\n            | Trait::Debug\n            | Trait::Default\n            | Trait::Eq\n            | Trait::Hash\n            | Trait::Ord\n            | Trait::PartialEq\n            | Trait::PartialOrd\n            | Trait::Serialize\n            | Trait::Deserialize => {}\n            Trait::BitAnd | Trait::BitOr | Trait::BitXor => {\n                let msg = format!(\n                    \"derive({}) is currently only supported on enums, not structs\",\n                    derive,\n                );\n                cx.error(derive, msg);\n            }\n            Trait::ExternType => {\n                let msg = format!(\"derive({}) on shared struct is not supported\", derive);\n                cx.error(derive, msg);\n            }\n        }\n    }\n\n    for field in &strct.fields {\n        if let Type::Fn(_) = field.ty {\n            cx.error(\n                field,\n                \"function pointers in a struct field are not implemented yet\",\n            );\n        } else if is_unsized(cx.types, &field.ty) {\n            let desc = describe(cx.types, &field.ty);\n            let msg = format!(\"using {} by value is not supported\", desc);\n            cx.error(field, msg);\n        }\n    }\n}\n\nfn check_api_enum(cx: &mut Check, enm: &Enum) {\n    check_reserved_name(cx, &enm.name.rust);\n    check_lifetimes(cx, &enm.generics);\n\n    if enm.variants.is_empty() && !enm.explicit_repr {\n        let span = span_for_enum_error(enm);\n        cx.error(\n            span,\n            \"explicit #[repr(...)] is required for enum without any variants\",\n        );\n    }\n\n    for derive in &enm.derives {\n        match derive.what {\n            Trait::BitAnd\n            | Trait::BitOr\n            | Trait::BitXor\n            | Trait::Clone\n            | Trait::Copy\n            | Trait::Debug\n            | Trait::Eq\n            | Trait::Hash\n            | Trait::Ord\n            | Trait::PartialEq\n            | Trait::PartialOrd\n            | Trait::Serialize\n            | Trait::Deserialize => {}\n            Trait::Default => {\n                let default_variants = enm.variants.iter().filter(|v| v.default).count();\n                if default_variants != 1 {\n                    let mut msg = Message::new();\n                    write!(msg, \"derive(Default) on enum requires exactly one variant to be marked with #[default]\");\n                    if default_variants > 0 {\n                        write!(msg, \" (found {})\", default_variants);\n                    }\n                    cx.error(derive, msg);\n                }\n            }\n            Trait::ExternType => {\n                let msg = \"derive(ExternType) on shared enum is not supported\";\n                cx.error(derive, msg);\n            }\n        }\n    }\n}\n\nfn check_api_type(cx: &mut Check, ety: &ExternType) {\n    check_reserved_name(cx, &ety.name.rust);\n    check_lifetimes(cx, &ety.generics);\n\n    for derive in &ety.derives {\n        if derive.what == Trait::ExternType && ety.lang == Lang::Rust {\n            continue;\n        }\n        let lang = match ety.lang {\n            Lang::Rust => \"Rust\",\n            Lang::Cxx | Lang::CxxUnwind => \"C++\",\n        };\n        let msg = format!(\n            \"derive({}) on opaque {} type is not supported yet\",\n            derive, lang,\n        );\n        cx.error(derive, msg);\n    }\n\n    if !ety.bounds.is_empty() {\n        let bounds = &ety.bounds;\n        let span = quote!(#(#bounds)*);\n        cx.error(span, \"extern type bounds are not implemented yet\");\n    }\n\n    if let Some(reasons) = cx.types.required_trivial.get(&ety.name.rust) {\n        let msg = format!(\n            \"needs a cxx::ExternType impl in order to be used as {}\",\n            trivial::as_what(&ety.name, reasons),\n        );\n        cx.error(ety, msg);\n    }\n}\n\nfn check_api_fn(cx: &mut Check, efn: &ExternFn) {\n    match efn.lang {\n        Lang::Cxx | Lang::CxxUnwind => {\n            if !efn.generics.params.is_empty() && !efn.trusted {\n                let ref span = span_for_generics_error(efn);\n                cx.error(span, \"extern C++ function with lifetimes must be declared in `unsafe extern \\\"C++\\\"` block\");\n            }\n        }\n        Lang::Rust => {\n            if !efn.generics.params.is_empty() && efn.unsafety.is_none() {\n                let ref span = span_for_generics_error(efn);\n                let message = format!(\n                    \"must be `unsafe fn {}` in order to expose explicit lifetimes to C++\",\n                    efn.name.rust,\n                );\n                cx.error(span, message);\n            }\n        }\n    }\n\n    check_generics(cx, &efn.generics);\n\n    match &efn.kind {\n        FnKind::Method(receiver) => {\n            let ref span = span_for_receiver_error(receiver);\n\n            if receiver.ty.rust == \"Self\" {\n                let mutability = match receiver.mutable {\n                    true => \"mut \",\n                    false => \"\",\n                };\n                let msg = format!(\n                    \"unnamed receiver type is only allowed if the surrounding extern block contains exactly one extern type; use `self: &{mutability}TheType`\",\n                    mutability = mutability,\n                );\n                cx.error(span, msg);\n            } else if cx.types.enums.contains_key(&receiver.ty.rust) {\n                cx.error(\n                    span,\n                    \"unsupported receiver type; C++ does not allow member functions on enums\",\n                );\n            } else if !cx.types.structs.contains_key(&receiver.ty.rust)\n                && !cx.types.cxx.contains(&receiver.ty.rust)\n                && !cx.types.rust.contains(&receiver.ty.rust)\n            {\n                cx.error(span, \"unrecognized receiver type\");\n            } else if receiver.mutable\n                && !receiver.pinned\n                && cx.types.cxx.contains(&receiver.ty.rust)\n                && !cx.types.structs.contains_key(&receiver.ty.rust)\n                && !cx.types.aliases.contains_key(&receiver.ty.rust)\n            {\n                cx.error(\n                    span,\n                    format!(\n                        \"mutable reference to opaque C++ type requires a pin -- use `self: Pin<&mut {}>`\",\n                        receiver.ty.rust,\n                    ),\n                );\n            }\n        }\n        FnKind::Assoc(self_type) => {\n            if cx.types.enums.contains_key(self_type) {\n                cx.error(\n                    self_type,\n                    \"unsupported self type; C++ does not allow member functions on enums\",\n                );\n            } else if !cx.types.structs.contains_key(self_type)\n                && !cx.types.cxx.contains(self_type)\n                && !cx.types.rust.contains(self_type)\n            {\n                cx.error(self_type, \"unrecognized self type\");\n            }\n        }\n        FnKind::Free => {}\n    }\n\n    for arg in &efn.args {\n        if let Type::Fn(_) = arg.ty {\n            if efn.lang == Lang::Rust {\n                cx.error(\n                    arg,\n                    \"passing a function pointer from C++ to Rust is not implemented yet\",\n                );\n            }\n        } else if let Type::Ptr(_) = arg.ty {\n            if efn.unsafety.is_none() {\n                cx.error(\n                    arg,\n                    \"pointer argument requires that the function be marked unsafe\",\n                );\n            }\n        } else if is_unsized(cx.types, &arg.ty) {\n            let desc = describe(cx.types, &arg.ty);\n            let msg = format!(\"passing {} by value is not supported\", desc);\n            cx.error(arg, msg);\n        }\n    }\n\n    if let Some(ty) = &efn.ret {\n        if let Type::Fn(_) = ty {\n            cx.error(ty, \"returning a function pointer is not implemented yet\");\n        } else if is_unsized(cx.types, ty) {\n            let desc = describe(cx.types, ty);\n            let msg = format!(\"returning {} by value is not supported\", desc);\n            cx.error(ty, msg);\n        }\n    }\n\n    if efn.lang == Lang::Cxx {\n        check_mut_return_restriction(cx, efn);\n    }\n}\n\nfn check_api_type_alias(cx: &mut Check, alias: &TypeAlias) {\n    check_lifetimes(cx, &alias.generics);\n\n    for derive in &alias.derives {\n        let msg = format!(\"derive({}) on extern type alias is not supported\", derive);\n        cx.error(derive, msg);\n    }\n}\n\nfn check_api_impl(cx: &mut Check, imp: &Impl) {\n    let ty = &imp.ty;\n\n    check_lifetimes(cx, &imp.impl_generics);\n\n    if let Some(negative) = imp.negative_token {\n        let span = quote!(#negative #ty);\n        cx.error(span, \"negative impl is not supported yet\");\n        return;\n    }\n\n    match ty {\n        Type::RustBox(ty)\n        | Type::RustVec(ty)\n        | Type::UniquePtr(ty)\n        | Type::SharedPtr(ty)\n        | Type::WeakPtr(ty)\n        | Type::CxxVector(ty) => {\n            if let Type::Ident(inner) = &ty.inner {\n                // Reject `impl Vec<u8>` and other built-in impls.\n                if Atom::from(&inner.rust).is_some() {\n                    cx.error(imp, \"unsupported Self type of explicit impl\");\n                }\n            }\n        }\n        // Reject `impl fn() -> &S {}`, `impl [S]`, etc.\n        _ => cx.error(imp, \"unsupported Self type of explicit impl\"),\n    }\n}\n\nfn check_mut_return_restriction(cx: &mut Check, efn: &ExternFn) {\n    if efn.unsafety.is_some() {\n        // Unrestricted as long as the function is made unsafe-to-call.\n        return;\n    }\n\n    match &efn.ret {\n        Some(Type::Ref(ty)) if ty.mutable => {}\n        Some(Type::SliceRef(slice)) if slice.mutable => {}\n        _ => return,\n    }\n\n    if let Some(receiver) = efn.receiver() {\n        if receiver.mutable {\n            return;\n        }\n        let Some(resolve) = cx.types.try_resolve(&receiver.ty) else {\n            return;\n        };\n        if !resolve.generics.lifetimes.is_empty() {\n            return;\n        }\n    }\n\n    struct FindLifetimeMut<'a> {\n        cx: &'a Check<'a>,\n        found: bool,\n    }\n\n    impl<'t, 'a> Visit<'t> for FindLifetimeMut<'a> {\n        fn visit_type(&mut self, ty: &'t Type) {\n            self.found |= match ty {\n                Type::Ref(ty) => ty.mutable,\n                Type::SliceRef(slice) => slice.mutable,\n                Type::Ident(ident) if Atom::from(&ident.rust).is_none() => {\n                    match self.cx.types.try_resolve(ident) {\n                        Some(resolve) => !resolve.generics.lifetimes.is_empty(),\n                        None => true,\n                    }\n                }\n                _ => false,\n            };\n            visit::visit_type(self, ty);\n        }\n    }\n\n    let mut visitor = FindLifetimeMut { cx, found: false };\n\n    for arg in &efn.args {\n        visitor.visit_type(&arg.ty);\n    }\n\n    if visitor.found {\n        return;\n    }\n\n    cx.error(\n        efn,\n        \"&mut return type is not allowed unless there is a &mut argument\",\n    );\n}\n\nfn check_reserved_name(cx: &mut Check, ident: &Ident) {\n    if ident == \"Box\"\n        || ident == \"UniquePtr\"\n        || ident == \"SharedPtr\"\n        || ident == \"WeakPtr\"\n        || ident == \"Vec\"\n        || ident == \"CxxVector\"\n        || ident == \"str\"\n        || Atom::from(ident).is_some()\n    {\n        cx.error(ident, \"reserved name\");\n    }\n}\n\nfn check_reserved_lifetime(cx: &mut Check, lifetime: &Lifetime) {\n    if lifetime.ident == \"static\" {\n        match cx.generator {\n            Generator::Macro => { /* rustc already reports this */ }\n            Generator::Build => {\n                cx.error(lifetime, error::RESERVED_LIFETIME);\n            }\n        }\n    }\n}\n\nfn check_lifetimes(cx: &mut Check, generics: &Lifetimes) {\n    for lifetime in &generics.lifetimes {\n        check_reserved_lifetime(cx, lifetime);\n    }\n}\n\nfn check_generics(cx: &mut Check, generics: &Generics) {\n    for generic_param in &generics.params {\n        if let GenericParam::Lifetime(def) = generic_param {\n            check_reserved_lifetime(cx, &def.lifetime);\n        }\n    }\n}\n\nfn is_unsized(types: &Types, ty: &Type) -> bool {\n    match ty {\n        Type::Ident(ident) => {\n            let ident = &ident.rust;\n            ident == CxxString\n                || (types.cxx.contains(ident)\n                    && !types.structs.contains_key(ident)\n                    && !types.enums.contains_key(ident)\n                    && !(types.aliases.contains_key(ident)\n                        && types.required_trivial.contains_key(ident)))\n                || types.rust.contains(ident)\n        }\n        Type::Array(array) => is_unsized(types, &array.inner),\n        Type::CxxVector(_) | Type::Fn(_) | Type::Void(_) => true,\n        Type::RustBox(_)\n        | Type::RustVec(_)\n        | Type::UniquePtr(_)\n        | Type::SharedPtr(_)\n        | Type::WeakPtr(_)\n        | Type::Ref(_)\n        | Type::Ptr(_)\n        | Type::Str(_)\n        | Type::SliceRef(_) => false,\n    }\n}\n\nfn span_for_struct_error(strct: &Struct) -> TokenStream {\n    let struct_token = strct.struct_token;\n    let mut brace_token = Group::new(Delimiter::Brace, TokenStream::new());\n    brace_token.set_span(strct.brace_token.span.join());\n    quote!(#struct_token #brace_token)\n}\n\nfn span_for_enum_error(enm: &Enum) -> TokenStream {\n    let enum_token = enm.enum_token;\n    let mut brace_token = Group::new(Delimiter::Brace, TokenStream::new());\n    brace_token.set_span(enm.brace_token.span.join());\n    quote!(#enum_token #brace_token)\n}\n\nfn span_for_receiver_error(receiver: &Receiver) -> TokenStream {\n    let ampersand = receiver.ampersand;\n    let lifetime = &receiver.lifetime;\n    let mutability = receiver.mutability;\n    if receiver.shorthand {\n        let var = receiver.var;\n        quote!(#ampersand #lifetime #mutability #var)\n    } else {\n        let ty = &receiver.ty;\n        quote!(#ampersand #lifetime #mutability #ty)\n    }\n}\n\nfn span_for_generics_error(efn: &ExternFn) -> TokenStream {\n    let unsafety = efn.unsafety;\n    let fn_token = efn.fn_token;\n    let generics = &efn.generics;\n    quote!(#unsafety #fn_token #generics)\n}\n\nfn describe(types: &Types, ty: &Type) -> String {\n    match ty {\n        Type::Ident(ident) => {\n            if types.structs.contains_key(&ident.rust) {\n                \"struct\".to_owned()\n            } else if types.enums.contains_key(&ident.rust) {\n                \"enum\".to_owned()\n            } else if types.aliases.contains_key(&ident.rust) {\n                \"C++ type\".to_owned()\n            } else if types.cxx.contains(&ident.rust) {\n                \"opaque C++ type\".to_owned()\n            } else if types.rust.contains(&ident.rust) {\n                \"opaque Rust type\".to_owned()\n            } else if Atom::from(&ident.rust) == Some(CxxString) {\n                \"C++ string\".to_owned()\n            } else if Atom::from(&ident.rust) == Some(Char) {\n                \"C char\".to_owned()\n            } else {\n                ident.rust.to_string()\n            }\n        }\n        Type::RustBox(_) => \"Box\".to_owned(),\n        Type::RustVec(_) => \"Vec\".to_owned(),\n        Type::UniquePtr(_) => \"unique_ptr\".to_owned(),\n        Type::SharedPtr(_) => \"shared_ptr\".to_owned(),\n        Type::WeakPtr(_) => \"weak_ptr\".to_owned(),\n        Type::Ref(_) => \"reference\".to_owned(),\n        Type::Ptr(_) => \"raw pointer\".to_owned(),\n        Type::Str(_) => \"&str\".to_owned(),\n        Type::CxxVector(_) => \"C++ vector\".to_owned(),\n        Type::SliceRef(_) => \"slice\".to_owned(),\n        Type::Fn(_) => \"function pointer\".to_owned(),\n        Type::Void(_) => \"()\".to_owned(),\n        Type::Array(_) => \"array\".to_owned(),\n    }\n}\n"
  },
  {
    "path": "syntax/derive.rs",
    "content": "use proc_macro2::{Ident, Span};\nuse std::fmt::{self, Display};\n\n#[derive(Copy, Clone)]\npub(crate) struct Derive {\n    pub what: Trait,\n    pub span: Span,\n}\n\n#[derive(Copy, Clone, PartialEq)]\npub(crate) enum Trait {\n    BitAnd,\n    BitOr,\n    BitXor,\n    Clone,\n    Copy,\n    Debug,\n    Default,\n    Eq,\n    ExternType,\n    Hash,\n    Ord,\n    PartialEq,\n    PartialOrd,\n    Serialize,\n    Deserialize,\n}\n\nimpl Derive {\n    pub(crate) fn from(ident: &Ident) -> Option<Self> {\n        let what = match ident.to_string().as_str() {\n            \"BitAnd\" => Trait::BitAnd,\n            \"BitOr\" => Trait::BitOr,\n            \"BitXor\" => Trait::BitXor,\n            \"Clone\" => Trait::Clone,\n            \"Copy\" => Trait::Copy,\n            \"Debug\" => Trait::Debug,\n            \"Default\" => Trait::Default,\n            \"Eq\" => Trait::Eq,\n            \"ExternType\" => Trait::ExternType,\n            \"Hash\" => Trait::Hash,\n            \"Ord\" => Trait::Ord,\n            \"PartialEq\" => Trait::PartialEq,\n            \"PartialOrd\" => Trait::PartialOrd,\n            \"Serialize\" => Trait::Serialize,\n            \"Deserialize\" => Trait::Deserialize,\n            _ => return None,\n        };\n        let span = ident.span();\n        Some(Derive { what, span })\n    }\n}\n\nimpl PartialEq<Trait> for Derive {\n    fn eq(&self, other: &Trait) -> bool {\n        self.what == *other\n    }\n}\n\nimpl AsRef<str> for Trait {\n    fn as_ref(&self) -> &str {\n        match self {\n            Trait::BitAnd => \"BitAnd\",\n            Trait::BitOr => \"BitOr\",\n            Trait::BitXor => \"BitXor\",\n            Trait::Clone => \"Clone\",\n            Trait::Copy => \"Copy\",\n            Trait::Debug => \"Debug\",\n            Trait::Default => \"Default\",\n            Trait::Eq => \"Eq\",\n            Trait::ExternType => \"ExternType\",\n            Trait::Hash => \"Hash\",\n            Trait::Ord => \"Ord\",\n            Trait::PartialEq => \"PartialEq\",\n            Trait::PartialOrd => \"PartialOrd\",\n            Trait::Serialize => \"Serialize\",\n            Trait::Deserialize => \"Deserialize\",\n        }\n    }\n}\n\nimpl Display for Derive {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        formatter.write_str(self.what.as_ref())\n    }\n}\n\npub(crate) fn contains(derives: &[Derive], query: Trait) -> bool {\n    derives.iter().any(|derive| derive.what == query)\n}\n"
  },
  {
    "path": "syntax/discriminant.rs",
    "content": "use crate::syntax::Atom::{self, *};\nuse proc_macro2::{Literal, Span, TokenStream};\nuse quote::ToTokens;\nuse std::cmp::Ordering;\nuse std::collections::BTreeSet;\nuse std::fmt::{self, Display};\nuse std::str::FromStr;\nuse syn::{Error, Expr, Lit, Result, Token, UnOp};\n\npub(crate) struct DiscriminantSet {\n    repr: Option<Atom>,\n    values: BTreeSet<Discriminant>,\n    previous: Option<Discriminant>,\n}\n\n#[derive(Copy, Clone, Eq, PartialEq)]\npub(crate) struct Discriminant {\n    sign: Sign,\n    magnitude: u64,\n}\n\n#[derive(Copy, Clone, Eq, PartialEq)]\nenum Sign {\n    Negative,\n    Positive,\n}\n\nimpl DiscriminantSet {\n    pub(crate) fn new(repr: Option<Atom>) -> Self {\n        DiscriminantSet {\n            repr,\n            values: BTreeSet::new(),\n            previous: None,\n        }\n    }\n\n    pub(crate) fn insert(&mut self, expr: &Expr) -> Result<Discriminant> {\n        let (discriminant, repr) = expr_to_discriminant(expr)?;\n        match (self.repr, repr) {\n            (None, Some(new_repr)) => {\n                if let Some(limits) = Limits::of(new_repr) {\n                    for &past in &self.values {\n                        if limits.min <= past && past <= limits.max {\n                            continue;\n                        }\n                        let msg = format!(\n                            \"discriminant value `{}` is outside the limits of {}\",\n                            past, new_repr,\n                        );\n                        return Err(Error::new(Span::call_site(), msg));\n                    }\n                }\n                self.repr = Some(new_repr);\n            }\n            (Some(prev), Some(repr)) if prev != repr => {\n                let msg = format!(\"expected {}, found {}\", prev, repr);\n                return Err(Error::new(Span::call_site(), msg));\n            }\n            _ => {}\n        }\n        insert(self, discriminant)\n    }\n\n    pub(crate) fn insert_next(&mut self) -> Result<Discriminant> {\n        let discriminant = match self.previous {\n            None => Discriminant::zero(),\n            Some(mut discriminant) => match discriminant.sign {\n                Sign::Negative => {\n                    discriminant.magnitude -= 1;\n                    if discriminant.magnitude == 0 {\n                        discriminant.sign = Sign::Positive;\n                    }\n                    discriminant\n                }\n                Sign::Positive => {\n                    if discriminant.magnitude == u64::MAX {\n                        let msg = format!(\"discriminant overflow on value after {}\", u64::MAX);\n                        return Err(Error::new(Span::call_site(), msg));\n                    }\n                    discriminant.magnitude += 1;\n                    discriminant\n                }\n            },\n        };\n        insert(self, discriminant)\n    }\n\n    pub(crate) fn inferred_repr(&self) -> Result<Atom> {\n        if let Some(repr) = self.repr {\n            return Ok(repr);\n        }\n        if self.values.is_empty() {\n            return Ok(U8);\n        }\n        let min = *self.values.iter().next().unwrap();\n        let max = *self.values.iter().next_back().unwrap();\n        for limits in &LIMITS {\n            if limits.min <= min && max <= limits.max {\n                return Ok(limits.repr);\n            }\n        }\n        let msg = \"these discriminant values do not fit in any supported enum repr type\";\n        Err(Error::new(Span::call_site(), msg))\n    }\n}\n\nfn expr_to_discriminant(expr: &Expr) -> Result<(Discriminant, Option<Atom>)> {\n    match expr {\n        Expr::Lit(expr) => {\n            if let Lit::Int(lit) = &expr.lit {\n                let discriminant = lit.base10_parse::<Discriminant>()?;\n                let repr = parse_int_suffix(lit.suffix())?;\n                return Ok((discriminant, repr));\n            }\n        }\n        Expr::Unary(unary) => {\n            if let UnOp::Neg(_) = unary.op {\n                let (mut discriminant, repr) = expr_to_discriminant(&unary.expr)?;\n                discriminant.sign = match discriminant.sign {\n                    Sign::Positive => Sign::Negative,\n                    Sign::Negative => Sign::Positive,\n                };\n                return Ok((discriminant, repr));\n            }\n        }\n        _ => {}\n    }\n    Err(Error::new_spanned(\n        expr,\n        \"enums with non-integer literal discriminants are not supported yet\",\n    ))\n}\n\nfn insert(set: &mut DiscriminantSet, discriminant: Discriminant) -> Result<Discriminant> {\n    if let Some(expected_repr) = set.repr {\n        if let Some(limits) = Limits::of(expected_repr) {\n            if discriminant < limits.min || limits.max < discriminant {\n                let msg = format!(\n                    \"discriminant value `{}` is outside the limits of {}\",\n                    discriminant, expected_repr,\n                );\n                return Err(Error::new(Span::call_site(), msg));\n            }\n        }\n    }\n    set.values.insert(discriminant);\n    set.previous = Some(discriminant);\n    Ok(discriminant)\n}\n\nimpl Discriminant {\n    pub(crate) const fn zero() -> Self {\n        Discriminant {\n            sign: Sign::Positive,\n            magnitude: 0,\n        }\n    }\n\n    const fn pos(u: u64) -> Self {\n        Discriminant {\n            sign: Sign::Positive,\n            magnitude: u,\n        }\n    }\n\n    const fn neg(i: i64) -> Self {\n        Discriminant {\n            sign: if i < 0 {\n                Sign::Negative\n            } else {\n                Sign::Positive\n            },\n            // This is `i.abs() as u64` but without overflow on MIN. Uses the\n            // fact that MIN.wrapping_abs() wraps back to MIN whose binary\n            // representation is 1<<63, and thus the `as u64` conversion\n            // produces 1<<63 too which happens to be the correct unsigned\n            // magnitude.\n            magnitude: i.wrapping_abs() as u64,\n        }\n    }\n}\n\nimpl Display for Discriminant {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        if self.sign == Sign::Negative {\n            f.write_str(\"-\")?;\n        }\n        write!(f, \"{}\", self.magnitude)\n    }\n}\n\nimpl ToTokens for Discriminant {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        if self.sign == Sign::Negative {\n            Token![-](Span::call_site()).to_tokens(tokens);\n        }\n        Literal::u64_unsuffixed(self.magnitude).to_tokens(tokens);\n    }\n}\n\nimpl FromStr for Discriminant {\n    type Err = Error;\n\n    fn from_str(mut s: &str) -> Result<Self> {\n        let sign = if s.starts_with('-') {\n            s = &s[1..];\n            Sign::Negative\n        } else {\n            Sign::Positive\n        };\n        match s.parse::<u64>() {\n            Ok(magnitude) => Ok(Discriminant { sign, magnitude }),\n            Err(_) => Err(Error::new(\n                Span::call_site(),\n                \"discriminant value outside of supported range\",\n            )),\n        }\n    }\n}\n\nimpl Ord for Discriminant {\n    fn cmp(&self, other: &Self) -> Ordering {\n        use self::Sign::{Negative, Positive};\n        match (self.sign, other.sign) {\n            (Negative, Negative) => self.magnitude.cmp(&other.magnitude).reverse(),\n            (Negative, Positive) => Ordering::Less, // negative < positive\n            (Positive, Negative) => Ordering::Greater, // positive > negative\n            (Positive, Positive) => self.magnitude.cmp(&other.magnitude),\n        }\n    }\n}\n\nimpl PartialOrd for Discriminant {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(self.cmp(other))\n    }\n}\n\nfn parse_int_suffix(suffix: &str) -> Result<Option<Atom>> {\n    if suffix.is_empty() {\n        return Ok(None);\n    }\n    if let Some(atom) = Atom::from_str(suffix) {\n        match atom {\n            U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize => return Ok(Some(atom)),\n            _ => {}\n        }\n    }\n    let msg = format!(\"unrecognized integer suffix: `{}`\", suffix);\n    Err(Error::new(Span::call_site(), msg))\n}\n\n#[derive(Copy, Clone)]\npub(crate) struct Limits {\n    pub repr: Atom,\n    pub min: Discriminant,\n    pub max: Discriminant,\n}\n\nimpl Limits {\n    pub(crate) fn of(repr: Atom) -> Option<Limits> {\n        for limits in &LIMITS {\n            if limits.repr == repr {\n                return Some(*limits);\n            }\n        }\n        None\n    }\n}\n\nconst LIMITS: [Limits; 8] = [\n    Limits {\n        repr: U8,\n        min: Discriminant::zero(),\n        max: Discriminant::pos(u8::MAX as u64),\n    },\n    Limits {\n        repr: I8,\n        min: Discriminant::neg(i8::MIN as i64),\n        max: Discriminant::pos(i8::MAX as u64),\n    },\n    Limits {\n        repr: U16,\n        min: Discriminant::zero(),\n        max: Discriminant::pos(u16::MAX as u64),\n    },\n    Limits {\n        repr: I16,\n        min: Discriminant::neg(i16::MIN as i64),\n        max: Discriminant::pos(i16::MAX as u64),\n    },\n    Limits {\n        repr: U32,\n        min: Discriminant::zero(),\n        max: Discriminant::pos(u32::MAX as u64),\n    },\n    Limits {\n        repr: I32,\n        min: Discriminant::neg(i32::MIN as i64),\n        max: Discriminant::pos(i32::MAX as u64),\n    },\n    Limits {\n        repr: U64,\n        min: Discriminant::zero(),\n        max: Discriminant::pos(u64::MAX),\n    },\n    Limits {\n        repr: I64,\n        min: Discriminant::neg(i64::MIN),\n        max: Discriminant::pos(i64::MAX as u64),\n    },\n];\n"
  },
  {
    "path": "syntax/doc.rs",
    "content": "use proc_macro2::TokenStream;\nuse quote::{quote, ToTokens};\nuse syn::LitStr;\n\npub(crate) struct Doc {\n    pub hidden: bool,\n    fragments: Vec<LitStr>,\n}\n\nimpl Doc {\n    pub(crate) fn new() -> Self {\n        Doc {\n            hidden: false,\n            fragments: Vec::new(),\n        }\n    }\n\n    pub(crate) fn push(&mut self, lit: LitStr) {\n        self.fragments.push(lit);\n    }\n\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    pub(crate) fn is_empty(&self) -> bool {\n        self.fragments.is_empty()\n    }\n\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    pub(crate) fn to_string(&self) -> String {\n        let mut doc = String::new();\n        for lit in &self.fragments {\n            doc += &lit.value();\n            doc.push('\\n');\n        }\n        doc\n    }\n}\n\nimpl ToTokens for Doc {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let fragments = &self.fragments;\n        tokens.extend(quote! { #(#[doc = #fragments])* });\n        if self.hidden {\n            tokens.extend(quote! { #[doc(hidden)] });\n        }\n    }\n}\n"
  },
  {
    "path": "syntax/error.rs",
    "content": "use std::fmt::{self, Display};\n\n#[derive(Copy, Clone)]\npub(crate) struct Error {\n    pub msg: &'static str,\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    pub label: Option<&'static str>,\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    pub note: Option<&'static str>,\n}\n\nimpl Display for Error {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        self.msg.fmt(formatter)\n    }\n}\n\npub(crate) static ERRORS: &[Error] = &[\n    BOX_CXX_TYPE,\n    CXXBRIDGE_RESERVED,\n    CXX_STRING_BY_VALUE,\n    CXX_TYPE_BY_VALUE,\n    DISCRIMINANT_OVERFLOW,\n    DOT_INCLUDE,\n    DOUBLE_UNDERSCORE,\n    RESERVED_LIFETIME,\n    RUST_TYPE_BY_VALUE,\n    UNSUPPORTED_TYPE,\n    USE_NOT_ALLOWED,\n];\n\npub(crate) static BOX_CXX_TYPE: Error = Error {\n    msg: \"Box of a C++ type is not supported yet\",\n    label: None,\n    note: Some(\"hint: use UniquePtr<> or SharedPtr<>\"),\n};\n\npub(crate) static CXXBRIDGE_RESERVED: Error = Error {\n    msg: \"identifiers starting with cxxbridge are reserved\",\n    label: Some(\"reserved identifier\"),\n    note: Some(\"identifiers starting with cxxbridge are reserved\"),\n};\n\npub(crate) static CXX_STRING_BY_VALUE: Error = Error {\n    msg: \"C++ string by value is not supported\",\n    label: None,\n    note: Some(\"hint: wrap it in a UniquePtr<>\"),\n};\n\npub(crate) static CXX_TYPE_BY_VALUE: Error = Error {\n    msg: \"C++ type by value is not supported\",\n    label: None,\n    note: Some(\"hint: wrap it in a UniquePtr<> or SharedPtr<>\"),\n};\n\npub(crate) static DISCRIMINANT_OVERFLOW: Error = Error {\n    msg: \"discriminant overflow on value after \",\n    label: Some(\"discriminant overflow\"),\n    note: Some(\"note: explicitly set `= 0` if that is desired outcome\"),\n};\n\npub(crate) static DOT_INCLUDE: Error = Error {\n    msg: \"#include relative to `.` or `..` is not supported in Cargo builds\",\n    label: Some(\"#include relative to `.` or `..` is not supported in Cargo builds\"),\n    note: Some(\"note: use a path starting with the crate name\"),\n};\n\npub(crate) static DOUBLE_UNDERSCORE: Error = Error {\n    msg: \"identifiers containing double underscore are reserved in C++\",\n    label: Some(\"reserved identifier\"),\n    note: Some(\"identifiers containing double underscore are reserved in C++\"),\n};\n\npub(crate) static RESERVED_LIFETIME: Error = Error {\n    msg: \"invalid lifetime parameter name: `'static`\",\n    label: Some(\"'static is a reserved lifetime name\"),\n    note: None,\n};\n\npub(crate) static RUST_TYPE_BY_VALUE: Error = Error {\n    msg: \"opaque Rust type by value is not supported\",\n    label: None,\n    note: Some(\"hint: wrap it in a Box<>\"),\n};\n\npub(crate) static UNSUPPORTED_TYPE: Error = Error {\n    msg: \"unsupported type: \",\n    label: Some(\"unsupported type\"),\n    note: None,\n};\n\npub(crate) static USE_NOT_ALLOWED: Error = Error {\n    msg: \"`use` items are not allowed within cxx bridge\",\n    label: Some(\"not allowed\"),\n    note: Some(\n        \"`use` items are not allowed within cxx bridge; only types defined\\n\\\n         within your bridge, primitive types, or types exported by the cxx\\n\\\n         crate may be used\",\n    ),\n};\n"
  },
  {
    "path": "syntax/file.rs",
    "content": "use crate::syntax::cfg::CfgExpr;\nuse crate::syntax::namespace::Namespace;\nuse quote::quote;\nuse syn::parse::{Error, Parse, ParseStream, Result};\nuse syn::{\n    braced, token, Abi, Attribute, ForeignItem, Ident, Item as RustItem, ItemEnum, ItemImpl,\n    ItemStruct, ItemUse, LitStr, Token, Visibility,\n};\n\npub(crate) struct Module {\n    #[expect(dead_code)]\n    pub cfg: CfgExpr,\n    pub namespace: Namespace,\n    pub attrs: Vec<Attribute>,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub vis: Visibility,\n    pub unsafety: Option<Token![unsafe]>,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub mod_token: Token![mod],\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub ident: Ident,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub brace_token: token::Brace,\n    pub content: Vec<Item>,\n}\n\npub(crate) enum Item {\n    Struct(ItemStruct),\n    Enum(ItemEnum),\n    ForeignMod(ItemForeignMod),\n    Use(ItemUse),\n    Impl(ItemImpl),\n    Other(RustItem),\n}\n\npub(crate) struct ItemForeignMod {\n    pub attrs: Vec<Attribute>,\n    pub unsafety: Option<Token![unsafe]>,\n    pub abi: Abi,\n    #[expect(dead_code)]\n    pub brace_token: token::Brace,\n    pub items: Vec<ForeignItem>,\n}\n\nimpl Parse for Module {\n    fn parse(input: ParseStream) -> Result<Self> {\n        let cfg = CfgExpr::Unconditional;\n        let namespace = Namespace::ROOT;\n        let mut attrs = input.call(Attribute::parse_outer)?;\n        let vis: Visibility = input.parse()?;\n        let unsafety: Option<Token![unsafe]> = input.parse()?;\n        let mod_token: Token![mod] = input.parse()?;\n        let ident: Ident = input.parse()?;\n\n        let semi: Option<Token![;]> = input.parse()?;\n        if let Some(semi) = semi {\n            let span = quote!(#vis #mod_token #semi);\n            return Err(Error::new_spanned(\n                span,\n                \"#[cxx::bridge] module must have inline contents\",\n            ));\n        }\n\n        let content;\n        let brace_token = braced!(content in input);\n        attrs.extend(content.call(Attribute::parse_inner)?);\n\n        let mut items = Vec::new();\n        while !content.is_empty() {\n            items.push(content.parse()?);\n        }\n\n        Ok(Module {\n            cfg,\n            namespace,\n            attrs,\n            vis,\n            unsafety,\n            mod_token,\n            ident,\n            brace_token,\n            content: items,\n        })\n    }\n}\n\nimpl Parse for Item {\n    fn parse(input: ParseStream) -> Result<Self> {\n        let attrs = input.call(Attribute::parse_outer)?;\n\n        let ahead = input.fork();\n        let unsafety = if ahead.parse::<Option<Token![unsafe]>>()?.is_some()\n            && ahead.parse::<Option<Token![extern]>>()?.is_some()\n            && ahead.parse::<Option<LitStr>>().is_ok()\n            && ahead.peek(token::Brace)\n        {\n            Some(input.parse()?)\n        } else {\n            None\n        };\n\n        let item = input.parse()?;\n        match item {\n            RustItem::Struct(mut item) => {\n                item.attrs.splice(..0, attrs);\n                Ok(Item::Struct(item))\n            }\n            RustItem::Enum(mut item) => {\n                item.attrs.splice(..0, attrs);\n                Ok(Item::Enum(item))\n            }\n            RustItem::ForeignMod(mut item) => {\n                item.attrs.splice(..0, attrs);\n                Ok(Item::ForeignMod(ItemForeignMod {\n                    attrs: item.attrs,\n                    unsafety,\n                    abi: item.abi,\n                    brace_token: item.brace_token,\n                    items: item.items,\n                }))\n            }\n            RustItem::Impl(mut item) => {\n                item.attrs.splice(..0, attrs);\n                Ok(Item::Impl(item))\n            }\n            RustItem::Use(mut item) => {\n                item.attrs.splice(..0, attrs);\n                Ok(Item::Use(item))\n            }\n            other => Ok(Item::Other(other)),\n        }\n    }\n}\n"
  },
  {
    "path": "syntax/ident.rs",
    "content": "use crate::syntax::check::Check;\nuse crate::syntax::{error, Api, Pair};\n\nfn check(cx: &mut Check, name: &Pair) {\n    for segment in &name.namespace {\n        check_cxx_ident(cx, &segment.to_string());\n    }\n    check_cxx_ident(cx, &name.cxx.to_string());\n    check_rust_ident(cx, &name.rust.to_string());\n\n    fn check_cxx_ident(cx: &mut Check, ident: &str) {\n        if ident.starts_with(\"cxxbridge\") {\n            cx.error(ident, error::CXXBRIDGE_RESERVED.msg);\n        }\n        if ident.contains(\"__\") {\n            cx.error(ident, error::DOUBLE_UNDERSCORE.msg);\n        }\n    }\n\n    fn check_rust_ident(cx: &mut Check, ident: &str) {\n        if ident.starts_with(\"cxxbridge\") {\n            cx.error(ident, error::CXXBRIDGE_RESERVED.msg);\n        }\n    }\n}\n\npub(crate) fn check_all(cx: &mut Check, apis: &[Api]) {\n    for api in apis {\n        match api {\n            Api::Include(_) | Api::Impl(_) => {}\n            Api::Struct(strct) => {\n                check(cx, &strct.name);\n                for field in &strct.fields {\n                    check(cx, &field.name);\n                }\n            }\n            Api::Enum(enm) => {\n                check(cx, &enm.name);\n                for variant in &enm.variants {\n                    check(cx, &variant.name);\n                }\n            }\n            Api::CxxType(ety) | Api::RustType(ety) => {\n                check(cx, &ety.name);\n            }\n            Api::CxxFunction(efn) | Api::RustFunction(efn) => {\n                check(cx, &efn.name);\n                for arg in &efn.args {\n                    check(cx, &arg.name);\n                }\n            }\n            Api::TypeAlias(alias) => {\n                check(cx, &alias.name);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "syntax/impls.rs",
    "content": "use crate::syntax::{\n    Array, ExternFn, Include, Lifetimes, Ptr, Receiver, Ref, Signature, SliceRef, Ty1, Type, Var,\n};\nuse std::hash::{Hash, Hasher};\nuse std::mem;\nuse std::ops::{Deref, DerefMut};\n\nimpl PartialEq for Include {\n    fn eq(&self, other: &Self) -> bool {\n        let Include {\n            cfg: _,\n            path,\n            kind,\n            begin_span: _,\n            end_span: _,\n        } = self;\n        let Include {\n            cfg: _,\n            path: path2,\n            kind: kind2,\n            begin_span: _,\n            end_span: _,\n        } = other;\n        path == path2 && kind == kind2\n    }\n}\n\nimpl Deref for ExternFn {\n    type Target = Signature;\n\n    fn deref(&self) -> &Self::Target {\n        &self.sig\n    }\n}\n\nimpl DerefMut for ExternFn {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.sig\n    }\n}\n\nimpl Hash for Type {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        mem::discriminant(self).hash(state);\n        match self {\n            Type::Ident(t) => t.hash(state),\n            Type::RustBox(t) => t.hash(state),\n            Type::UniquePtr(t) => t.hash(state),\n            Type::SharedPtr(t) => t.hash(state),\n            Type::WeakPtr(t) => t.hash(state),\n            Type::Ref(t) => t.hash(state),\n            Type::Ptr(t) => t.hash(state),\n            Type::Str(t) => t.hash(state),\n            Type::RustVec(t) => t.hash(state),\n            Type::CxxVector(t) => t.hash(state),\n            Type::Fn(t) => t.hash(state),\n            Type::SliceRef(t) => t.hash(state),\n            Type::Array(t) => t.hash(state),\n            Type::Void(_) => {}\n        }\n    }\n}\n\nimpl Eq for Type {}\n\nimpl PartialEq for Type {\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (Type::Ident(lhs), Type::Ident(rhs)) => lhs == rhs,\n            (Type::RustBox(lhs), Type::RustBox(rhs)) => lhs == rhs,\n            (Type::UniquePtr(lhs), Type::UniquePtr(rhs)) => lhs == rhs,\n            (Type::SharedPtr(lhs), Type::SharedPtr(rhs)) => lhs == rhs,\n            (Type::WeakPtr(lhs), Type::WeakPtr(rhs)) => lhs == rhs,\n            (Type::Ref(lhs), Type::Ref(rhs)) => lhs == rhs,\n            (Type::Str(lhs), Type::Str(rhs)) => lhs == rhs,\n            (Type::RustVec(lhs), Type::RustVec(rhs)) => lhs == rhs,\n            (Type::CxxVector(lhs), Type::CxxVector(rhs)) => lhs == rhs,\n            (Type::Fn(lhs), Type::Fn(rhs)) => lhs == rhs,\n            (Type::SliceRef(lhs), Type::SliceRef(rhs)) => lhs == rhs,\n            (Type::Void(_), Type::Void(_)) => true,\n            (_, _) => false,\n        }\n    }\n}\n\nimpl Eq for Lifetimes {}\n\nimpl PartialEq for Lifetimes {\n    fn eq(&self, other: &Self) -> bool {\n        let Lifetimes {\n            lt_token: _,\n            lifetimes,\n            gt_token: _,\n        } = self;\n        let Lifetimes {\n            lt_token: _,\n            lifetimes: lifetimes2,\n            gt_token: _,\n        } = other;\n        lifetimes.iter().eq(lifetimes2)\n    }\n}\n\nimpl Hash for Lifetimes {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        let Lifetimes {\n            lt_token: _,\n            lifetimes,\n            gt_token: _,\n        } = self;\n        lifetimes.len().hash(state);\n        for lifetime in lifetimes {\n            lifetime.hash(state);\n        }\n    }\n}\n\nimpl Eq for Ty1 {}\n\nimpl PartialEq for Ty1 {\n    fn eq(&self, other: &Self) -> bool {\n        let Ty1 {\n            name,\n            langle: _,\n            inner,\n            rangle: _,\n        } = self;\n        let Ty1 {\n            name: name2,\n            langle: _,\n            inner: inner2,\n            rangle: _,\n        } = other;\n        name == name2 && inner == inner2\n    }\n}\n\nimpl Hash for Ty1 {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        let Ty1 {\n            name,\n            langle: _,\n            inner,\n            rangle: _,\n        } = self;\n        name.hash(state);\n        inner.hash(state);\n    }\n}\n\nimpl Eq for Ref {}\n\nimpl PartialEq for Ref {\n    fn eq(&self, other: &Self) -> bool {\n        let Ref {\n            pinned,\n            ampersand: _,\n            lifetime,\n            mutable,\n            inner,\n            pin_tokens: _,\n            mutability: _,\n        } = self;\n        let Ref {\n            pinned: pinned2,\n            ampersand: _,\n            lifetime: lifetime2,\n            mutable: mutable2,\n            inner: inner2,\n            pin_tokens: _,\n            mutability: _,\n        } = other;\n        pinned == pinned2 && lifetime == lifetime2 && mutable == mutable2 && inner == inner2\n    }\n}\n\nimpl Hash for Ref {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        let Ref {\n            pinned,\n            ampersand: _,\n            lifetime,\n            mutable,\n            inner,\n            pin_tokens: _,\n            mutability: _,\n        } = self;\n        pinned.hash(state);\n        lifetime.hash(state);\n        mutable.hash(state);\n        inner.hash(state);\n    }\n}\n\nimpl Eq for Ptr {}\n\nimpl PartialEq for Ptr {\n    fn eq(&self, other: &Ptr) -> bool {\n        let Ptr {\n            star: _,\n            mutable,\n            inner,\n            mutability: _,\n            constness: _,\n        } = self;\n        let Ptr {\n            star: _,\n            mutable: mutable2,\n            inner: inner2,\n            mutability: _,\n            constness: _,\n        } = other;\n        mutable == mutable2 && inner == inner2\n    }\n}\n\nimpl Hash for Ptr {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        let Ptr {\n            star: _,\n            mutable,\n            inner,\n            mutability: _,\n            constness: _,\n        } = self;\n        mutable.hash(state);\n        inner.hash(state);\n    }\n}\n\nimpl Eq for SliceRef {}\n\nimpl PartialEq for SliceRef {\n    fn eq(&self, other: &Self) -> bool {\n        let SliceRef {\n            ampersand: _,\n            lifetime,\n            mutable,\n            bracket: _,\n            inner,\n            mutability: _,\n        } = self;\n        let SliceRef {\n            ampersand: _,\n            lifetime: lifetime2,\n            mutable: mutable2,\n            bracket: _,\n            inner: inner2,\n            mutability: _,\n        } = other;\n        lifetime == lifetime2 && mutable == mutable2 && inner == inner2\n    }\n}\n\nimpl Hash for SliceRef {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        let SliceRef {\n            ampersand: _,\n            lifetime,\n            mutable,\n            bracket: _,\n            inner,\n            mutability: _,\n        } = self;\n        lifetime.hash(state);\n        mutable.hash(state);\n        inner.hash(state);\n    }\n}\n\nimpl Eq for Array {}\n\nimpl PartialEq for Array {\n    fn eq(&self, other: &Self) -> bool {\n        let Array {\n            bracket: _,\n            inner,\n            semi_token: _,\n            len,\n            len_token: _,\n        } = self;\n        let Array {\n            bracket: _,\n            inner: inner2,\n            semi_token: _,\n            len: len2,\n            len_token: _,\n        } = other;\n        inner == inner2 && len == len2\n    }\n}\n\nimpl Hash for Array {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        let Array {\n            bracket: _,\n            inner,\n            semi_token: _,\n            len,\n            len_token: _,\n        } = self;\n        inner.hash(state);\n        len.hash(state);\n    }\n}\n\nimpl Eq for Signature {}\n\nimpl PartialEq for Signature {\n    fn eq(&self, other: &Self) -> bool {\n        let Signature {\n            asyncness,\n            unsafety,\n            fn_token: _,\n            generics: _,\n            kind,\n            args,\n            ret,\n            throws,\n            paren_token: _,\n            throws_tokens: _,\n        } = self;\n        let Signature {\n            asyncness: asyncness2,\n            unsafety: unsafety2,\n            fn_token: _,\n            generics: _,\n            kind: kind2,\n            args: args2,\n            ret: ret2,\n            throws: throws2,\n            paren_token: _,\n            throws_tokens: _,\n        } = other;\n        asyncness.is_some() == asyncness2.is_some()\n            && unsafety.is_some() == unsafety2.is_some()\n            && kind == kind2\n            && ret == ret2\n            && throws == throws2\n            && args.len() == args2.len()\n            && args.iter().zip(args2).all(|(arg, arg2)| {\n                let Var {\n                    cfg: _,\n                    doc: _,\n                    attrs: _,\n                    visibility: _,\n                    name: _,\n                    colon_token: _,\n                    ty,\n                } = arg;\n                let Var {\n                    cfg: _,\n                    doc: _,\n                    attrs: _,\n                    visibility: _,\n                    name: _,\n                    colon_token: _,\n                    ty: ty2,\n                } = arg2;\n                ty == ty2\n            })\n    }\n}\n\nimpl Hash for Signature {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        let Signature {\n            asyncness,\n            unsafety,\n            fn_token: _,\n            generics: _,\n            kind,\n            args,\n            ret,\n            throws,\n            paren_token: _,\n            throws_tokens: _,\n        } = self;\n        asyncness.is_some().hash(state);\n        unsafety.is_some().hash(state);\n        kind.hash(state);\n        for arg in args {\n            let Var {\n                cfg: _,\n                doc: _,\n                attrs: _,\n                visibility: _,\n                name: _,\n                colon_token: _,\n                ty,\n            } = arg;\n            ty.hash(state);\n        }\n        ret.hash(state);\n        throws.hash(state);\n    }\n}\n\nimpl Eq for Receiver {}\n\nimpl PartialEq for Receiver {\n    fn eq(&self, other: &Self) -> bool {\n        let Receiver {\n            pinned,\n            ampersand: _,\n            lifetime,\n            mutable,\n            var: _,\n            colon_token: _,\n            ty,\n            shorthand: _,\n            pin_tokens: _,\n            mutability: _,\n        } = self;\n        let Receiver {\n            pinned: pinned2,\n            ampersand: _,\n            lifetime: lifetime2,\n            mutable: mutable2,\n            var: _,\n            colon_token: _,\n            ty: ty2,\n            shorthand: _,\n            pin_tokens: _,\n            mutability: _,\n        } = other;\n        pinned == pinned2 && lifetime == lifetime2 && mutable == mutable2 && ty == ty2\n    }\n}\n\nimpl Hash for Receiver {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        let Receiver {\n            pinned,\n            ampersand: _,\n            lifetime,\n            mutable,\n            var: _,\n            colon_token: _,\n            ty,\n            shorthand: _,\n            pin_tokens: _,\n            mutability: _,\n        } = self;\n        pinned.hash(state);\n        lifetime.hash(state);\n        mutable.hash(state);\n        ty.hash(state);\n    }\n}\n"
  },
  {
    "path": "syntax/improper.rs",
    "content": "use self::ImproperCtype::*;\nuse crate::syntax::atom::Atom::{self, *};\nuse crate::syntax::query::TypeQuery;\nuse crate::syntax::Types;\nuse proc_macro2::Ident;\n\npub(crate) enum ImproperCtype<'a> {\n    Definite(bool),\n    Depends(&'a Ident),\n}\n\nimpl<'a> Types<'a> {\n    // yes, no, maybe\n    pub(crate) fn determine_improper_ctype(\n        &self,\n        ty: impl Into<TypeQuery<'a>>,\n    ) -> ImproperCtype<'a> {\n        match ty.into() {\n            TypeQuery::Ident(ident) => {\n                let ident = &ident.rust;\n                if let Some(atom) = Atom::from(ident) {\n                    Definite(atom == RustString)\n                } else if let Some(strct) = self.structs.get(ident) {\n                    Depends(&strct.name.rust) // iterate to fixed-point\n                } else {\n                    Definite(self.rust.contains(ident) || self.aliases.contains_key(ident))\n                }\n            }\n            TypeQuery::RustBox\n            | TypeQuery::RustVec\n            | TypeQuery::Str\n            | TypeQuery::Fn\n            | TypeQuery::Void\n            | TypeQuery::SliceRef => Definite(true),\n            TypeQuery::UniquePtr\n            | TypeQuery::SharedPtr\n            | TypeQuery::WeakPtr\n            | TypeQuery::CxxVector => Definite(false),\n            TypeQuery::Ref(ty) => self.determine_improper_ctype(&ty.inner),\n            TypeQuery::Ptr(ty) => self.determine_improper_ctype(&ty.inner),\n            TypeQuery::Array(ty) => self.determine_improper_ctype(&ty.inner),\n        }\n    }\n}\n"
  },
  {
    "path": "syntax/instantiate.rs",
    "content": "use crate::syntax::map::UnorderedMap;\nuse crate::syntax::resolve::Resolution;\nuse crate::syntax::types::Types;\nuse crate::syntax::{mangle, Symbol, Ty1, Type};\nuse proc_macro2::{Ident, Span};\nuse std::hash::{Hash, Hasher};\n\n#[derive(PartialEq, Eq, Hash)]\npub(crate) enum ImplKey<'a> {\n    RustBox(NamedImplKey<'a>),\n    RustVec(NamedImplKey<'a>),\n    UniquePtr(NamedImplKey<'a>),\n    SharedPtr(NamedImplKey<'a>),\n    WeakPtr(NamedImplKey<'a>),\n    CxxVector(NamedImplKey<'a>),\n}\n\nimpl<'a> ImplKey<'a> {\n    /// Whether to produce FFI symbols instantiating the given generic type even\n    /// when an explicit `impl Foo<T> {}` is not present in the current bridge.\n    ///\n    /// The main consideration is that the same instantiation must not be\n    /// present in two places, which is accomplished using trait impls and the\n    /// orphan rule. Every instantiation of a C++ template like `CxxVector<T>`\n    /// and Rust generic type like `Vec<T>` requires the implementation of\n    /// traits defined by the `cxx` crate for some local type or for a\n    /// fundamental type like `Box<LocalType>`.\n    pub(crate) fn is_implicit_impl_ok(&self, types: &Types) -> bool {\n        // TODO: relax this for Rust generics to allow Vec<Vec<T>> etc.\n        types.is_local(self.inner())\n    }\n\n    /// Returns the type argument in the generic instantiation described by\n    /// `self`. For example, if `self` represents `UniquePtr<u32>` then this\n    /// will return `u32`.\n    fn inner(&self) -> &'a Type {\n        let named_impl_key = match self {\n            ImplKey::RustBox(key)\n            | ImplKey::RustVec(key)\n            | ImplKey::UniquePtr(key)\n            | ImplKey::SharedPtr(key)\n            | ImplKey::WeakPtr(key)\n            | ImplKey::CxxVector(key) => key,\n        };\n        named_impl_key.inner\n    }\n}\n\npub(crate) struct NamedImplKey<'a> {\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub begin_span: Span,\n    /// Mangled form of the `inner` type.\n    pub symbol: Symbol,\n    /// Generic type - e.g. `UniquePtr<u8>`.\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    pub outer: &'a Type,\n    /// Generic type argument - e.g. `u8` from `UniquePtr<u8>`.\n    pub inner: &'a Type,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub end_span: Span,\n}\n\nimpl Type {\n    pub(crate) fn impl_key(&self, res: &UnorderedMap<&Ident, Resolution>) -> Option<ImplKey> {\n        match self {\n            Type::RustBox(ty) => Some(ImplKey::RustBox(NamedImplKey::new(self, ty, res)?)),\n            Type::RustVec(ty) => Some(ImplKey::RustVec(NamedImplKey::new(self, ty, res)?)),\n            Type::UniquePtr(ty) => Some(ImplKey::UniquePtr(NamedImplKey::new(self, ty, res)?)),\n            Type::SharedPtr(ty) => Some(ImplKey::SharedPtr(NamedImplKey::new(self, ty, res)?)),\n            Type::WeakPtr(ty) => Some(ImplKey::WeakPtr(NamedImplKey::new(self, ty, res)?)),\n            Type::CxxVector(ty) => Some(ImplKey::CxxVector(NamedImplKey::new(self, ty, res)?)),\n            _ => None,\n        }\n    }\n}\n\nimpl<'a> PartialEq for NamedImplKey<'a> {\n    fn eq(&self, other: &Self) -> bool {\n        PartialEq::eq(&self.symbol, &other.symbol)\n    }\n}\n\nimpl<'a> Eq for NamedImplKey<'a> {}\n\nimpl<'a> Hash for NamedImplKey<'a> {\n    fn hash<H: Hasher>(&self, hasher: &mut H) {\n        self.symbol.hash(hasher);\n    }\n}\n\nimpl<'a> NamedImplKey<'a> {\n    fn new(outer: &'a Type, ty1: &'a Ty1, res: &UnorderedMap<&Ident, Resolution>) -> Option<Self> {\n        let inner = &ty1.inner;\n        Some(NamedImplKey {\n            symbol: mangle::typename(inner, res)?,\n            begin_span: ty1.name.span(),\n            outer,\n            inner,\n            end_span: ty1.rangle.span,\n        })\n    }\n}\n"
  },
  {
    "path": "syntax/mangle.rs",
    "content": "// Mangled symbol arrangements:\n//\n//   (a) One-off internal symbol.\n//          pattern:  {CXXBRIDGE} $ {NAME}\n//          examples:\n//             - cxxbridge1$exception\n//          defining characteristics:\n//             - 2 segments, none an integer\n//\n//   (b) Behavior on a builtin binding without generic parameter.\n//          pattern:  {CXXBRIDGE} $ {TYPE} $ {NAME}\n//          examples:\n//             - cxxbridge1$string$len\n//          defining characteristics:\n//             - 3 segments, none an integer\n//\n//   (c) Behavior on a builtin binding with generic parameter.\n//          pattern:  {CXXBRIDGE} $ {TYPE} $ {PARAM...} $ {NAME}\n//          examples:\n//             - cxxbridge1$box$org$rust$Struct$alloc\n//             - cxxbridge1$unique_ptr$std$vector$u8$drop\n//          defining characteristics:\n//             - 4+ segments, none an integer\n//\n//   (d) User-defined extern function.\n//          pattern:  {NAMESPACE...} $ {CXXBRIDGE} $ {CXXVERSION} $ {NAME}\n//          examples:\n//             - cxxbridge1$189$new_client\n//             - org$rust$cxxbridge1$189$new_client\n//          defining characteristics:\n//             - second segment from end is an integer\n//\n//   (e) User-defined extern member function.\n//          pattern:  {NAMESPACE...} $ {CXXBRIDGE} $ {CXXVERSION} $ {TYPE} $ {NAME}\n//          examples:\n//             - org$cxxbridge1$189$Struct$get\n//          defining characteristics:\n//             - third segment from end is an integer\n//\n//   (f) Operator overload.\n//          pattern:  {NAMESPACE...} $ {CXXBRIDGE} $ {CXXVERSION} $ {TYPE} $ operator $ {NAME}\n//          examples:\n//             - org$rust$cxxbridge1$189$Struct$operator$eq\n//          defining characteristics:\n//             - second segment from end is `operator` (not possible in type or namespace names)\n//\n//   (g) Closure trampoline.\n//          pattern:  {NAMESPACE...} $ {CXXBRIDGE} $ {CXXVERSION} $ {TYPE?} $ {NAME} $ {ARGUMENT} $ {DIRECTION}\n//          examples:\n//             - org$rust$cxxbridge1$Struct$invoke$f$0\n//          defining characteristics:\n//             - last symbol is `0` (C half) or `1` (Rust half) which are not legal identifiers on their own\n//\n//\n// Mangled preprocessor variable arrangements:\n//\n//   (A) One-off internal variable.\n//          pattern:  {CXXBRIDGE} _ {NAME}\n//          examples:\n//             - CXXBRIDGE1_PANIC\n//             - CXXBRIDGE1_RUST_STRING\n//          defining characteristics:\n//             - NAME does not begin with STRUCT or ENUM\n//\n//   (B) Guard around user-defined type.\n//          pattern:  {CXXBRIDGE} _ {STRUCT or ENUM} _ {NAMESPACE...} $ {TYPE}\n//          examples:\n//             - CXXBRIDGE1_STRUCT_org$rust$Struct\n//             - CXXBRIDGE1_ENUM_Enabled\n\nuse crate::syntax::map::UnorderedMap;\nuse crate::syntax::resolve::Resolution;\nuse crate::syntax::symbol::{self, Symbol};\nuse crate::syntax::{ExternFn, Pair, Type, Types};\nuse proc_macro2::Ident;\n\nconst CXXBRIDGE: &str = \"cxxbridge1\";\nconst CXXVERSION: &str = env!(\"CARGO_PKG_VERSION_PATCH\");\n\nmacro_rules! join {\n    ($($segment:expr),+ $(,)?) => {\n        symbol::join(&[$(&$segment),+])\n    };\n}\n\npub(crate) fn extern_fn(efn: &ExternFn, types: &Types) -> Symbol {\n    match efn.self_type() {\n        Some(self_type) => {\n            let self_type_ident = types.resolve(self_type);\n            join!(\n                efn.name.namespace,\n                CXXBRIDGE,\n                CXXVERSION,\n                self_type_ident.name.cxx,\n                efn.name.rust,\n            )\n        }\n        None => join!(efn.name.namespace, CXXBRIDGE, CXXVERSION, efn.name.rust),\n    }\n}\n\npub(crate) fn operator(receiver: &Pair, operator: &'static str) -> Symbol {\n    join!(\n        receiver.namespace,\n        CXXBRIDGE,\n        CXXVERSION,\n        receiver.cxx,\n        \"operator\",\n        operator,\n    )\n}\n\n// The C half of a function pointer trampoline.\npub(crate) fn c_trampoline(efn: &ExternFn, var: &Pair, types: &Types) -> Symbol {\n    join!(extern_fn(efn, types), var.rust, 0)\n}\n\n// The Rust half of a function pointer trampoline.\npub(crate) fn r_trampoline(efn: &ExternFn, var: &Pair, types: &Types) -> Symbol {\n    join!(extern_fn(efn, types), var.rust, 1)\n}\n\n/// Mangles the given type (e.g. `Box<org::rust::Struct>`) into a symbol\n/// fragment (`box$org$rust$Struct`) to be used in the name of generic\n/// instantiations (`cxxbridge1$box$org$rust$Struct$alloc`) pertaining to that\n/// type.\n///\n/// Generic instantiation is not supported for all types in full generality.\n/// This function must handle unsupported types gracefully by returning `None`\n/// because it is used early during construction of the data structures that are\n/// the input to 'syntax/check.rs', and unsupported generic instantiations are\n/// only reported as an error later.\npub(crate) fn typename(t: &Type, res: &UnorderedMap<&Ident, Resolution>) -> Option<Symbol> {\n    match t {\n        Type::Ident(named_type) => res.get(&named_type.rust).map(|res| res.name.to_symbol()),\n        Type::CxxVector(ty1) => typename(&ty1.inner, res).map(|s| join!(\"std\", \"vector\", s)),\n        Type::RustBox(ty1) => typename(&ty1.inner, res).map(|s| join!(\"box\", s)),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "syntax/map.rs",
    "content": "use std::borrow::Borrow;\nuse std::hash::Hash;\nuse std::ops::Index;\n\npub(crate) use self::ordered::OrderedMap;\npub(crate) use self::unordered::UnorderedMap;\npub(crate) use std::collections::hash_map::Entry;\n\nmod ordered {\n    use indexmap::Equivalent;\n    use std::hash::Hash;\n\n    pub(crate) struct OrderedMap<K, V>(indexmap::IndexMap<K, V>);\n\n    impl<K, V> OrderedMap<K, V> {\n        pub(crate) fn new() -> Self {\n            OrderedMap(indexmap::IndexMap::new())\n        }\n\n        pub(crate) fn keys(&self) -> indexmap::map::Keys<K, V> {\n            self.0.keys()\n        }\n\n        pub(crate) fn contains_key<Q>(&self, key: &Q) -> bool\n        where\n            Q: ?Sized + Hash + Equivalent<K>,\n        {\n            self.0.contains_key(key)\n        }\n    }\n\n    impl<K, V> OrderedMap<K, V>\n    where\n        K: Hash + Eq,\n    {\n        pub(crate) fn insert(&mut self, key: K, value: V) -> Option<V> {\n            self.0.insert(key, value)\n        }\n\n        pub(crate) fn entry(&mut self, key: K) -> indexmap::map::Entry<K, V> {\n            self.0.entry(key)\n        }\n    }\n\n    impl<'a, K, V> IntoIterator for &'a OrderedMap<K, V> {\n        type Item = (&'a K, &'a V);\n        type IntoIter = indexmap::map::Iter<'a, K, V>;\n        fn into_iter(self) -> Self::IntoIter {\n            self.0.iter()\n        }\n    }\n}\n\nmod unordered {\n    use crate::syntax::set::UnorderedSet;\n    use std::borrow::Borrow;\n    use std::collections::hash_map::{Entry, HashMap};\n    use std::hash::Hash;\n\n    // Wrapper prohibits accidentally introducing iteration over the map, which\n    // could lead to nondeterministic generated code.\n    pub(crate) struct UnorderedMap<K, V>(HashMap<K, V>);\n\n    impl<K, V> UnorderedMap<K, V> {\n        pub(crate) fn new() -> Self {\n            UnorderedMap(HashMap::new())\n        }\n    }\n\n    impl<K, V> UnorderedMap<K, V>\n    where\n        K: Hash + Eq,\n    {\n        pub(crate) fn insert(&mut self, key: K, value: V) -> Option<V> {\n            self.0.insert(key, value)\n        }\n\n        pub(crate) fn contains_key<Q>(&self, key: &Q) -> bool\n        where\n            K: Borrow<Q>,\n            Q: ?Sized + Hash + Eq,\n        {\n            self.0.contains_key(key)\n        }\n\n        pub(crate) fn get<Q>(&self, key: &Q) -> Option<&V>\n        where\n            K: Borrow<Q>,\n            Q: ?Sized + Hash + Eq,\n        {\n            self.0.get(key)\n        }\n\n        pub(crate) fn entry(&mut self, key: K) -> Entry<K, V> {\n            self.0.entry(key)\n        }\n\n        #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro\n        pub(crate) fn remove<Q>(&mut self, key: &Q) -> Option<V>\n        where\n            K: Borrow<Q>,\n            Q: ?Sized + Hash + Eq,\n        {\n            self.0.remove(key)\n        }\n\n        pub(crate) fn keys(&self) -> UnorderedSet<K>\n        where\n            K: Copy,\n        {\n            let mut set = UnorderedSet::new();\n            for key in self.0.keys() {\n                set.insert(*key);\n            }\n            set\n        }\n    }\n}\n\nimpl<K, V> Default for UnorderedMap<K, V> {\n    fn default() -> Self {\n        UnorderedMap::new()\n    }\n}\n\nimpl<Q, K, V> Index<&Q> for UnorderedMap<K, V>\nwhere\n    K: Borrow<Q> + Hash + Eq,\n    Q: ?Sized + Hash + Eq,\n{\n    type Output = V;\n\n    fn index(&self, key: &Q) -> &V {\n        self.get(key).unwrap()\n    }\n}\n"
  },
  {
    "path": "syntax/message.rs",
    "content": "use proc_macro2::TokenStream;\nuse quote::ToTokens;\nuse std::fmt::{self, Display};\n\npub(crate) struct Message(String);\n\nimpl Message {\n    pub fn new() -> Self {\n        Message(String::new())\n    }\n\n    pub fn write_fmt(&mut self, args: fmt::Arguments) {\n        fmt::Write::write_fmt(&mut self.0, args).unwrap();\n    }\n}\n\nimpl Display for Message {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        self.0.fmt(formatter)\n    }\n}\n\nimpl ToTokens for Message {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        self.0.to_tokens(tokens);\n    }\n}\n"
  },
  {
    "path": "syntax/mod.rs",
    "content": "// Functionality that is shared between the cxxbridge macro and the cmd.\n\npub(crate) mod atom;\npub(crate) mod attrs;\npub(crate) mod cfg;\npub(crate) mod check;\npub(crate) mod derive;\npub(crate) mod discriminant;\nmod doc;\npub(crate) mod error;\npub(crate) mod file;\npub(crate) mod ident;\nmod impls;\nmod improper;\npub(crate) mod instantiate;\npub(crate) mod mangle;\npub(crate) mod map;\npub(crate) mod message;\nmod names;\npub(crate) mod namespace;\nmod parse;\nmod pod;\npub(crate) mod primitive;\npub(crate) mod qualified;\npub(crate) mod query;\npub(crate) mod report;\npub(crate) mod repr;\npub(crate) mod resolve;\npub(crate) mod set;\nmod signature;\npub(crate) mod symbol;\nmod tokens;\nmod toposort;\npub(crate) mod trivial;\npub(crate) mod types;\npub(crate) mod unpin;\nmod visit;\n\nuse self::attrs::OtherAttrs;\nuse self::cfg::CfgExpr;\nuse self::namespace::Namespace;\nuse self::parse::kw;\nuse self::symbol::Symbol;\nuse proc_macro2::{Ident, Span};\nuse syn::punctuated::Punctuated;\nuse syn::token::{Brace, Bracket, Paren};\nuse syn::{Expr, Generics, Lifetime, LitInt, Token, Type as RustType};\n\npub(crate) use self::atom::Atom;\npub(crate) use self::derive::{Derive, Trait};\npub(crate) use self::discriminant::Discriminant;\npub(crate) use self::doc::Doc;\npub(crate) use self::names::ForeignName;\npub(crate) use self::parse::parse_items;\npub(crate) use self::types::Types;\n\npub(crate) enum Api {\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    Include(Include),\n    Struct(Struct),\n    Enum(Enum),\n    CxxType(ExternType),\n    CxxFunction(ExternFn),\n    RustType(ExternType),\n    RustFunction(ExternFn),\n    TypeAlias(TypeAlias),\n    Impl(Impl),\n}\n\npub(crate) struct Include {\n    pub cfg: CfgExpr,\n    pub path: String,\n    pub kind: IncludeKind,\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    pub begin_span: Span,\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    pub end_span: Span,\n}\n\n/// Whether to emit `#include \"path\"` or `#include <path>`.\n#[derive(Copy, Clone, PartialEq, Debug)]\npub enum IncludeKind {\n    /// `#include \"quoted/path/to\"`\n    Quoted,\n    /// `#include <bracketed/path/to>`\n    Bracketed,\n}\n\npub(crate) struct ExternType {\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    pub cfg: CfgExpr,\n    pub lang: Lang,\n    pub doc: Doc,\n    pub derives: Vec<Derive>,\n    pub attrs: OtherAttrs,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub visibility: Token![pub],\n    pub type_token: Token![type],\n    pub name: Pair,\n    pub generics: Lifetimes,\n    #[expect(dead_code)]\n    pub colon_token: Option<Token![:]>,\n    pub bounds: Vec<Derive>,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub semi_token: Token![;],\n    pub trusted: bool,\n}\n\npub(crate) struct Struct {\n    pub cfg: CfgExpr,\n    pub doc: Doc,\n    pub derives: Vec<Derive>,\n    pub align: Option<LitInt>,\n    pub attrs: OtherAttrs,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub visibility: Token![pub],\n    pub struct_token: Token![struct],\n    pub name: Pair,\n    pub generics: Lifetimes,\n    pub brace_token: Brace,\n    pub fields: Vec<Var>,\n}\n\npub(crate) struct Enum {\n    pub cfg: CfgExpr,\n    pub doc: Doc,\n    pub derives: Vec<Derive>,\n    pub attrs: OtherAttrs,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub visibility: Token![pub],\n    pub enum_token: Token![enum],\n    pub name: Pair,\n    pub generics: Lifetimes,\n    pub brace_token: Brace,\n    pub variants: Vec<Variant>,\n    pub repr: EnumRepr,\n    pub explicit_repr: bool,\n}\n\npub(crate) struct EnumRepr {\n    pub atom: Atom,\n    pub repr_type: Type,\n}\n\npub(crate) struct ExternFn {\n    pub cfg: CfgExpr,\n    pub lang: Lang,\n    pub doc: Doc,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub attrs: OtherAttrs,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub visibility: Token![pub],\n    pub name: Pair,\n    pub sig: Signature,\n    pub semi_token: Token![;],\n    pub trusted: bool,\n}\n\npub(crate) struct TypeAlias {\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    pub cfg: CfgExpr,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub doc: Doc,\n    pub derives: Vec<Derive>,\n    pub attrs: OtherAttrs,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub visibility: Token![pub],\n    pub type_token: Token![type],\n    pub name: Pair,\n    pub generics: Lifetimes,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub eq_token: Token![=],\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub ty: RustType,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub semi_token: Token![;],\n}\n\npub(crate) struct Impl {\n    pub cfg: CfgExpr,\n    #[expect(dead_code)]\n    pub attrs: OtherAttrs,\n    pub impl_token: Token![impl],\n    pub impl_generics: Lifetimes,\n    #[expect(dead_code)]\n    pub negative: bool,\n    pub ty: Type,\n    pub brace_token: Brace,\n    pub negative_token: Option<Token![!]>,\n}\n\n#[derive(Clone, Default)]\npub(crate) struct Lifetimes {\n    pub lt_token: Option<Token![<]>,\n    pub lifetimes: Punctuated<Lifetime, Token![,]>,\n    pub gt_token: Option<Token![>]>,\n}\n\npub(crate) struct Signature {\n    pub asyncness: Option<Token![async]>,\n    pub unsafety: Option<Token![unsafe]>,\n    pub fn_token: Token![fn],\n    pub generics: Generics,\n    pub kind: FnKind,\n    pub args: Punctuated<Var, Token![,]>,\n    pub ret: Option<Type>,\n    pub throws: bool,\n    pub paren_token: Paren,\n    pub throws_tokens: Option<(kw::Result, Token![<], Token![>])>,\n}\n\n#[derive(PartialEq, Hash)]\npub(crate) enum FnKind {\n    /// Rust method or C++ non-static member function.\n    Method(Receiver),\n    /// Rust associated function or C++ static member function.\n    Assoc(Ident),\n    /// Non-member function.\n    Free,\n}\n\npub(crate) struct Var {\n    pub cfg: CfgExpr,\n    pub doc: Doc,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub attrs: OtherAttrs,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub visibility: Token![pub],\n    pub name: Pair,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub colon_token: Token![:],\n    pub ty: Type,\n}\n\npub(crate) struct Receiver {\n    pub pinned: bool,\n    pub ampersand: Token![&],\n    pub lifetime: Option<Lifetime>,\n    pub mutable: bool,\n    pub var: Token![self],\n    pub ty: NamedType,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub colon_token: Token![:],\n    pub shorthand: bool,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub pin_tokens: Option<(kw::Pin, Token![<], Token![>])>,\n    pub mutability: Option<Token![mut]>,\n}\n\npub(crate) struct Variant {\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    pub cfg: CfgExpr,\n    pub doc: Doc,\n    pub default: bool,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub attrs: OtherAttrs,\n    pub name: Pair,\n    pub discriminant: Discriminant,\n    #[expect(dead_code)]\n    pub expr: Option<Expr>,\n}\n\npub(crate) enum Type {\n    Ident(NamedType),\n    RustBox(Box<Ty1>),\n    RustVec(Box<Ty1>),\n    UniquePtr(Box<Ty1>),\n    SharedPtr(Box<Ty1>),\n    WeakPtr(Box<Ty1>),\n    Ref(Box<Ref>),\n    Ptr(Box<Ptr>),\n    Str(Box<Ref>),\n    CxxVector(Box<Ty1>),\n    Fn(Box<Signature>),\n    Void(Span),\n    SliceRef(Box<SliceRef>),\n    Array(Box<Array>),\n}\n\npub(crate) struct Ty1 {\n    pub name: Ident,\n    pub langle: Token![<],\n    pub inner: Type,\n    pub rangle: Token![>],\n}\n\npub(crate) struct Ref {\n    pub pinned: bool,\n    pub ampersand: Token![&],\n    pub lifetime: Option<Lifetime>,\n    pub mutable: bool,\n    pub inner: Type,\n    pub pin_tokens: Option<(kw::Pin, Token![<], Token![>])>,\n    pub mutability: Option<Token![mut]>,\n}\n\npub(crate) struct Ptr {\n    pub star: Token![*],\n    pub mutable: bool,\n    pub inner: Type,\n    pub mutability: Option<Token![mut]>,\n    pub constness: Option<Token![const]>,\n}\n\npub(crate) struct SliceRef {\n    pub ampersand: Token![&],\n    pub lifetime: Option<Lifetime>,\n    pub mutable: bool,\n    pub bracket: Bracket,\n    pub inner: Type,\n    pub mutability: Option<Token![mut]>,\n}\n\npub(crate) struct Array {\n    pub bracket: Bracket,\n    pub inner: Type,\n    pub semi_token: Token![;],\n    pub len: usize,\n    pub len_token: LitInt,\n}\n\n#[derive(Copy, Clone, PartialEq)]\npub(crate) enum Lang {\n    Cxx,\n    CxxUnwind,\n    Rust,\n}\n\n// An association of a defined Rust name with a fully resolved, namespace\n// qualified C++ name.\n#[derive(Clone)]\npub(crate) struct Pair {\n    pub namespace: Namespace,\n    pub cxx: ForeignName,\n    pub rust: Ident,\n}\n\n// Wrapper for a type which needs to be resolved before it can be printed in\n// C++.\n#[derive(PartialEq, Eq, Hash)]\npub(crate) struct NamedType {\n    pub rust: Ident,\n    pub generics: Lifetimes,\n}\n"
  },
  {
    "path": "syntax/names.rs",
    "content": "use crate::syntax::symbol::Segment;\nuse crate::syntax::{Lifetimes, NamedType, Pair, Symbol};\nuse proc_macro2::{Ident, Span};\nuse std::fmt::{self, Display};\nuse std::iter;\nuse syn::ext::IdentExt;\nuse syn::parse::{Error, Parser, Result};\nuse syn::punctuated::Punctuated;\n\n#[derive(Clone)]\npub(crate) struct ForeignName {\n    text: String,\n}\n\nimpl Pair {\n    pub(crate) fn to_symbol(&self) -> Symbol {\n        let segments = self\n            .namespace\n            .iter()\n            .map(|ident| ident as &dyn Segment)\n            .chain(iter::once(&self.cxx as &dyn Segment));\n        Symbol::from_idents(segments)\n    }\n}\n\nimpl NamedType {\n    pub(crate) fn new(rust: Ident) -> Self {\n        let generics = Lifetimes {\n            lt_token: None,\n            lifetimes: Punctuated::new(),\n            gt_token: None,\n        };\n        NamedType { rust, generics }\n    }\n}\n\nimpl ForeignName {\n    pub(crate) fn parse(text: &str, span: Span) -> Result<Self> {\n        // TODO: support C++ names containing whitespace (`unsigned int`) or\n        // non-alphanumeric characters (`operator++`).\n        match Ident::parse_any.parse_str(text) {\n            Ok(ident) => {\n                let text = ident.to_string();\n                Ok(ForeignName { text })\n            }\n            Err(err) => Err(Error::new(span, err)),\n        }\n    }\n}\n\nimpl Display for ForeignName {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        formatter.write_str(&self.text)\n    }\n}\n\nimpl PartialEq<str> for ForeignName {\n    fn eq(&self, rhs: &str) -> bool {\n        self.text == rhs\n    }\n}\n"
  },
  {
    "path": "syntax/namespace.rs",
    "content": "use crate::syntax::qualified::QualifiedName;\nuse std::slice::Iter;\nuse syn::parse::{Error, Parse, ParseStream, Result};\nuse syn::{Expr, Ident, Lit, Meta, Token};\n\nmod kw {\n    syn::custom_keyword!(namespace);\n}\n\n#[derive(Clone, Default, PartialEq)]\npub(crate) struct Namespace {\n    segments: Vec<Ident>,\n}\n\nimpl Namespace {\n    pub(crate) const ROOT: Self = Namespace {\n        segments: Vec::new(),\n    };\n\n    pub(crate) fn iter(&self) -> Iter<Ident> {\n        self.segments.iter()\n    }\n\n    pub(crate) fn parse_bridge_attr_namespace(input: ParseStream) -> Result<Self> {\n        if input.is_empty() {\n            return Ok(Namespace::ROOT);\n        }\n\n        input.parse::<kw::namespace>()?;\n        input.parse::<Token![=]>()?;\n        let namespace = input.parse::<Namespace>()?;\n        input.parse::<Option<Token![,]>>()?;\n        Ok(namespace)\n    }\n\n    pub(crate) fn parse_meta(meta: &Meta) -> Result<Self> {\n        if let Meta::NameValue(meta) = meta {\n            match &meta.value {\n                Expr::Lit(expr) => {\n                    if let Lit::Str(lit) = &expr.lit {\n                        let segments = QualifiedName::parse_quoted(lit)?.segments;\n                        return Ok(Namespace { segments });\n                    }\n                }\n                Expr::Path(expr)\n                    if expr.qself.is_none()\n                        && expr\n                            .path\n                            .segments\n                            .iter()\n                            .all(|segment| segment.arguments.is_none()) =>\n                {\n                    let segments = expr\n                        .path\n                        .segments\n                        .iter()\n                        .map(|segment| segment.ident.clone())\n                        .collect();\n                    return Ok(Namespace { segments });\n                }\n                _ => {}\n            }\n        }\n        Err(Error::new_spanned(meta, \"unsupported namespace attribute\"))\n    }\n}\n\nimpl Default for &Namespace {\n    fn default() -> Self {\n        const ROOT: &Namespace = &Namespace::ROOT;\n        ROOT\n    }\n}\n\nimpl Parse for Namespace {\n    fn parse(input: ParseStream) -> Result<Self> {\n        let segments = QualifiedName::parse_quoted_or_unquoted(input)?.segments;\n        Ok(Namespace { segments })\n    }\n}\n\nimpl<'a> IntoIterator for &'a Namespace {\n    type Item = &'a Ident;\n    type IntoIter = Iter<'a, Ident>;\n    fn into_iter(self) -> Self::IntoIter {\n        self.iter()\n    }\n}\n\nimpl<'a> FromIterator<&'a Ident> for Namespace {\n    fn from_iter<I>(idents: I) -> Self\n    where\n        I: IntoIterator<Item = &'a Ident>,\n    {\n        let segments = idents.into_iter().cloned().collect();\n        Namespace { segments }\n    }\n}\n"
  },
  {
    "path": "syntax/parse.rs",
    "content": "use crate::syntax::attrs::OtherAttrs;\nuse crate::syntax::cfg::CfgExpr;\nuse crate::syntax::discriminant::DiscriminantSet;\nuse crate::syntax::file::{Item, ItemForeignMod};\nuse crate::syntax::report::Errors;\nuse crate::syntax::repr::Repr;\nuse crate::syntax::Atom::*;\nuse crate::syntax::{\n    attrs, error, Api, Array, Derive, Doc, Enum, EnumRepr, ExternFn, ExternType, FnKind,\n    ForeignName, Impl, Include, IncludeKind, Lang, Lifetimes, NamedType, Namespace, Pair, Ptr,\n    Receiver, Ref, Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var, Variant,\n};\nuse proc_macro2::{Delimiter, Group, Span, TokenStream, TokenTree};\nuse quote::{format_ident, quote, quote_spanned};\nuse std::mem;\nuse syn::parse::{ParseStream, Parser};\nuse syn::punctuated::Punctuated;\nuse syn::{\n    Abi, Attribute, Error, Expr, Fields, FnArg, ForeignItem, ForeignItemFn, ForeignItemType,\n    GenericArgument, GenericParam, Generics, Ident, ItemEnum, ItemImpl, ItemStruct, Lit, LitStr,\n    Pat, PathArguments, Result, ReturnType, Signature as RustSignature, Token, TraitBound,\n    TraitBoundModifier, Type as RustType, TypeArray, TypeBareFn, TypeParamBound, TypePath, TypePtr,\n    TypeReference, Variant as RustVariant, Visibility,\n};\n\npub(crate) mod kw {\n    syn::custom_keyword!(Pin);\n    syn::custom_keyword!(Result);\n}\n\npub(crate) fn parse_items(\n    cx: &mut Errors,\n    items: Vec<Item>,\n    trusted: bool,\n    namespace: &Namespace,\n) -> Vec<Api> {\n    let mut apis = Vec::new();\n    for item in items {\n        match item {\n            Item::Struct(item) => match parse_struct(cx, item, namespace) {\n                Ok(strct) => apis.push(strct),\n                Err(err) => cx.push(err),\n            },\n            Item::Enum(item) => apis.push(parse_enum(cx, item, namespace)),\n            Item::ForeignMod(foreign_mod) => {\n                parse_foreign_mod(cx, foreign_mod, &mut apis, trusted, namespace);\n            }\n            Item::Impl(item) => match parse_impl(cx, item) {\n                Ok(imp) => apis.push(imp),\n                Err(err) => cx.push(err),\n            },\n            Item::Use(item) => cx.error(item, error::USE_NOT_ALLOWED),\n            Item::Other(item) => cx.error(item, \"unsupported item\"),\n        }\n    }\n    apis\n}\n\nfn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) -> Result<Api> {\n    let mut cfg = CfgExpr::Unconditional;\n    let mut doc = Doc::new();\n    let mut derives = Vec::new();\n    let mut repr = None;\n    let mut namespace = namespace.clone();\n    let mut cxx_name = None;\n    let mut rust_name = None;\n    let attrs = attrs::parse(\n        cx,\n        mem::take(&mut item.attrs),\n        attrs::Parser {\n            cfg: Some(&mut cfg),\n            doc: Some(&mut doc),\n            derives: Some(&mut derives),\n            repr: Some(&mut repr),\n            namespace: Some(&mut namespace),\n            cxx_name: Some(&mut cxx_name),\n            rust_name: Some(&mut rust_name),\n            ..Default::default()\n        },\n    );\n\n    let align = match repr {\n        Some(Repr::Align(align)) => Some(align),\n        Some(Repr::Atom(_atom, span)) => {\n            cx.push(Error::new(span, \"unsupported alignment on a struct\"));\n            None\n        }\n        None => None,\n    };\n\n    let named_fields = match item.fields {\n        Fields::Named(fields) => fields,\n        Fields::Unit => return Err(Error::new_spanned(item, \"unit structs are not supported\")),\n        Fields::Unnamed(_) => {\n            return Err(Error::new_spanned(item, \"tuple structs are not supported\"));\n        }\n    };\n\n    let mut lifetimes = Punctuated::new();\n    let mut has_unsupported_generic_param = false;\n    for pair in item.generics.params.into_pairs() {\n        let (param, punct) = pair.into_tuple();\n        match param {\n            GenericParam::Lifetime(param) => {\n                if !param.bounds.is_empty() && !has_unsupported_generic_param {\n                    let msg = \"lifetime parameter with bounds is not supported yet\";\n                    cx.error(&param, msg);\n                    has_unsupported_generic_param = true;\n                }\n                lifetimes.push_value(param.lifetime);\n                if let Some(punct) = punct {\n                    lifetimes.push_punct(punct);\n                }\n            }\n            GenericParam::Type(param) => {\n                if !has_unsupported_generic_param {\n                    let msg = \"struct with generic type parameter is not supported yet\";\n                    cx.error(&param, msg);\n                    has_unsupported_generic_param = true;\n                }\n            }\n            GenericParam::Const(param) => {\n                if !has_unsupported_generic_param {\n                    let msg = \"struct with const generic parameter is not supported yet\";\n                    cx.error(&param, msg);\n                    has_unsupported_generic_param = true;\n                }\n            }\n        }\n    }\n\n    if let Some(where_clause) = &item.generics.where_clause {\n        cx.error(\n            where_clause,\n            \"struct with where-clause is not supported yet\",\n        );\n    }\n\n    let mut fields = Vec::new();\n    for field in named_fields.named {\n        let ident = field.ident.unwrap();\n        let mut cfg = CfgExpr::Unconditional;\n        let mut doc = Doc::new();\n        let mut cxx_name = None;\n        let mut rust_name = None;\n        let attrs = attrs::parse(\n            cx,\n            field.attrs,\n            attrs::Parser {\n                cfg: Some(&mut cfg),\n                doc: Some(&mut doc),\n                cxx_name: Some(&mut cxx_name),\n                rust_name: Some(&mut rust_name),\n                ..Default::default()\n            },\n        );\n        let ty = match parse_type(&field.ty) {\n            Ok(ty) => ty,\n            Err(err) => {\n                cx.push(err);\n                continue;\n            }\n        };\n        let visibility = visibility_pub(&field.vis, ident.span());\n        let name = pair(Namespace::default(), &ident, cxx_name, rust_name);\n        let colon_token = field.colon_token.unwrap();\n        fields.push(Var {\n            cfg,\n            doc,\n            attrs,\n            visibility,\n            name,\n            colon_token,\n            ty,\n        });\n    }\n\n    let struct_token = item.struct_token;\n    let visibility = visibility_pub(&item.vis, struct_token.span);\n    let name = pair(namespace, &item.ident, cxx_name, rust_name);\n    let generics = Lifetimes {\n        lt_token: item.generics.lt_token,\n        lifetimes,\n        gt_token: item.generics.gt_token,\n    };\n    let brace_token = named_fields.brace_token;\n\n    Ok(Api::Struct(Struct {\n        cfg,\n        doc,\n        derives,\n        align,\n        attrs,\n        visibility,\n        struct_token,\n        name,\n        generics,\n        brace_token,\n        fields,\n    }))\n}\n\nfn parse_enum(cx: &mut Errors, item: ItemEnum, namespace: &Namespace) -> Api {\n    let mut cfg = CfgExpr::Unconditional;\n    let mut doc = Doc::new();\n    let mut derives = Vec::new();\n    let mut repr = None;\n    let mut namespace = namespace.clone();\n    let mut cxx_name = None;\n    let mut rust_name = None;\n    let attrs = attrs::parse(\n        cx,\n        item.attrs,\n        attrs::Parser {\n            cfg: Some(&mut cfg),\n            doc: Some(&mut doc),\n            derives: Some(&mut derives),\n            repr: Some(&mut repr),\n            namespace: Some(&mut namespace),\n            cxx_name: Some(&mut cxx_name),\n            rust_name: Some(&mut rust_name),\n            ..Default::default()\n        },\n    );\n\n    if !item.generics.params.is_empty() {\n        let vis = &item.vis;\n        let enum_token = item.enum_token;\n        let ident = &item.ident;\n        let generics = &item.generics;\n        let span = quote!(#vis #enum_token #ident #generics);\n        cx.error(span, \"enum with generic parameters is not supported\");\n    } else if let Some(where_clause) = &item.generics.where_clause {\n        cx.error(where_clause, \"enum with where-clause is not supported\");\n    }\n\n    let repr = match repr {\n        Some(Repr::Atom(atom, _span)) => Some(atom),\n        Some(Repr::Align(align)) => {\n            cx.error(align, \"C++ does not support custom alignment on an enum\");\n            None\n        }\n        None => None,\n    };\n\n    let mut variants = Vec::new();\n    let mut discriminants = DiscriminantSet::new(repr);\n    for variant in item.variants {\n        match parse_variant(cx, variant, &mut discriminants) {\n            Ok(variant) => variants.push(variant),\n            Err(err) => cx.push(err),\n        }\n    }\n\n    let enum_token = item.enum_token;\n    let visibility = visibility_pub(&item.vis, enum_token.span);\n    let brace_token = item.brace_token;\n\n    let explicit_repr = repr.is_some();\n    let mut repr = U8;\n    match discriminants.inferred_repr() {\n        Ok(inferred) => repr = inferred,\n        Err(err) => {\n            let span = quote_spanned!(brace_token.span=> #enum_token {});\n            cx.error(span, err);\n            variants.clear();\n        }\n    }\n\n    let name = pair(namespace, &item.ident, cxx_name, rust_name);\n    let repr_ident = Ident::new(repr.as_ref(), Span::call_site());\n    let repr_type = Type::Ident(NamedType::new(repr_ident));\n    let repr = EnumRepr {\n        atom: repr,\n        repr_type,\n    };\n    let generics = Lifetimes {\n        lt_token: None,\n        lifetimes: Punctuated::new(),\n        gt_token: None,\n    };\n\n    Api::Enum(Enum {\n        cfg,\n        doc,\n        derives,\n        attrs,\n        visibility,\n        enum_token,\n        name,\n        generics,\n        brace_token,\n        variants,\n        repr,\n        explicit_repr,\n    })\n}\n\nfn parse_variant(\n    cx: &mut Errors,\n    mut variant: RustVariant,\n    discriminants: &mut DiscriminantSet,\n) -> Result<Variant> {\n    let mut cfg = CfgExpr::Unconditional;\n    let mut doc = Doc::new();\n    let mut default = false;\n    let mut cxx_name = None;\n    let mut rust_name = None;\n    let attrs = attrs::parse(\n        cx,\n        mem::take(&mut variant.attrs),\n        attrs::Parser {\n            cfg: Some(&mut cfg),\n            doc: Some(&mut doc),\n            default: Some(&mut default),\n            cxx_name: Some(&mut cxx_name),\n            rust_name: Some(&mut rust_name),\n            ..Default::default()\n        },\n    );\n\n    match variant.fields {\n        Fields::Unit => {}\n        _ => {\n            let msg = \"enums with data are not supported yet\";\n            return Err(Error::new_spanned(variant, msg));\n        }\n    }\n\n    let expr = variant.discriminant.as_ref().map(|(_, expr)| expr);\n    let try_discriminant = match &expr {\n        Some(lit) => discriminants.insert(lit),\n        None => discriminants.insert_next(),\n    };\n    let discriminant = match try_discriminant {\n        Ok(discriminant) => discriminant,\n        Err(err) => return Err(Error::new_spanned(variant, err)),\n    };\n\n    let name = pair(Namespace::ROOT, &variant.ident, cxx_name, rust_name);\n    let expr = variant.discriminant.map(|(_, expr)| expr);\n\n    Ok(Variant {\n        cfg,\n        doc,\n        default,\n        attrs,\n        name,\n        discriminant,\n        expr,\n    })\n}\n\nfn parse_foreign_mod(\n    cx: &mut Errors,\n    foreign_mod: ItemForeignMod,\n    out: &mut Vec<Api>,\n    trusted: bool,\n    namespace: &Namespace,\n) {\n    let lang = match parse_lang(&foreign_mod.abi) {\n        Ok(lang) => lang,\n        Err(err) => return cx.push(err),\n    };\n\n    match lang {\n        Lang::Rust => {\n            if foreign_mod.unsafety.is_some() {\n                let unsafety = foreign_mod.unsafety;\n                let abi = &foreign_mod.abi;\n                let span = quote!(#unsafety #abi);\n                cx.error(span, \"extern \\\"Rust\\\" block does not need to be unsafe\");\n            }\n        }\n        Lang::Cxx | Lang::CxxUnwind => {}\n    }\n\n    let trusted = trusted || foreign_mod.unsafety.is_some();\n\n    let mut cfg = CfgExpr::Unconditional;\n    let mut namespace = namespace.clone();\n    let attrs = attrs::parse(\n        cx,\n        foreign_mod.attrs,\n        attrs::Parser {\n            cfg: Some(&mut cfg),\n            namespace: Some(&mut namespace),\n            ..Default::default()\n        },\n    );\n\n    let mut items = Vec::new();\n    for foreign in foreign_mod.items {\n        match foreign {\n            ForeignItem::Type(foreign) => {\n                let ety = parse_extern_type(cx, foreign, lang, trusted, &cfg, &namespace, &attrs);\n                items.push(ety);\n            }\n            ForeignItem::Fn(foreign) => {\n                match parse_extern_fn(cx, foreign, lang, trusted, &cfg, &namespace, &attrs) {\n                    Ok(efn) => items.push(efn),\n                    Err(err) => cx.push(err),\n                }\n            }\n            ForeignItem::Macro(foreign) if foreign.mac.path.is_ident(\"include\") => {\n                match foreign.mac.parse_body_with(parse_include) {\n                    Ok(mut include) => {\n                        include.cfg = cfg.clone();\n                        items.push(Api::Include(include));\n                    }\n                    Err(err) => cx.push(err),\n                }\n            }\n            ForeignItem::Verbatim(tokens) => {\n                match parse_extern_verbatim(cx, tokens, lang, trusted, &cfg, &namespace, &attrs) {\n                    Ok(api) => items.push(api),\n                    Err(err) => cx.push(err),\n                }\n            }\n            _ => cx.error(foreign, \"unsupported foreign item\"),\n        }\n    }\n\n    if !trusted\n        && items.iter().any(|api| match api {\n            Api::CxxFunction(efn) => efn.unsafety.is_none(),\n            _ => false,\n        })\n    {\n        cx.error(\n            foreign_mod.abi,\n            \"block must be declared `unsafe extern \\\"C++\\\"` if it contains any safe-to-call C++ functions\",\n        );\n    }\n\n    let mut types = items.iter().filter_map(|item| match item {\n        Api::CxxType(ety) | Api::RustType(ety) => Some(&ety.name),\n        Api::TypeAlias(alias) => Some(&alias.name),\n        _ => None,\n    });\n    if let (Some(single_type), None) = (types.next(), types.next()) {\n        let single_type = single_type.clone();\n        for item in &mut items {\n            if let Api::CxxFunction(efn) | Api::RustFunction(efn) = item {\n                if let Some(receiver) = efn.sig.receiver_mut() {\n                    if receiver.ty.rust == \"Self\" {\n                        receiver.ty.rust = single_type.rust.clone();\n                    }\n                }\n            }\n        }\n    }\n\n    out.extend(items);\n}\n\nfn parse_lang(abi: &Abi) -> Result<Lang> {\n    let Some(name) = &abi.name else {\n        return Err(Error::new_spanned(\n            abi,\n            \"ABI name is required, extern \\\"C++\\\" or extern \\\"Rust\\\"\",\n        ));\n    };\n\n    match name.value().as_str() {\n        \"C++\" => Ok(Lang::Cxx),\n        \"C++-unwind\" => Ok(Lang::CxxUnwind),\n        \"Rust\" => Ok(Lang::Rust),\n        _ => Err(Error::new_spanned(\n            abi,\n            \"unrecognized ABI, requires either \\\"C++\\\" or \\\"Rust\\\"\",\n        )),\n    }\n}\n\nfn parse_extern_type(\n    cx: &mut Errors,\n    foreign_type: ForeignItemType,\n    lang: Lang,\n    trusted: bool,\n    extern_block_cfg: &CfgExpr,\n    namespace: &Namespace,\n    attrs: &OtherAttrs,\n) -> Api {\n    let mut cfg = extern_block_cfg.clone();\n    let mut doc = Doc::new();\n    let mut derives = Vec::new();\n    let mut namespace = namespace.clone();\n    let mut cxx_name = None;\n    let mut rust_name = None;\n    let mut attrs = attrs.clone();\n    attrs.extend(attrs::parse(\n        cx,\n        foreign_type.attrs,\n        attrs::Parser {\n            cfg: Some(&mut cfg),\n            doc: Some(&mut doc),\n            derives: Some(&mut derives),\n            namespace: Some(&mut namespace),\n            cxx_name: Some(&mut cxx_name),\n            rust_name: Some(&mut rust_name),\n            ..Default::default()\n        },\n    ));\n\n    let type_token = foreign_type.type_token;\n    let visibility = visibility_pub(&foreign_type.vis, type_token.span);\n    let name = pair(namespace, &foreign_type.ident, cxx_name, rust_name);\n    let generics = extern_type_lifetimes(cx, foreign_type.generics);\n    let colon_token = None;\n    let bounds = Vec::new();\n    let semi_token = foreign_type.semi_token;\n\n    (match lang {\n        Lang::Cxx | Lang::CxxUnwind => Api::CxxType,\n        Lang::Rust => Api::RustType,\n    })(ExternType {\n        cfg,\n        lang,\n        doc,\n        derives,\n        attrs,\n        visibility,\n        type_token,\n        name,\n        generics,\n        colon_token,\n        bounds,\n        semi_token,\n        trusted,\n    })\n}\n\nfn parse_extern_fn(\n    cx: &mut Errors,\n    mut foreign_fn: ForeignItemFn,\n    lang: Lang,\n    trusted: bool,\n    extern_block_cfg: &CfgExpr,\n    namespace: &Namespace,\n    attrs: &OtherAttrs,\n) -> Result<Api> {\n    let mut cfg = extern_block_cfg.clone();\n    let mut doc = Doc::new();\n    let mut namespace = namespace.clone();\n    let mut cxx_name = None;\n    let mut rust_name = None;\n    let mut self_type = None;\n    let mut attrs = attrs.clone();\n    attrs.extend(attrs::parse(\n        cx,\n        mem::take(&mut foreign_fn.attrs),\n        attrs::Parser {\n            cfg: Some(&mut cfg),\n            doc: Some(&mut doc),\n            namespace: Some(&mut namespace),\n            cxx_name: Some(&mut cxx_name),\n            rust_name: Some(&mut rust_name),\n            self_type: Some(&mut self_type),\n            ..Default::default()\n        },\n    ));\n\n    let generics = &foreign_fn.sig.generics;\n    if generics.where_clause.is_some()\n        || generics.params.iter().any(|param| match param {\n            GenericParam::Lifetime(lifetime) => !lifetime.bounds.is_empty(),\n            GenericParam::Type(_) | GenericParam::Const(_) => true,\n        })\n    {\n        return Err(Error::new_spanned(\n            foreign_fn,\n            \"extern function with generic parameters is not supported yet\",\n        ));\n    }\n\n    if let Some(variadic) = &foreign_fn.sig.variadic {\n        return Err(Error::new_spanned(\n            variadic,\n            \"variadic function is not supported yet\",\n        ));\n    }\n\n    if foreign_fn.sig.asyncness.is_some() {\n        return Err(Error::new_spanned(\n            foreign_fn,\n            \"async function is not directly supported yet, but see https://cxx.rs/async.html \\\n            for a working approach, and https://github.com/pcwalton/cxx-async for some helpers; \\\n            eventually what you wrote will work but it isn't integrated into the cxx::bridge \\\n            macro yet\",\n        ));\n    }\n\n    if foreign_fn.sig.constness.is_some() {\n        return Err(Error::new_spanned(\n            foreign_fn,\n            \"const extern function is not supported\",\n        ));\n    }\n\n    if let Some(abi) = &foreign_fn.sig.abi {\n        return Err(Error::new_spanned(\n            abi,\n            \"explicit ABI on extern function is not supported\",\n        ));\n    }\n\n    let mut receiver = None;\n    let mut args = Punctuated::new();\n    for arg in foreign_fn.sig.inputs.pairs() {\n        let (arg, comma) = arg.into_tuple();\n        match arg {\n            FnArg::Receiver(arg) => {\n                if let Some((ampersand, lifetime)) = &arg.reference {\n                    receiver = Some(Receiver {\n                        pinned: false,\n                        ampersand: *ampersand,\n                        lifetime: lifetime.clone(),\n                        mutable: arg.mutability.is_some(),\n                        var: arg.self_token,\n                        colon_token: Token![:](arg.self_token.span),\n                        ty: NamedType::new(Ident::new(\"Self\", arg.self_token.span)),\n                        shorthand: true,\n                        pin_tokens: None,\n                        mutability: arg.mutability,\n                    });\n                    continue;\n                }\n                if let Some(colon_token) = arg.colon_token {\n                    let ty = parse_type(&arg.ty)?;\n                    if let Type::Ref(reference) = ty {\n                        if let Type::Ident(ident) = reference.inner {\n                            receiver = Some(Receiver {\n                                pinned: reference.pinned,\n                                ampersand: reference.ampersand,\n                                lifetime: reference.lifetime,\n                                mutable: reference.mutable,\n                                var: Token![self](ident.rust.span()),\n                                colon_token,\n                                ty: ident,\n                                shorthand: false,\n                                pin_tokens: reference.pin_tokens,\n                                mutability: reference.mutability,\n                            });\n                            continue;\n                        }\n                    }\n                }\n                return Err(Error::new_spanned(arg, \"unsupported method receiver\"));\n            }\n            FnArg::Typed(arg) => {\n                let ident = match arg.pat.as_ref() {\n                    Pat::Ident(pat) => pat.ident.clone(),\n                    Pat::Wild(pat) => {\n                        Ident::new(&format!(\"arg{}\", args.len()), pat.underscore_token.span)\n                    }\n                    _ => return Err(Error::new_spanned(arg, \"unsupported signature\")),\n                };\n                let ty = parse_type(&arg.ty)?;\n                let cfg = CfgExpr::Unconditional;\n                let doc = Doc::new();\n                let attrs = OtherAttrs::new();\n                let visibility = Token![pub](ident.span());\n                let name = pair(Namespace::default(), &ident, None, None);\n                let colon_token = arg.colon_token;\n                args.push_value(Var {\n                    cfg,\n                    doc,\n                    attrs,\n                    visibility,\n                    name,\n                    colon_token,\n                    ty,\n                });\n                if let Some(comma) = comma {\n                    args.push_punct(*comma);\n                }\n            }\n        }\n    }\n\n    let kind = match (self_type, receiver) {\n        (None, None) => FnKind::Free,\n        (Some(self_type), None) => FnKind::Assoc(self_type),\n        (None, Some(receiver)) => FnKind::Method(receiver),\n        (Some(self_type), Some(receiver)) => {\n            let msg = \"function with Self type must not have a `self` argument\";\n            cx.error(self_type, msg);\n            FnKind::Method(receiver)\n        }\n    };\n\n    let mut throws_tokens = None;\n    let ret = parse_return_type(&foreign_fn.sig.output, &mut throws_tokens)?;\n    let throws = throws_tokens.is_some();\n    let asyncness = foreign_fn.sig.asyncness;\n    let unsafety = foreign_fn.sig.unsafety;\n    let fn_token = foreign_fn.sig.fn_token;\n    let inherited_span = unsafety.map_or(fn_token.span, |unsafety| unsafety.span);\n    let visibility = visibility_pub(&foreign_fn.vis, inherited_span);\n    let name = pair(namespace, &foreign_fn.sig.ident, cxx_name, rust_name);\n    let generics = generics.clone();\n    let paren_token = foreign_fn.sig.paren_token;\n    let semi_token = foreign_fn.semi_token;\n\n    Ok(match lang {\n        Lang::Cxx | Lang::CxxUnwind => Api::CxxFunction,\n        Lang::Rust => Api::RustFunction,\n    }(ExternFn {\n        cfg,\n        lang,\n        doc,\n        attrs,\n        visibility,\n        name,\n        sig: Signature {\n            asyncness,\n            unsafety,\n            fn_token,\n            generics,\n            kind,\n            args,\n            ret,\n            throws,\n            paren_token,\n            throws_tokens,\n        },\n        semi_token,\n        trusted,\n    }))\n}\n\nfn parse_extern_verbatim(\n    cx: &mut Errors,\n    tokens: TokenStream,\n    lang: Lang,\n    trusted: bool,\n    extern_block_cfg: &CfgExpr,\n    namespace: &Namespace,\n    attrs: &OtherAttrs,\n) -> Result<Api> {\n    |input: ParseStream| -> Result<Api> {\n        let unparsed_attrs = input.call(Attribute::parse_outer)?;\n        let visibility: Visibility = input.parse()?;\n        if input.peek(Token![type]) {\n            parse_extern_verbatim_type(\n                cx,\n                unparsed_attrs,\n                visibility,\n                input,\n                lang,\n                trusted,\n                extern_block_cfg,\n                namespace,\n                attrs,\n            )\n        } else if input.peek(Token![fn]) {\n            parse_extern_verbatim_fn(input)\n        } else {\n            let span = input.cursor().token_stream();\n            Err(Error::new_spanned(\n                span,\n                \"unsupported foreign item, expected `type` or `fn`\",\n            ))\n        }\n    }\n    .parse2(tokens)\n}\n\nfn parse_extern_verbatim_type(\n    cx: &mut Errors,\n    unparsed_attrs: Vec<Attribute>,\n    visibility: Visibility,\n    input: ParseStream,\n    lang: Lang,\n    trusted: bool,\n    extern_block_cfg: &CfgExpr,\n    namespace: &Namespace,\n    attrs: &OtherAttrs,\n) -> Result<Api> {\n    let type_token: Token![type] = input.parse()?;\n    let ident: Ident = input.parse()?;\n    let generics: Generics = input.parse()?;\n    let lifetimes = extern_type_lifetimes(cx, generics);\n    let lookahead = input.lookahead1();\n    if lookahead.peek(Token![=]) {\n        // type Alias = crate::path::to::Type;\n        parse_type_alias(\n            cx,\n            unparsed_attrs,\n            visibility,\n            type_token,\n            ident,\n            lifetimes,\n            input,\n            lang,\n            extern_block_cfg,\n            namespace,\n            attrs,\n        )\n    } else if lookahead.peek(Token![:]) {\n        // type Opaque: Bound2 + Bound2;\n        parse_extern_type_bounded(\n            cx,\n            unparsed_attrs,\n            visibility,\n            type_token,\n            ident,\n            lifetimes,\n            input,\n            lang,\n            trusted,\n            extern_block_cfg,\n            namespace,\n            attrs,\n        )\n    } else {\n        Err(lookahead.error())\n    }\n}\n\nfn extern_type_lifetimes(cx: &mut Errors, generics: Generics) -> Lifetimes {\n    let mut lifetimes = Punctuated::new();\n    let mut has_unsupported_generic_param = false;\n    for pair in generics.params.into_pairs() {\n        let (param, punct) = pair.into_tuple();\n        match param {\n            GenericParam::Lifetime(param) => {\n                if !param.bounds.is_empty() && !has_unsupported_generic_param {\n                    let msg = \"lifetime parameter with bounds is not supported yet\";\n                    cx.error(&param, msg);\n                    has_unsupported_generic_param = true;\n                }\n                lifetimes.push_value(param.lifetime);\n                if let Some(punct) = punct {\n                    lifetimes.push_punct(punct);\n                }\n            }\n            GenericParam::Type(param) => {\n                if !has_unsupported_generic_param {\n                    let msg = \"extern type with generic type parameter is not supported yet\";\n                    cx.error(&param, msg);\n                    has_unsupported_generic_param = true;\n                }\n            }\n            GenericParam::Const(param) => {\n                if !has_unsupported_generic_param {\n                    let msg = \"extern type with const generic parameter is not supported yet\";\n                    cx.error(&param, msg);\n                    has_unsupported_generic_param = true;\n                }\n            }\n        }\n    }\n    Lifetimes {\n        lt_token: generics.lt_token,\n        lifetimes,\n        gt_token: generics.gt_token,\n    }\n}\n\nfn parse_extern_verbatim_fn(input: ParseStream) -> Result<Api> {\n    input.parse::<RustSignature>()?;\n    input.parse::<Token![;]>()?;\n    unreachable!()\n}\n\nfn parse_type_alias(\n    cx: &mut Errors,\n    unparsed_attrs: Vec<Attribute>,\n    visibility: Visibility,\n    type_token: Token![type],\n    ident: Ident,\n    generics: Lifetimes,\n    input: ParseStream,\n    lang: Lang,\n    extern_block_cfg: &CfgExpr,\n    namespace: &Namespace,\n    attrs: &OtherAttrs,\n) -> Result<Api> {\n    let eq_token: Token![=] = input.parse()?;\n    let ty: RustType = input.parse()?;\n    let semi_token: Token![;] = input.parse()?;\n\n    let mut cfg = extern_block_cfg.clone();\n    let mut doc = Doc::new();\n    let mut derives = Vec::new();\n    let mut namespace = namespace.clone();\n    let mut cxx_name = None;\n    let mut rust_name = None;\n    let mut attrs = attrs.clone();\n    attrs.extend(attrs::parse(\n        cx,\n        unparsed_attrs,\n        attrs::Parser {\n            cfg: Some(&mut cfg),\n            doc: Some(&mut doc),\n            derives: Some(&mut derives),\n            namespace: Some(&mut namespace),\n            cxx_name: Some(&mut cxx_name),\n            rust_name: Some(&mut rust_name),\n            ..Default::default()\n        },\n    ));\n\n    if lang == Lang::Rust {\n        let span = quote!(#type_token #semi_token);\n        let msg = \"type alias in extern \\\"Rust\\\" block is not supported\";\n        return Err(Error::new_spanned(span, msg));\n    }\n\n    let visibility = visibility_pub(&visibility, type_token.span);\n    let name = pair(namespace, &ident, cxx_name, rust_name);\n\n    Ok(Api::TypeAlias(TypeAlias {\n        cfg,\n        doc,\n        derives,\n        attrs,\n        visibility,\n        type_token,\n        name,\n        generics,\n        eq_token,\n        ty,\n        semi_token,\n    }))\n}\n\nfn parse_extern_type_bounded(\n    cx: &mut Errors,\n    unparsed_attrs: Vec<Attribute>,\n    visibility: Visibility,\n    type_token: Token![type],\n    ident: Ident,\n    generics: Lifetimes,\n    input: ParseStream,\n    lang: Lang,\n    trusted: bool,\n    extern_block_cfg: &CfgExpr,\n    namespace: &Namespace,\n    attrs: &OtherAttrs,\n) -> Result<Api> {\n    let mut bounds = Vec::new();\n    let colon_token: Option<Token![:]> = input.parse()?;\n    if colon_token.is_some() {\n        loop {\n            match input.parse()? {\n                TypeParamBound::Trait(TraitBound {\n                    paren_token: None,\n                    modifier: TraitBoundModifier::None,\n                    lifetimes: None,\n                    path,\n                }) if if let Some(derive) = path.get_ident().and_then(Derive::from) {\n                    bounds.push(derive);\n                    true\n                } else {\n                    false\n                } => {}\n                bound => cx.error(bound, \"unsupported trait\"),\n            }\n\n            let lookahead = input.lookahead1();\n            if lookahead.peek(Token![+]) {\n                input.parse::<Token![+]>()?;\n            } else if lookahead.peek(Token![;]) {\n                break;\n            } else {\n                return Err(lookahead.error());\n            }\n        }\n    }\n    let semi_token: Token![;] = input.parse()?;\n\n    let mut cfg = extern_block_cfg.clone();\n    let mut doc = Doc::new();\n    let mut derives = Vec::new();\n    let mut namespace = namespace.clone();\n    let mut cxx_name = None;\n    let mut rust_name = None;\n    let mut attrs = attrs.clone();\n    attrs.extend(attrs::parse(\n        cx,\n        unparsed_attrs,\n        attrs::Parser {\n            cfg: Some(&mut cfg),\n            doc: Some(&mut doc),\n            derives: Some(&mut derives),\n            namespace: Some(&mut namespace),\n            cxx_name: Some(&mut cxx_name),\n            rust_name: Some(&mut rust_name),\n            ..Default::default()\n        },\n    ));\n\n    let visibility = visibility_pub(&visibility, type_token.span);\n    let name = pair(namespace, &ident, cxx_name, rust_name);\n\n    Ok(match lang {\n        Lang::Cxx | Lang::CxxUnwind => Api::CxxType,\n        Lang::Rust => Api::RustType,\n    }(ExternType {\n        cfg,\n        lang,\n        doc,\n        derives,\n        attrs,\n        visibility,\n        type_token,\n        name,\n        generics,\n        colon_token,\n        bounds,\n        semi_token,\n        trusted,\n    }))\n}\n\nfn parse_impl(cx: &mut Errors, imp: ItemImpl) -> Result<Api> {\n    let impl_token = imp.impl_token;\n\n    let mut cfg = CfgExpr::Unconditional;\n    let attrs = attrs::parse(\n        cx,\n        imp.attrs,\n        attrs::Parser {\n            cfg: Some(&mut cfg),\n            ..Default::default()\n        },\n    );\n\n    if !imp.items.is_empty() {\n        let mut span = Group::new(Delimiter::Brace, TokenStream::new());\n        span.set_span(imp.brace_token.span.join());\n        return Err(Error::new_spanned(span, \"expected an empty impl block\"));\n    }\n\n    if let Some((bang, path, for_token)) = &imp.trait_ {\n        let self_ty = &imp.self_ty;\n        let span = quote!(#bang #path #for_token #self_ty);\n        return Err(Error::new_spanned(\n            span,\n            \"unexpected impl, expected something like `impl UniquePtr<T> {}`\",\n        ));\n    }\n\n    if let Some(where_clause) = imp.generics.where_clause {\n        return Err(Error::new_spanned(\n            where_clause,\n            \"where-clause on an impl is not supported yet\",\n        ));\n    }\n    let mut impl_generics = Lifetimes {\n        lt_token: imp.generics.lt_token,\n        lifetimes: Punctuated::new(),\n        gt_token: imp.generics.gt_token,\n    };\n    for pair in imp.generics.params.into_pairs() {\n        let (param, punct) = pair.into_tuple();\n        match param {\n            GenericParam::Lifetime(def) if def.bounds.is_empty() => {\n                impl_generics.lifetimes.push_value(def.lifetime);\n                if let Some(punct) = punct {\n                    impl_generics.lifetimes.push_punct(punct);\n                }\n            }\n            _ => {\n                let span = quote!(#impl_token #impl_generics);\n                return Err(Error::new_spanned(\n                    span,\n                    \"generic parameter on an impl is not supported yet\",\n                ));\n            }\n        }\n    }\n\n    let mut negative_token = None;\n    let mut self_ty = *imp.self_ty;\n    if let RustType::Verbatim(ty) = &self_ty {\n        let mut iter = ty.clone().into_iter();\n        if let Some(TokenTree::Punct(punct)) = iter.next() {\n            if punct.as_char() == '!' {\n                let ty = iter.collect::<TokenStream>();\n                if !ty.is_empty() {\n                    negative_token = Some(Token![!](punct.span()));\n                    self_ty = syn::parse2(ty)?;\n                }\n            }\n        }\n    }\n\n    let ty = parse_type(&self_ty)?;\n\n    let negative = negative_token.is_some();\n    let brace_token = imp.brace_token;\n\n    Ok(Api::Impl(Impl {\n        cfg,\n        attrs,\n        impl_token,\n        impl_generics,\n        negative,\n        ty,\n        brace_token,\n        negative_token,\n    }))\n}\n\nfn parse_include(input: ParseStream) -> Result<Include> {\n    if input.peek(LitStr) {\n        let lit: LitStr = input.parse()?;\n        let span = lit.span();\n        return Ok(Include {\n            cfg: CfgExpr::Unconditional,\n            path: lit.value(),\n            kind: IncludeKind::Quoted,\n            begin_span: span,\n            end_span: span,\n        });\n    }\n\n    if input.peek(Token![<]) {\n        let mut path = String::new();\n\n        let langle: Token![<] = input.parse()?;\n        while !input.is_empty() && !input.peek(Token![>]) {\n            let token: TokenTree = input.parse()?;\n            match token {\n                TokenTree::Ident(token) => path += &token.to_string(),\n                TokenTree::Literal(token)\n                    if token\n                        .to_string()\n                        .starts_with(|ch: char| ch.is_ascii_digit()) =>\n                {\n                    path += &token.to_string();\n                }\n                TokenTree::Punct(token) => path.push(token.as_char()),\n                _ => return Err(Error::new(token.span(), \"unexpected token in include path\")),\n            }\n        }\n        let rangle: Token![>] = input.parse()?;\n\n        return Ok(Include {\n            cfg: CfgExpr::Unconditional,\n            path,\n            kind: IncludeKind::Bracketed,\n            begin_span: langle.span,\n            end_span: rangle.span,\n        });\n    }\n\n    Err(input.error(\"expected \\\"quoted/path/to\\\" or <bracketed/path/to>\"))\n}\n\nfn parse_type(ty: &RustType) -> Result<Type> {\n    match ty {\n        RustType::Reference(ty) => parse_type_reference(ty),\n        RustType::Ptr(ty) => parse_type_ptr(ty),\n        RustType::Path(ty) => parse_type_path(ty),\n        RustType::Array(ty) => parse_type_array(ty),\n        RustType::BareFn(ty) => parse_type_fn(ty),\n        RustType::Tuple(ty) if ty.elems.is_empty() => Ok(Type::Void(ty.paren_token.span.join())),\n        _ => Err(Error::new_spanned(ty, \"unsupported type\")),\n    }\n}\n\nfn parse_type_reference(ty: &TypeReference) -> Result<Type> {\n    let ampersand = ty.and_token;\n    let lifetime = ty.lifetime.clone();\n    let mutable = ty.mutability.is_some();\n    let mutability = ty.mutability;\n\n    if let RustType::Slice(slice) = ty.elem.as_ref() {\n        let inner = parse_type(&slice.elem)?;\n        let bracket = slice.bracket_token;\n        return Ok(Type::SliceRef(Box::new(SliceRef {\n            ampersand,\n            lifetime,\n            mutable,\n            bracket,\n            inner,\n            mutability,\n        })));\n    }\n\n    let inner = parse_type(&ty.elem)?;\n    let pinned = false;\n    let pin_tokens = None;\n\n    Ok(match &inner {\n        Type::Ident(ident) if ident.rust == \"str\" => {\n            if ty.mutability.is_some() {\n                return Err(Error::new_spanned(ty, \"unsupported type\"));\n            } else {\n                Type::Str\n            }\n        }\n        _ => Type::Ref,\n    }(Box::new(Ref {\n        pinned,\n        ampersand,\n        lifetime,\n        mutable,\n        inner,\n        pin_tokens,\n        mutability,\n    })))\n}\n\nfn parse_type_ptr(ty: &TypePtr) -> Result<Type> {\n    let star = ty.star_token;\n    let mutable = ty.mutability.is_some();\n    let constness = ty.const_token;\n    let mutability = ty.mutability;\n\n    let inner = parse_type(&ty.elem)?;\n\n    Ok(Type::Ptr(Box::new(Ptr {\n        star,\n        mutable,\n        inner,\n        mutability,\n        constness,\n    })))\n}\n\nfn parse_type_path(ty: &TypePath) -> Result<Type> {\n    let path = &ty.path;\n    if ty.qself.is_none() && path.leading_colon.is_none() && path.segments.len() == 1 {\n        let segment = &path.segments[0];\n        let ident = segment.ident.clone();\n        match &segment.arguments {\n            PathArguments::None => return Ok(Type::Ident(NamedType::new(ident))),\n            PathArguments::AngleBracketed(generic) => {\n                if ident == \"UniquePtr\" && generic.args.len() == 1 {\n                    if let GenericArgument::Type(arg) = &generic.args[0] {\n                        let inner = parse_type(arg)?;\n                        return Ok(Type::UniquePtr(Box::new(Ty1 {\n                            name: ident,\n                            langle: generic.lt_token,\n                            inner,\n                            rangle: generic.gt_token,\n                        })));\n                    }\n                } else if ident == \"SharedPtr\" && generic.args.len() == 1 {\n                    if let GenericArgument::Type(arg) = &generic.args[0] {\n                        let inner = parse_type(arg)?;\n                        return Ok(Type::SharedPtr(Box::new(Ty1 {\n                            name: ident,\n                            langle: generic.lt_token,\n                            inner,\n                            rangle: generic.gt_token,\n                        })));\n                    }\n                } else if ident == \"WeakPtr\" && generic.args.len() == 1 {\n                    if let GenericArgument::Type(arg) = &generic.args[0] {\n                        let inner = parse_type(arg)?;\n                        return Ok(Type::WeakPtr(Box::new(Ty1 {\n                            name: ident,\n                            langle: generic.lt_token,\n                            inner,\n                            rangle: generic.gt_token,\n                        })));\n                    }\n                } else if ident == \"CxxVector\" && generic.args.len() == 1 {\n                    if let GenericArgument::Type(arg) = &generic.args[0] {\n                        let inner = parse_type(arg)?;\n                        return Ok(Type::CxxVector(Box::new(Ty1 {\n                            name: ident,\n                            langle: generic.lt_token,\n                            inner,\n                            rangle: generic.gt_token,\n                        })));\n                    }\n                } else if ident == \"Box\" && generic.args.len() == 1 {\n                    if let GenericArgument::Type(arg) = &generic.args[0] {\n                        let inner = parse_type(arg)?;\n                        return Ok(Type::RustBox(Box::new(Ty1 {\n                            name: ident,\n                            langle: generic.lt_token,\n                            inner,\n                            rangle: generic.gt_token,\n                        })));\n                    }\n                } else if ident == \"Vec\" && generic.args.len() == 1 {\n                    if let GenericArgument::Type(arg) = &generic.args[0] {\n                        let inner = parse_type(arg)?;\n                        return Ok(Type::RustVec(Box::new(Ty1 {\n                            name: ident,\n                            langle: generic.lt_token,\n                            inner,\n                            rangle: generic.gt_token,\n                        })));\n                    }\n                } else if ident == \"Pin\" && generic.args.len() == 1 {\n                    if let GenericArgument::Type(arg) = &generic.args[0] {\n                        let inner = parse_type(arg)?;\n                        let pin_token = kw::Pin(ident.span());\n                        if let Type::Ref(mut inner) = inner {\n                            inner.pinned = true;\n                            inner.pin_tokens =\n                                Some((pin_token, generic.lt_token, generic.gt_token));\n                            return Ok(Type::Ref(inner));\n                        }\n                    }\n                } else {\n                    let mut lifetimes = Punctuated::new();\n                    let mut only_lifetimes = true;\n                    for pair in generic.args.pairs() {\n                        let (param, punct) = pair.into_tuple();\n                        if let GenericArgument::Lifetime(param) = param {\n                            lifetimes.push_value(param.clone());\n                            if let Some(punct) = punct {\n                                lifetimes.push_punct(*punct);\n                            }\n                        } else {\n                            only_lifetimes = false;\n                            break;\n                        }\n                    }\n                    if only_lifetimes {\n                        return Ok(Type::Ident(NamedType {\n                            rust: ident,\n                            generics: Lifetimes {\n                                lt_token: Some(generic.lt_token),\n                                lifetimes,\n                                gt_token: Some(generic.gt_token),\n                            },\n                        }));\n                    }\n                }\n            }\n            PathArguments::Parenthesized(_) => {}\n        }\n    }\n\n    if ty.qself.is_none() && path.segments.len() == 2 && path.segments[0].ident == \"cxx\" {\n        return Err(Error::new_spanned(\n            ty,\n            \"unexpected `cxx::` qualifier found in a `#[cxx::bridge]`\",\n        ));\n    }\n\n    Err(Error::new_spanned(ty, \"unsupported type\"))\n}\n\nfn parse_type_array(ty: &TypeArray) -> Result<Type> {\n    let inner = parse_type(&ty.elem)?;\n\n    let Expr::Lit(len_expr) = &ty.len else {\n        let msg = \"unsupported expression, array length must be an integer literal\";\n        return Err(Error::new_spanned(&ty.len, msg));\n    };\n\n    let Lit::Int(len_token) = &len_expr.lit else {\n        let msg = \"array length must be an integer literal\";\n        return Err(Error::new_spanned(len_expr, msg));\n    };\n\n    let len = len_token.base10_parse::<usize>()?;\n    if len == 0 {\n        let msg = \"array with zero size is not supported\";\n        return Err(Error::new_spanned(ty, msg));\n    }\n\n    let bracket = ty.bracket_token;\n    let semi_token = ty.semi_token;\n\n    Ok(Type::Array(Box::new(Array {\n        bracket,\n        inner,\n        semi_token,\n        len,\n        len_token: len_token.clone(),\n    })))\n}\n\nfn parse_type_fn(ty: &TypeBareFn) -> Result<Type> {\n    if ty.lifetimes.is_some() {\n        return Err(Error::new_spanned(\n            ty,\n            \"function pointer with lifetime parameters is not supported yet\",\n        ));\n    }\n\n    if ty.variadic.is_some() {\n        return Err(Error::new_spanned(\n            ty,\n            \"variadic function pointer is not supported yet\",\n        ));\n    }\n\n    let args = ty\n        .inputs\n        .iter()\n        .enumerate()\n        .map(|(i, arg)| {\n            let (ident, colon_token) = match &arg.name {\n                Some((ident, colon_token)) => (ident.clone(), *colon_token),\n                None => {\n                    let fn_span = ty.paren_token.span.join();\n                    let ident = format_ident!(\"arg{}\", i, span = fn_span);\n                    let colon_token = Token![:](fn_span);\n                    (ident, colon_token)\n                }\n            };\n            let ty = parse_type(&arg.ty)?;\n            let cfg = CfgExpr::Unconditional;\n            let doc = Doc::new();\n            let attrs = OtherAttrs::new();\n            let visibility = Token![pub](ident.span());\n            let name = pair(Namespace::default(), &ident, None, None);\n            Ok(Var {\n                cfg,\n                doc,\n                attrs,\n                visibility,\n                name,\n                colon_token,\n                ty,\n            })\n        })\n        .collect::<Result<_>>()?;\n\n    let mut throws_tokens = None;\n    let ret = parse_return_type(&ty.output, &mut throws_tokens)?;\n    let throws = throws_tokens.is_some();\n\n    let asyncness = None;\n    let unsafety = ty.unsafety;\n    let fn_token = ty.fn_token;\n    let generics = Generics::default();\n    let kind = FnKind::Free;\n    let paren_token = ty.paren_token;\n\n    Ok(Type::Fn(Box::new(Signature {\n        asyncness,\n        unsafety,\n        fn_token,\n        generics,\n        kind,\n        args,\n        ret,\n        throws,\n        paren_token,\n        throws_tokens,\n    })))\n}\n\nfn parse_return_type(\n    ty: &ReturnType,\n    throws_tokens: &mut Option<(kw::Result, Token![<], Token![>])>,\n) -> Result<Option<Type>> {\n    let mut ret = match ty {\n        ReturnType::Default => return Ok(None),\n        ReturnType::Type(_, ret) => ret.as_ref(),\n    };\n\n    if let RustType::Path(ty) = ret {\n        let path = &ty.path;\n        if ty.qself.is_none() && path.leading_colon.is_none() && path.segments.len() == 1 {\n            let segment = &path.segments[0];\n            let ident = segment.ident.clone();\n            if let PathArguments::AngleBracketed(generic) = &segment.arguments {\n                if ident == \"Result\" && generic.args.len() == 1 {\n                    if let GenericArgument::Type(arg) = &generic.args[0] {\n                        ret = arg;\n                        *throws_tokens =\n                            Some((kw::Result(ident.span()), generic.lt_token, generic.gt_token));\n                    }\n                }\n            }\n        }\n    }\n\n    match parse_type(ret)? {\n        Type::Void(_) => Ok(None),\n        ty => Ok(Some(ty)),\n    }\n}\n\nfn visibility_pub(vis: &Visibility, inherited: Span) -> Token![pub] {\n    Token![pub](match vis {\n        Visibility::Public(vis) => vis.span,\n        Visibility::Restricted(vis) => vis.pub_token.span,\n        Visibility::Inherited => inherited,\n    })\n}\n\nfn pair(\n    namespace: Namespace,\n    default: &Ident,\n    cxx: Option<ForeignName>,\n    rust: Option<Ident>,\n) -> Pair {\n    Pair {\n        namespace,\n        cxx: cxx\n            .unwrap_or_else(|| ForeignName::parse(&default.to_string(), default.span()).unwrap()),\n        rust: rust.unwrap_or_else(|| default.clone()),\n    }\n}\n"
  },
  {
    "path": "syntax/pod.rs",
    "content": "use crate::syntax::atom::Atom::{self, *};\nuse crate::syntax::query::TypeQuery;\nuse crate::syntax::{primitive, Types};\n\nimpl<'a> Types<'a> {\n    pub(crate) fn is_guaranteed_pod(&self, ty: impl Into<TypeQuery<'a>>) -> bool {\n        match ty.into() {\n            TypeQuery::Ident(ident) => {\n                let ident = &ident.rust;\n                if let Some(atom) = Atom::from(ident) {\n                    match atom {\n                        Bool | Char | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64\n                        | Isize | F32 | F64 => true,\n                        CxxString | RustString => false,\n                    }\n                } else if let Some(strct) = self.structs.get(ident) {\n                    strct.fields.iter().all(|field| {\n                        primitive::kind(&field.ty).is_none() && self.is_guaranteed_pod(&field.ty)\n                    })\n                } else {\n                    self.enums.contains_key(ident)\n                }\n            }\n            TypeQuery::RustBox\n            | TypeQuery::RustVec\n            | TypeQuery::UniquePtr\n            | TypeQuery::SharedPtr\n            | TypeQuery::WeakPtr\n            | TypeQuery::CxxVector\n            | TypeQuery::Void => false,\n            TypeQuery::Ref(_)\n            | TypeQuery::Str\n            | TypeQuery::Fn\n            | TypeQuery::SliceRef\n            | TypeQuery::Ptr(_) => true,\n            TypeQuery::Array(array) => self.is_guaranteed_pod(&array.inner),\n        }\n    }\n}\n"
  },
  {
    "path": "syntax/primitive.rs",
    "content": "use crate::syntax::atom::Atom::{self, *};\nuse crate::syntax::Type;\n\npub(crate) enum PrimitiveKind {\n    Boolean,\n    Number,\n    Pointer,\n}\n\npub(crate) fn kind(ty: &Type) -> Option<PrimitiveKind> {\n    match ty {\n        Type::Ident(ident) => Atom::from(&ident.rust).and_then(|atom| match atom {\n            Bool => Some(PrimitiveKind::Boolean),\n            Char | U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize | F32 | F64 => {\n                Some(PrimitiveKind::Number)\n            }\n            CxxString | RustString => None,\n        }),\n        Type::Ptr(_) => Some(PrimitiveKind::Pointer),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "syntax/qualified.rs",
    "content": "use syn::ext::IdentExt;\nuse syn::parse::{Error, ParseStream, Result};\nuse syn::{Ident, LitStr, Token};\n\npub(crate) struct QualifiedName {\n    pub segments: Vec<Ident>,\n}\n\nimpl QualifiedName {\n    pub(crate) fn parse_quoted(lit: &LitStr) -> Result<Self> {\n        if lit.value().is_empty() {\n            let segments = Vec::new();\n            Ok(QualifiedName { segments })\n        } else {\n            lit.parse_with(|input: ParseStream| {\n                let allow_raw = false;\n                parse_unquoted(input, allow_raw)\n            })\n        }\n    }\n\n    pub(crate) fn parse_unquoted(input: ParseStream) -> Result<Self> {\n        let allow_raw = true;\n        parse_unquoted(input, allow_raw)\n    }\n\n    pub(crate) fn parse_quoted_or_unquoted(input: ParseStream) -> Result<Self> {\n        if input.peek(LitStr) {\n            let lit: LitStr = input.parse()?;\n            Self::parse_quoted(&lit)\n        } else {\n            Self::parse_unquoted(input)\n        }\n    }\n}\n\nfn parse_unquoted(input: ParseStream, allow_raw: bool) -> Result<QualifiedName> {\n    let mut segments = Vec::new();\n    let mut trailing_punct = true;\n    let leading_colons: Option<Token![::]> = input.parse()?;\n    while trailing_punct && input.peek(Ident::peek_any) {\n        let mut ident = Ident::parse_any(input)?;\n        if let Some(unraw) = ident.to_string().strip_prefix(\"r#\") {\n            if !allow_raw {\n                let msg = format!(\n                    \"raw identifier `{}` is not allowed in a quoted namespace; use `{}`, or remove quotes\",\n                    ident, unraw,\n                );\n                return Err(Error::new(ident.span(), msg));\n            }\n            ident = Ident::new(unraw, ident.span());\n        }\n        segments.push(ident);\n        let colons: Option<Token![::]> = input.parse()?;\n        trailing_punct = colons.is_some();\n    }\n    if segments.is_empty() && leading_colons.is_none() {\n        return Err(input.error(\"expected path\"));\n    } else if trailing_punct {\n        return Err(input.error(\"expected path segment\"));\n    }\n    Ok(QualifiedName { segments })\n}\n"
  },
  {
    "path": "syntax/query.rs",
    "content": "use crate::syntax::{Array, NamedType, Ptr, Ref, Type};\n\n#[derive(Copy, Clone)]\npub(crate) enum TypeQuery<'a> {\n    Ident(&'a NamedType),\n    RustBox,\n    RustVec,\n    UniquePtr,\n    SharedPtr,\n    WeakPtr,\n    Ref(&'a Ref),\n    Ptr(&'a Ptr),\n    Str,\n    CxxVector,\n    Fn,\n    Void,\n    SliceRef,\n    Array(&'a Array),\n}\n\nimpl<'a> From<&'a NamedType> for TypeQuery<'a> {\n    fn from(query: &'a NamedType) -> Self {\n        TypeQuery::Ident(query)\n    }\n}\n\nimpl<'a> From<&'a Type> for TypeQuery<'a> {\n    fn from(query: &'a Type) -> Self {\n        match query {\n            Type::Ident(query) => TypeQuery::Ident(query),\n            Type::RustBox(_) => TypeQuery::RustBox,\n            Type::RustVec(_) => TypeQuery::RustVec,\n            Type::UniquePtr(_) => TypeQuery::UniquePtr,\n            Type::SharedPtr(_) => TypeQuery::SharedPtr,\n            Type::WeakPtr(_) => TypeQuery::WeakPtr,\n            Type::Ref(query) => TypeQuery::Ref(query),\n            Type::Ptr(query) => TypeQuery::Ptr(query),\n            Type::Str(_) => TypeQuery::Str,\n            Type::CxxVector(_) => TypeQuery::CxxVector,\n            Type::Fn(_) => TypeQuery::Fn,\n            Type::Void(_) => TypeQuery::Void,\n            Type::SliceRef(_) => TypeQuery::SliceRef,\n            Type::Array(query) => TypeQuery::Array(query),\n        }\n    }\n}\n"
  },
  {
    "path": "syntax/report.rs",
    "content": "use quote::ToTokens;\nuse std::fmt::Display;\nuse syn::{Error, Result};\n\npub(crate) struct Errors {\n    errors: Vec<Error>,\n}\n\nimpl Errors {\n    pub(crate) fn new() -> Self {\n        Errors { errors: Vec::new() }\n    }\n\n    pub(crate) fn error(&mut self, sp: impl ToTokens, msg: impl Display) {\n        self.errors.push(Error::new_spanned(sp, msg));\n    }\n\n    pub(crate) fn push(&mut self, error: Error) {\n        self.errors.push(error);\n    }\n\n    pub(crate) fn propagate(&mut self) -> Result<()> {\n        let mut iter = self.errors.drain(..);\n        let Some(mut all_errors) = iter.next() else {\n            return Ok(());\n        };\n        for err in iter {\n            all_errors.combine(err);\n        }\n        Err(all_errors)\n    }\n}\n"
  },
  {
    "path": "syntax/repr.rs",
    "content": "use crate::syntax::Atom::{self, *};\nuse proc_macro2::{Ident, Span};\nuse syn::parse::{Error, Parse, ParseStream, Result};\nuse syn::{parenthesized, Expr, LitInt};\n\npub(crate) enum Repr {\n    Align(LitInt),\n    Atom(Atom, Span),\n}\n\nimpl Parse for Repr {\n    fn parse(input: ParseStream) -> Result<Self> {\n        let begin = input.cursor();\n        let ident: Ident = input.parse()?;\n        if let Some(atom) = Atom::from(&ident) {\n            match atom {\n                U8 | U16 | U32 | U64 | Usize | I8 | I16 | I32 | I64 | Isize if input.is_empty() => {\n                    return Ok(Repr::Atom(atom, ident.span()));\n                }\n                _ => {}\n            }\n        } else if ident == \"align\" {\n            let content;\n            parenthesized!(content in input);\n            let align_expr: Expr = content.fork().parse()?;\n            if !matches!(align_expr, Expr::Lit(_)) {\n                return Err(Error::new_spanned(\n                    align_expr,\n                    \"invalid repr(align) attribute: an arithmetic expression is not supported\",\n                ));\n            }\n            let align_lit: LitInt = content.parse()?;\n            let align: u32 = align_lit.base10_parse()?;\n            if !align.is_power_of_two() {\n                return Err(Error::new_spanned(\n                    align_lit,\n                    \"invalid repr(align) attribute: not a power of two\",\n                ));\n            }\n            if align > 2u32.pow(13) {\n                return Err(Error::new_spanned(\n                    align_lit,\n                    \"invalid repr(align) attribute: larger than 2^13\",\n                ));\n            }\n            return Ok(Repr::Align(align_lit));\n        }\n        Err(Error::new_spanned(\n            begin.token_stream(),\n            \"unrecognized repr\",\n        ))\n    }\n}\n"
  },
  {
    "path": "syntax/resolve.rs",
    "content": "use crate::syntax::attrs::OtherAttrs;\nuse crate::syntax::{Lifetimes, NamedType, Pair, Types};\nuse proc_macro2::Ident;\n\n#[derive(Copy, Clone)]\npub(crate) struct Resolution<'a> {\n    pub name: &'a Pair,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub attrs: &'a OtherAttrs,\n    pub generics: &'a Lifetimes,\n}\n\nimpl<'a> Types<'a> {\n    pub(crate) fn resolve(&self, ident: &impl UnresolvedName) -> Resolution<'a> {\n        let ident = ident.ident();\n        match self.try_resolve(ident) {\n            Some(resolution) => resolution,\n            None => panic!(\"Unable to resolve type `{}`\", ident),\n        }\n    }\n\n    pub(crate) fn try_resolve(&self, ident: &impl UnresolvedName) -> Option<Resolution<'a>> {\n        let ident = ident.ident();\n        self.resolutions.get(ident).copied()\n    }\n}\n\npub(crate) trait UnresolvedName {\n    fn ident(&self) -> &Ident;\n}\n\nimpl UnresolvedName for Ident {\n    fn ident(&self) -> &Ident {\n        self\n    }\n}\n\nimpl UnresolvedName for NamedType {\n    fn ident(&self) -> &Ident {\n        &self.rust\n    }\n}\n"
  },
  {
    "path": "syntax/set.rs",
    "content": "use std::fmt::{self, Debug};\nuse std::slice;\n\npub(crate) use self::ordered::OrderedSet;\npub(crate) use self::unordered::UnorderedSet;\n\nmod ordered {\n    use super::{Iter, UnorderedSet};\n    use std::hash::Hash;\n\n    pub(crate) struct OrderedSet<T> {\n        set: UnorderedSet<T>,\n        vec: Vec<T>,\n    }\n\n    impl<'a, T> OrderedSet<&'a T>\n    where\n        T: Hash + Eq,\n    {\n        pub(crate) fn new() -> Self {\n            OrderedSet {\n                set: UnorderedSet::new(),\n                vec: Vec::new(),\n            }\n        }\n\n        pub(crate) fn insert(&mut self, value: &'a T) -> bool {\n            let new = self.set.insert(value);\n            if new {\n                self.vec.push(value);\n            }\n            new\n        }\n    }\n\n    impl<'a, T> OrderedSet<&'a T> {\n        pub(crate) fn is_empty(&self) -> bool {\n            self.vec.is_empty()\n        }\n\n        pub(crate) fn iter(&self) -> Iter<'_, 'a, T> {\n            Iter(self.vec.iter())\n        }\n    }\n\n    impl<'s, 'a, T> IntoIterator for &'s OrderedSet<&'a T> {\n        type Item = &'a T;\n        type IntoIter = Iter<'s, 'a, T>;\n        fn into_iter(self) -> Self::IntoIter {\n            self.iter()\n        }\n    }\n\n    impl<'a, T> IntoIterator for OrderedSet<&'a T> {\n        type Item = &'a T;\n        type IntoIter = <Vec<&'a T> as IntoIterator>::IntoIter;\n        fn into_iter(self) -> Self::IntoIter {\n            self.vec.into_iter()\n        }\n    }\n}\n\nmod unordered {\n    use std::borrow::Borrow;\n    use std::collections::HashSet;\n    use std::hash::Hash;\n\n    // Wrapper prohibits accidentally introducing iteration over the set, which\n    // could lead to nondeterministic generated code.\n    pub(crate) struct UnorderedSet<T>(HashSet<T>);\n\n    impl<T> UnorderedSet<T>\n    where\n        T: Hash + Eq,\n    {\n        pub(crate) fn new() -> Self {\n            UnorderedSet(HashSet::new())\n        }\n\n        pub(crate) fn insert(&mut self, value: T) -> bool {\n            self.0.insert(value)\n        }\n\n        pub(crate) fn contains<Q>(&self, value: &Q) -> bool\n        where\n            T: Borrow<Q>,\n            Q: ?Sized + Hash + Eq,\n        {\n            self.0.contains(value)\n        }\n\n        #[allow(dead_code)] // only used by cxx-build, not cxxbridge-cmd\n        pub(crate) fn get<Q>(&self, value: &Q) -> Option<&T>\n        where\n            T: Borrow<Q>,\n            Q: ?Sized + Hash + Eq,\n        {\n            self.0.get(value)\n        }\n\n        pub(crate) fn retain(&mut self, f: impl FnMut(&T) -> bool) {\n            self.0.retain(f);\n        }\n\n        #[cfg_attr(not(proc_macro), expect(dead_code))]\n        pub(crate) fn extend(&mut self, iter: impl IntoIterator<Item = T>) {\n            for value in iter {\n                self.insert(value);\n            }\n        }\n    }\n}\n\npub(crate) struct Iter<'s, 'a, T>(slice::Iter<'s, &'a T>);\n\nimpl<'s, 'a, T> Iterator for Iter<'s, 'a, T> {\n    type Item = &'a T;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.0.next().copied()\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.0.size_hint()\n    }\n}\n\nimpl<T> Debug for OrderedSet<&T>\nwhere\n    T: Debug,\n{\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        formatter.debug_set().entries(self).finish()\n    }\n}\n"
  },
  {
    "path": "syntax/signature.rs",
    "content": "use crate::syntax::set::{OrderedSet, UnorderedSet};\nuse crate::syntax::{FnKind, Receiver, Signature, Type};\nuse proc_macro2::Ident;\nuse syn::Lifetime;\n\nimpl Signature {\n    pub fn receiver(&self) -> Option<&Receiver> {\n        match &self.kind {\n            FnKind::Method(receiver) => Some(receiver),\n            FnKind::Assoc(_) | FnKind::Free => None,\n        }\n    }\n\n    pub fn receiver_mut(&mut self) -> Option<&mut Receiver> {\n        match &mut self.kind {\n            FnKind::Method(receiver) => Some(receiver),\n            FnKind::Assoc(_) | FnKind::Free => None,\n        }\n    }\n\n    pub fn self_type(&self) -> Option<&Ident> {\n        match &self.kind {\n            FnKind::Method(receiver) => Some(&receiver.ty.rust),\n            FnKind::Assoc(self_type) => Some(self_type),\n            FnKind::Free => None,\n        }\n    }\n\n    #[cfg_attr(not(proc_macro), allow(dead_code))]\n    pub fn undeclared_lifetimes<'a>(&'a self) -> OrderedSet<&'a Lifetime> {\n        let mut declared_lifetimes = UnorderedSet::new();\n        for param in self.generics.lifetimes() {\n            declared_lifetimes.insert(&param.lifetime);\n        }\n\n        let mut undeclared_lifetimes = OrderedSet::new();\n        let mut collect_lifetime = |lifetime: &'a Lifetime| {\n            if lifetime.ident != \"_\"\n                && lifetime.ident != \"static\"\n                && !declared_lifetimes.contains(lifetime)\n            {\n                undeclared_lifetimes.insert(lifetime);\n            }\n        };\n\n        match &self.kind {\n            FnKind::Method(receiver) => {\n                if let Some(lifetime) = &receiver.lifetime {\n                    collect_lifetime(lifetime);\n                }\n                for lifetime in &receiver.ty.generics.lifetimes {\n                    collect_lifetime(lifetime);\n                }\n            }\n            FnKind::Assoc(self_type) => {\n                // If support is added for explicit lifetimes in the Self type\n                // of static member functions, that needs to be handled here.\n                let _: &Ident = self_type;\n            }\n            FnKind::Free => {}\n        }\n\n        fn collect_type<'a>(collect_lifetime: &mut impl FnMut(&'a Lifetime), ty: &'a Type) {\n            match ty {\n                Type::Ident(named_type) => {\n                    for lifetime in &named_type.generics.lifetimes {\n                        collect_lifetime(lifetime);\n                    }\n                }\n                Type::RustBox(ty1)\n                | Type::RustVec(ty1)\n                | Type::UniquePtr(ty1)\n                | Type::SharedPtr(ty1)\n                | Type::WeakPtr(ty1)\n                | Type::CxxVector(ty1) => collect_type(collect_lifetime, &ty1.inner),\n                Type::Ref(ty) | Type::Str(ty) => {\n                    if let Some(lifetime) = &ty.lifetime {\n                        collect_lifetime(lifetime);\n                    }\n                    collect_type(collect_lifetime, &ty.inner);\n                }\n                Type::Ptr(ty) => collect_type(collect_lifetime, &ty.inner),\n                Type::Fn(signature) => {\n                    for lifetime in signature.undeclared_lifetimes() {\n                        collect_lifetime(lifetime);\n                    }\n                }\n                Type::Void(_) => {}\n                Type::SliceRef(ty) => {\n                    if let Some(lifetime) = &ty.lifetime {\n                        collect_lifetime(lifetime);\n                    }\n                    collect_type(collect_lifetime, &ty.inner);\n                }\n                Type::Array(ty) => collect_type(collect_lifetime, &ty.inner),\n            }\n        }\n\n        for arg in &self.args {\n            collect_type(&mut collect_lifetime, &arg.ty);\n        }\n\n        if let Some(ret) = &self.ret {\n            collect_type(&mut collect_lifetime, ret);\n        }\n\n        undeclared_lifetimes\n    }\n}\n"
  },
  {
    "path": "syntax/symbol.rs",
    "content": "use crate::syntax::namespace::Namespace;\nuse crate::syntax::{ForeignName, Pair};\nuse proc_macro2::{Ident, TokenStream};\nuse quote::ToTokens;\nuse std::fmt::{self, Display, Write};\n\n// A mangled symbol consisting of segments separated by '$'.\n// Example: cxxbridge1$string$new\n#[derive(Eq, Hash, PartialEq)]\npub(crate) struct Symbol(String);\n\nimpl Display for Symbol {\n    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {\n        Display::fmt(&self.0, formatter)\n    }\n}\n\nimpl ToTokens for Symbol {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        ToTokens::to_tokens(&self.0, tokens);\n    }\n}\n\nimpl Symbol {\n    fn push(&mut self, segment: &dyn Display) {\n        let len_before = self.0.len();\n        if !self.0.is_empty() {\n            self.0.push('$');\n        }\n        self.0.write_fmt(format_args!(\"{}\", segment)).unwrap();\n        assert!(self.0.len() > len_before);\n    }\n\n    pub(crate) fn from_idents<'a>(it: impl Iterator<Item = &'a dyn Segment>) -> Self {\n        let mut symbol = Symbol(String::new());\n        for segment in it {\n            segment.write(&mut symbol);\n        }\n        assert!(!symbol.0.is_empty());\n        symbol\n    }\n\n    #[cfg_attr(proc_macro, expect(dead_code))]\n    pub(crate) fn contains(&self, ch: char) -> bool {\n        self.0.contains(ch)\n    }\n}\n\npub(crate) trait Segment {\n    fn write(&self, symbol: &mut Symbol);\n}\n\nimpl Segment for str {\n    fn write(&self, symbol: &mut Symbol) {\n        symbol.push(&self);\n    }\n}\n\nimpl Segment for usize {\n    fn write(&self, symbol: &mut Symbol) {\n        symbol.push(&self);\n    }\n}\n\nimpl Segment for Ident {\n    fn write(&self, symbol: &mut Symbol) {\n        symbol.push(&self);\n    }\n}\n\nimpl Segment for Symbol {\n    fn write(&self, symbol: &mut Symbol) {\n        symbol.push(&self);\n    }\n}\n\nimpl Segment for Namespace {\n    fn write(&self, symbol: &mut Symbol) {\n        for segment in self {\n            symbol.push(segment);\n        }\n    }\n}\n\nimpl Segment for Pair {\n    fn write(&self, symbol: &mut Symbol) {\n        self.namespace.write(symbol);\n        self.cxx.write(symbol);\n    }\n}\n\nimpl Segment for ForeignName {\n    fn write(&self, symbol: &mut Symbol) {\n        // TODO: support C++ names containing whitespace (`unsigned int`) or\n        // non-alphanumeric characters (`operator++`).\n        self.to_string().write(symbol);\n    }\n}\n\nimpl<T> Segment for &'_ T\nwhere\n    T: ?Sized + Segment + Display,\n{\n    fn write(&self, symbol: &mut Symbol) {\n        (**self).write(symbol);\n    }\n}\n\npub(crate) fn join(segments: &[&dyn Segment]) -> Symbol {\n    let mut symbol = Symbol(String::new());\n    for segment in segments {\n        segment.write(&mut symbol);\n    }\n    assert!(!symbol.0.is_empty());\n    symbol\n}\n"
  },
  {
    "path": "syntax/tokens.rs",
    "content": "use crate::syntax::atom::Atom::*;\nuse crate::syntax::{\n    Array, Atom, Derive, Enum, EnumRepr, ExternFn, ExternType, Impl, Lifetimes, NamedType, Ptr,\n    Ref, Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var,\n};\nuse proc_macro2::{Ident, Span, TokenStream};\nuse quote::{quote_spanned, ToTokens};\nuse syn::{token, Token};\n\nimpl ToTokens for Type {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        match self {\n            Type::Ident(ident) => {\n                if ident.rust == Char {\n                    let span = ident.rust.span();\n                    tokens.extend(quote_spanned!(span=> ::cxx::core::ffi::));\n                } else if ident.rust == CxxString {\n                    let span = ident.rust.span();\n                    tokens.extend(quote_spanned!(span=> ::cxx::));\n                } else if ident.rust == RustString {\n                    let span = ident.rust.span();\n                    tokens.extend(quote_spanned!(span=> ::cxx::alloc::string::));\n                }\n                ident.to_tokens(tokens);\n            }\n            Type::RustBox(ty)\n            | Type::UniquePtr(ty)\n            | Type::SharedPtr(ty)\n            | Type::WeakPtr(ty)\n            | Type::CxxVector(ty)\n            | Type::RustVec(ty) => ty.to_tokens(tokens),\n            Type::Ref(r) | Type::Str(r) => r.to_tokens(tokens),\n            Type::Ptr(p) => p.to_tokens(tokens),\n            Type::Array(a) => a.to_tokens(tokens),\n            Type::Fn(f) => f.to_tokens(tokens),\n            Type::Void(span) => tokens.extend(quote_spanned!(*span=> ())),\n            Type::SliceRef(r) => r.to_tokens(tokens),\n        }\n    }\n}\n\nimpl ToTokens for Var {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let Var {\n            cfg: _,\n            doc: _,\n            attrs: _,\n            visibility: _,\n            name,\n            colon_token: _,\n            ty,\n        } = self;\n        name.rust.to_tokens(tokens);\n        Token![:](name.rust.span()).to_tokens(tokens);\n        ty.to_tokens(tokens);\n    }\n}\n\nimpl ToTokens for Ty1 {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let Ty1 {\n            name,\n            langle,\n            inner,\n            rangle,\n        } = self;\n        let span = name.span();\n        match name.to_string().as_str() {\n            \"UniquePtr\" | \"SharedPtr\" | \"WeakPtr\" | \"CxxVector\" => {\n                tokens.extend(quote_spanned!(span=> ::cxx::));\n            }\n            \"Box\" => {\n                tokens.extend(quote_spanned!(span=> ::cxx::alloc::boxed::));\n            }\n            \"Vec\" => {\n                tokens.extend(quote_spanned!(span=> ::cxx::alloc::vec::));\n            }\n            _ => {}\n        }\n        name.to_tokens(tokens);\n        langle.to_tokens(tokens);\n        inner.to_tokens(tokens);\n        rangle.to_tokens(tokens);\n    }\n}\n\nimpl ToTokens for Ref {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let Ref {\n            pinned: _,\n            ampersand,\n            lifetime,\n            mutable: _,\n            inner,\n            pin_tokens,\n            mutability,\n        } = self;\n        if let Some((pin, langle, _rangle)) = pin_tokens {\n            tokens.extend(quote_spanned!(pin.span=> ::cxx::core::pin::Pin));\n            langle.to_tokens(tokens);\n        }\n        ampersand.to_tokens(tokens);\n        lifetime.to_tokens(tokens);\n        mutability.to_tokens(tokens);\n        inner.to_tokens(tokens);\n        if let Some((_pin, _langle, rangle)) = pin_tokens {\n            rangle.to_tokens(tokens);\n        }\n    }\n}\n\nimpl ToTokens for Ptr {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let Ptr {\n            star,\n            mutable: _,\n            inner,\n            mutability,\n            constness,\n        } = self;\n        star.to_tokens(tokens);\n        mutability.to_tokens(tokens);\n        constness.to_tokens(tokens);\n        inner.to_tokens(tokens);\n    }\n}\n\nimpl ToTokens for SliceRef {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let SliceRef {\n            ampersand,\n            lifetime,\n            mutable: _,\n            bracket,\n            inner,\n            mutability,\n        } = self;\n        ampersand.to_tokens(tokens);\n        lifetime.to_tokens(tokens);\n        mutability.to_tokens(tokens);\n        bracket.surround(tokens, |tokens| {\n            inner.to_tokens(tokens);\n        });\n    }\n}\n\nimpl ToTokens for Array {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let Array {\n            bracket,\n            inner,\n            semi_token,\n            len: _,\n            len_token,\n        } = self;\n        bracket.surround(tokens, |tokens| {\n            inner.to_tokens(tokens);\n            semi_token.to_tokens(tokens);\n            len_token.to_tokens(tokens);\n        });\n    }\n}\n\nimpl ToTokens for Atom {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        Ident::new(self.as_ref(), Span::call_site()).to_tokens(tokens);\n    }\n}\n\nimpl ToTokens for Derive {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        Ident::new(self.what.as_ref(), self.span).to_tokens(tokens);\n    }\n}\n\nimpl ToTokens for ExternType {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        // Notional token range for error reporting purposes.\n        self.type_token.to_tokens(tokens);\n        self.name.rust.to_tokens(tokens);\n        self.generics.to_tokens(tokens);\n    }\n}\n\nimpl ToTokens for TypeAlias {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        // Notional token range for error reporting purposes.\n        self.type_token.to_tokens(tokens);\n        self.name.rust.to_tokens(tokens);\n        self.generics.to_tokens(tokens);\n    }\n}\n\nimpl ToTokens for Struct {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        // Notional token range for error reporting purposes.\n        self.struct_token.to_tokens(tokens);\n        self.name.rust.to_tokens(tokens);\n        self.generics.to_tokens(tokens);\n    }\n}\n\nimpl ToTokens for Enum {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        // Notional token range for error reporting purposes.\n        self.enum_token.to_tokens(tokens);\n        self.name.rust.to_tokens(tokens);\n        self.generics.to_tokens(tokens);\n    }\n}\n\nimpl ToTokens for ExternFn {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        // Notional token range for error reporting purposes.\n        self.unsafety.to_tokens(tokens);\n        self.fn_token.to_tokens(tokens);\n        self.semi_token.to_tokens(tokens);\n    }\n}\n\nimpl ToTokens for Impl {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let Impl {\n            cfg: _,\n            attrs: _,\n            impl_token,\n            impl_generics,\n            negative: _,\n            ty,\n            brace_token,\n            negative_token,\n        } = self;\n        impl_token.to_tokens(tokens);\n        impl_generics.to_tokens(tokens);\n        negative_token.to_tokens(tokens);\n        ty.to_tokens(tokens);\n        brace_token.surround(tokens, |_tokens| {});\n    }\n}\n\nimpl ToTokens for Lifetimes {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let Lifetimes {\n            lt_token,\n            lifetimes,\n            gt_token,\n        } = self;\n        lt_token.to_tokens(tokens);\n        lifetimes.to_tokens(tokens);\n        gt_token.to_tokens(tokens);\n    }\n}\n\nimpl ToTokens for Signature {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let Signature {\n            asyncness: _,\n            unsafety: _,\n            fn_token,\n            generics: _,\n            kind: _,\n            args,\n            ret,\n            throws: _,\n            paren_token,\n            throws_tokens,\n        } = self;\n        fn_token.to_tokens(tokens);\n        paren_token.surround(tokens, |tokens| {\n            args.to_tokens(tokens);\n        });\n        if let Some(ret) = ret {\n            Token![->](paren_token.span.join()).to_tokens(tokens);\n            if let Some((result, langle, rangle)) = throws_tokens {\n                result.to_tokens(tokens);\n                langle.to_tokens(tokens);\n                ret.to_tokens(tokens);\n                rangle.to_tokens(tokens);\n            } else {\n                ret.to_tokens(tokens);\n            }\n        } else if let Some((result, langle, rangle)) = throws_tokens {\n            Token![->](paren_token.span.join()).to_tokens(tokens);\n            result.to_tokens(tokens);\n            langle.to_tokens(tokens);\n            token::Paren(langle.span).surround(tokens, |_| ());\n            rangle.to_tokens(tokens);\n        }\n    }\n}\n\nimpl ToTokens for EnumRepr {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let EnumRepr { atom, repr_type: _ } = self;\n        atom.to_tokens(tokens);\n    }\n}\n\nimpl ToTokens for NamedType {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let NamedType { rust, generics } = self;\n        rust.to_tokens(tokens);\n        generics.to_tokens(tokens);\n    }\n}\n"
  },
  {
    "path": "syntax/toposort.rs",
    "content": "use crate::syntax::map::{Entry, UnorderedMap as Map};\nuse crate::syntax::report::Errors;\nuse crate::syntax::{Api, Struct, Type, Types};\n\nenum Mark {\n    Visiting,\n    Visited,\n}\n\npub(crate) fn sort<'a>(cx: &mut Errors, apis: &'a [Api], types: &Types<'a>) -> Vec<&'a Struct> {\n    let mut sorted = Vec::new();\n    let ref mut marks = Map::new();\n    for api in apis {\n        if let Api::Struct(strct) = api {\n            let _ = visit(cx, strct, &mut sorted, marks, types);\n        }\n    }\n    sorted\n}\n\nfn visit<'a>(\n    cx: &mut Errors,\n    strct: &'a Struct,\n    sorted: &mut Vec<&'a Struct>,\n    marks: &mut Map<*const Struct, Mark>,\n    types: &Types<'a>,\n) -> Result<(), ()> {\n    match marks.entry(strct) {\n        Entry::Occupied(entry) => match entry.get() {\n            Mark::Visiting => return Err(()), // not a DAG\n            Mark::Visited => return Ok(()),\n        },\n        Entry::Vacant(entry) => {\n            entry.insert(Mark::Visiting);\n        }\n    }\n    let mut result = Ok(());\n    for field in &strct.fields {\n        if let Type::Ident(ident) = &field.ty {\n            if let Some(inner) = types.structs.get(&ident.rust) {\n                if visit(cx, inner, sorted, marks, types).is_err() {\n                    cx.error(field, \"unsupported cyclic data structure\");\n                    result = Err(());\n                }\n            }\n        }\n    }\n    marks.insert(strct, Mark::Visited);\n    sorted.push(strct);\n    result\n}\n"
  },
  {
    "path": "syntax/trivial.rs",
    "content": "use crate::syntax::cfg::ComputedCfg;\nuse crate::syntax::instantiate::ImplKey;\nuse crate::syntax::map::{OrderedMap, UnorderedMap};\nuse crate::syntax::resolve::Resolution;\nuse crate::syntax::set::{OrderedSet as Set, UnorderedSet};\nuse crate::syntax::types::ConditionalImpl;\nuse crate::syntax::{Api, Enum, ExternFn, NamedType, Pair, SliceRef, Struct, Type, TypeAlias};\nuse proc_macro2::Ident;\nuse std::fmt::{self, Display};\n\n#[derive(Copy, Clone)]\npub(crate) enum TrivialReason<'a> {\n    StructField(&'a Struct),\n    FunctionArgument(&'a ExternFn),\n    FunctionReturn(&'a ExternFn),\n    BoxTarget {\n        // Whether the extern functions used by rust::Box are being produced\n        // within this cxx::bridge expansion, as opposed to the boxed type being\n        // a type alias from a different module.\n        #[cfg_attr(not(proc_macro), expect(dead_code))]\n        local: bool,\n    },\n    VecElement {\n        #[cfg_attr(not(proc_macro), expect(dead_code))]\n        local: bool,\n    },\n    SliceElement(&'a SliceRef),\n}\n\npub(crate) fn required_trivial_reasons<'a>(\n    apis: &'a [Api],\n    all: &OrderedMap<&'a Type, ComputedCfg>,\n    structs: &UnorderedMap<&'a Ident, &'a Struct>,\n    enums: &UnorderedMap<&'a Ident, &'a Enum>,\n    cxx: &UnorderedSet<&'a Ident>,\n    aliases: &UnorderedMap<&'a Ident, &'a TypeAlias>,\n    impls: &OrderedMap<ImplKey<'a>, ConditionalImpl<'a>>,\n    resolutions: &UnorderedMap<&Ident, Resolution>,\n) -> UnorderedMap<&'a Ident, Vec<TrivialReason<'a>>> {\n    let mut required_trivial = UnorderedMap::new();\n\n    let mut insist_extern_types_are_trivial = |ident: &'a NamedType, reason| {\n        if cxx.contains(&ident.rust)\n            && !structs.contains_key(&ident.rust)\n            && !enums.contains_key(&ident.rust)\n        {\n            required_trivial\n                .entry(&ident.rust)\n                .or_insert_with(Vec::new)\n                .push(reason);\n        }\n    };\n\n    for api in apis {\n        match api {\n            Api::Struct(strct) => {\n                for field in &strct.fields {\n                    if let Type::Ident(ident) = &field.ty {\n                        let reason = TrivialReason::StructField(strct);\n                        insist_extern_types_are_trivial(ident, reason);\n                    }\n                }\n            }\n            Api::CxxFunction(efn) | Api::RustFunction(efn) => {\n                for arg in &efn.args {\n                    if let Type::Ident(ident) = &arg.ty {\n                        let reason = TrivialReason::FunctionArgument(efn);\n                        insist_extern_types_are_trivial(ident, reason);\n                    }\n                }\n                if let Some(Type::Ident(ident)) = &efn.ret {\n                    let reason = TrivialReason::FunctionReturn(efn);\n                    insist_extern_types_are_trivial(ident, reason);\n                }\n            }\n            _ => {}\n        }\n    }\n\n    for (ty, _cfg) in all {\n        // Ignore cfg. For now if any use of an extern type requires it to be\n        // trivial, we enforce that it is trivial in all configurations. This\n        // can potentially be relaxed if there is a motivating use case.\n        match ty {\n            Type::RustBox(ty1) => {\n                if let Type::Ident(ident) = &ty1.inner {\n                    let local = !aliases.contains_key(&ident.rust)\n                        || impls.contains_key(&ty.impl_key(resolutions).unwrap());\n                    let reason = TrivialReason::BoxTarget { local };\n                    insist_extern_types_are_trivial(ident, reason);\n                }\n            }\n            Type::RustVec(ty1) => {\n                if let Type::Ident(ident) = &ty1.inner {\n                    let local = !aliases.contains_key(&ident.rust)\n                        || impls.contains_key(&ty.impl_key(resolutions).unwrap());\n                    let reason = TrivialReason::VecElement { local };\n                    insist_extern_types_are_trivial(ident, reason);\n                }\n            }\n            Type::SliceRef(ty) => {\n                if let Type::Ident(ident) = &ty.inner {\n                    let reason = TrivialReason::SliceElement(ty);\n                    insist_extern_types_are_trivial(ident, reason);\n                }\n            }\n            _ => {}\n        }\n    }\n\n    required_trivial\n}\n\n// Context:\n// \"type {type} should be trivially move constructible and trivially destructible in C++ to be used as {what} in Rust\"\n// \"needs a cxx::ExternType impl in order to be used as {what}\"\npub(crate) fn as_what<'a>(name: &'a Pair, reasons: &'a [TrivialReason]) -> impl Display + 'a {\n    struct Description<'a> {\n        name: &'a Pair,\n        reasons: &'a [TrivialReason<'a>],\n    }\n\n    impl<'a> Display for Description<'a> {\n        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n            let mut field_of = Set::new();\n            let mut argument_of = Set::new();\n            let mut return_of = Set::new();\n            let mut box_target = false;\n            let mut vec_element = false;\n            let mut slice_shared_element = false;\n            let mut slice_mut_element = false;\n\n            for reason in self.reasons {\n                match reason {\n                    TrivialReason::StructField(strct) => {\n                        field_of.insert(&strct.name.rust);\n                    }\n                    TrivialReason::FunctionArgument(efn) => {\n                        argument_of.insert(&efn.name.rust);\n                    }\n                    TrivialReason::FunctionReturn(efn) => {\n                        return_of.insert(&efn.name.rust);\n                    }\n                    TrivialReason::BoxTarget { .. } => box_target = true,\n                    TrivialReason::VecElement { .. } => vec_element = true,\n                    TrivialReason::SliceElement(slice) => {\n                        if slice.mutable {\n                            slice_mut_element = true;\n                        } else {\n                            slice_shared_element = true;\n                        }\n                    }\n                }\n            }\n\n            let mut clauses = Vec::new();\n            if !field_of.is_empty() {\n                clauses.push(Clause::Set {\n                    article: \"a\",\n                    desc: \"field of\",\n                    set: &field_of,\n                });\n            }\n            if !argument_of.is_empty() {\n                clauses.push(Clause::Set {\n                    article: \"an\",\n                    desc: \"argument of\",\n                    set: &argument_of,\n                });\n            }\n            if !return_of.is_empty() {\n                clauses.push(Clause::Set {\n                    article: \"a\",\n                    desc: \"return value of\",\n                    set: &return_of,\n                });\n            }\n            if box_target {\n                clauses.push(Clause::Ty1 {\n                    article: \"type\",\n                    desc: \"Box\",\n                    param: self.name,\n                });\n            }\n            if vec_element {\n                clauses.push(Clause::Ty1 {\n                    article: \"a\",\n                    desc: \"vector element in Vec\",\n                    param: self.name,\n                });\n            }\n            if slice_shared_element || slice_mut_element {\n                clauses.push(Clause::Slice {\n                    article: \"a\",\n                    desc: \"slice element in\",\n                    shared: slice_shared_element,\n                    mutable: slice_mut_element,\n                    param: self.name,\n                });\n            }\n\n            for (i, clause) in clauses.iter().enumerate() {\n                if i == 0 {\n                    write!(f, \"{} \", clause.article())?;\n                } else if i + 1 < clauses.len() {\n                    write!(f, \", \")?;\n                } else {\n                    write!(f, \" or \")?;\n                }\n                clause.fmt(f)?;\n            }\n\n            Ok(())\n        }\n    }\n\n    enum Clause<'a> {\n        Set {\n            article: &'a str,\n            desc: &'a str,\n            set: &'a Set<&'a Ident>,\n        },\n        Ty1 {\n            article: &'a str,\n            desc: &'a str,\n            param: &'a Pair,\n        },\n        Slice {\n            article: &'a str,\n            desc: &'a str,\n            shared: bool,\n            mutable: bool,\n            param: &'a Pair,\n        },\n    }\n\n    impl<'a> Clause<'a> {\n        fn article(&self) -> &'a str {\n            match self {\n                Clause::Set { article, .. }\n                | Clause::Ty1 { article, .. }\n                | Clause::Slice { article, .. } => article,\n            }\n        }\n\n        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n            match self {\n                Clause::Set {\n                    article: _,\n                    desc,\n                    set,\n                } => {\n                    write!(f, \"{} \", desc)?;\n                    for (i, ident) in set.iter().take(3).enumerate() {\n                        if i > 0 {\n                            write!(f, \", \")?;\n                        }\n                        write!(f, \"`{}`\", ident)?;\n                    }\n                    Ok(())\n                }\n                Clause::Ty1 {\n                    article: _,\n                    desc,\n                    param,\n                } => write!(f, \"{}<{}>\", desc, param.rust),\n                Clause::Slice {\n                    article: _,\n                    desc,\n                    shared,\n                    mutable,\n                    param,\n                } => {\n                    write!(f, \"{} \", desc)?;\n                    if *shared {\n                        write!(f, \"&[{}]\", param.rust)?;\n                    }\n                    if *shared && *mutable {\n                        write!(f, \" and \")?;\n                    }\n                    if *mutable {\n                        write!(f, \"&mut [{}]\", param.rust)?;\n                    }\n                    Ok(())\n                }\n            }\n        }\n    }\n\n    Description { name, reasons }\n}\n"
  },
  {
    "path": "syntax/types.rs",
    "content": "use crate::syntax::attrs::OtherAttrs;\nuse crate::syntax::cfg::ComputedCfg;\nuse crate::syntax::improper::ImproperCtype;\nuse crate::syntax::instantiate::ImplKey;\nuse crate::syntax::map::{OrderedMap, UnorderedMap};\nuse crate::syntax::query::TypeQuery;\nuse crate::syntax::report::Errors;\nuse crate::syntax::resolve::Resolution;\nuse crate::syntax::set::UnorderedSet;\nuse crate::syntax::trivial::{self, TrivialReason};\nuse crate::syntax::unpin::{self, UnpinReason};\nuse crate::syntax::visit::{self, Visit};\nuse crate::syntax::{\n    toposort, Api, Atom, Enum, ExternFn, ExternType, Impl, Lifetimes, Pair, Struct, Type, TypeAlias,\n};\nuse indexmap::map::Entry;\nuse proc_macro2::Ident;\nuse quote::ToTokens;\n\npub(crate) struct Types<'a> {\n    pub all: OrderedMap<&'a Type, ComputedCfg<'a>>,\n    pub structs: UnorderedMap<&'a Ident, &'a Struct>,\n    pub enums: UnorderedMap<&'a Ident, &'a Enum>,\n    pub cxx: UnorderedSet<&'a Ident>,\n    pub rust: UnorderedSet<&'a Ident>,\n    pub aliases: UnorderedMap<&'a Ident, &'a TypeAlias>,\n    pub untrusted: UnorderedMap<&'a Ident, &'a ExternType>,\n    pub required_trivial: UnorderedMap<&'a Ident, Vec<TrivialReason<'a>>>,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub required_unpin: UnorderedMap<&'a Ident, UnpinReason<'a>>,\n    pub impls: OrderedMap<ImplKey<'a>, ConditionalImpl<'a>>,\n    pub resolutions: UnorderedMap<&'a Ident, Resolution<'a>>,\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub associated_fn: UnorderedMap<&'a Ident, Vec<&'a ExternFn>>,\n    pub struct_improper_ctypes: UnorderedSet<&'a Ident>,\n    pub toposorted_structs: Vec<&'a Struct>,\n}\n\npub(crate) struct ConditionalImpl<'a> {\n    pub cfg: ComputedCfg<'a>,\n    // None for implicit impls, which arise from using a generic type\n    // instantiation in a struct field or function signature.\n    #[cfg_attr(not(proc_macro), expect(dead_code))]\n    pub explicit_impl: Option<&'a Impl>,\n}\n\nimpl<'a> Types<'a> {\n    pub(crate) fn collect(cx: &mut Errors, apis: &'a [Api]) -> Self {\n        let mut all = OrderedMap::new();\n        let mut structs = UnorderedMap::new();\n        let mut enums = UnorderedMap::new();\n        let mut cxx = UnorderedSet::new();\n        let mut rust = UnorderedSet::new();\n        let mut aliases = UnorderedMap::new();\n        let mut untrusted = UnorderedMap::new();\n        let mut impls = OrderedMap::new();\n        let mut resolutions = UnorderedMap::new();\n        let mut associated_fn = UnorderedMap::new();\n        let struct_improper_ctypes = UnorderedSet::new();\n        let toposorted_structs = Vec::new();\n\n        fn visit<'a>(\n            all: &mut OrderedMap<&'a Type, ComputedCfg<'a>>,\n            ty: &'a Type,\n            cfg: impl Into<ComputedCfg<'a>>,\n        ) {\n            struct CollectTypes<'s, 'a> {\n                all: &'s mut OrderedMap<&'a Type, ComputedCfg<'a>>,\n                cfg: ComputedCfg<'a>,\n            }\n\n            impl<'s, 'a> Visit<'a> for CollectTypes<'s, 'a> {\n                fn visit_type(&mut self, ty: &'a Type) {\n                    match self.all.entry(ty) {\n                        Entry::Vacant(entry) => {\n                            entry.insert(self.cfg.clone());\n                        }\n                        Entry::Occupied(mut entry) => entry.get_mut().merge_or(self.cfg.clone()),\n                    }\n                    visit::visit_type(self, ty);\n                }\n            }\n\n            let mut visitor = CollectTypes {\n                all,\n                cfg: cfg.into(),\n            };\n            visitor.visit_type(ty);\n        }\n\n        let mut add_resolution =\n            |name: &'a Pair, attrs: &'a OtherAttrs, generics: &'a Lifetimes| {\n                resolutions.insert(\n                    &name.rust,\n                    Resolution {\n                        name,\n                        attrs,\n                        generics,\n                    },\n                );\n            };\n\n        let mut type_names = UnorderedSet::new();\n        let mut function_names = UnorderedSet::new();\n        for api in apis {\n            // The same identifier is permitted to be declared as both a shared\n            // enum and extern C++ type, or shared struct and extern C++ type.\n            // That indicates to not emit the C++ enum/struct definition because\n            // it's defined by the included headers already.\n            //\n            // All other cases of duplicate identifiers are reported as an error.\n            match api {\n                Api::Include(_) => {}\n                Api::Struct(strct) => {\n                    let ident = &strct.name.rust;\n                    if !type_names.insert(ident)\n                        && (!cxx.contains(ident)\n                            || structs.contains_key(ident)\n                            || enums.contains_key(ident))\n                    {\n                        // If already declared as a struct or enum, or if\n                        // colliding with something other than an extern C++\n                        // type, then error.\n                        duplicate_name(cx, strct, ItemName::Type(ident));\n                    }\n                    structs.insert(&strct.name.rust, strct);\n                    for field in &strct.fields {\n                        let cfg = ComputedCfg::all(&strct.cfg, &field.cfg);\n                        visit(&mut all, &field.ty, cfg);\n                    }\n                    add_resolution(&strct.name, &strct.attrs, &strct.generics);\n                }\n                Api::Enum(enm) => {\n                    match all.entry(&enm.repr.repr_type) {\n                        Entry::Vacant(entry) => {\n                            entry.insert(ComputedCfg::Leaf(&enm.cfg));\n                        }\n                        Entry::Occupied(mut entry) => entry.get_mut().merge_or(&enm.cfg),\n                    }\n                    let ident = &enm.name.rust;\n                    if !type_names.insert(ident)\n                        && (!cxx.contains(ident)\n                            || structs.contains_key(ident)\n                            || enums.contains_key(ident))\n                    {\n                        // If already declared as a struct or enum, or if\n                        // colliding with something other than an extern C++\n                        // type, then error.\n                        duplicate_name(cx, enm, ItemName::Type(ident));\n                    }\n                    enums.insert(ident, enm);\n                    add_resolution(&enm.name, &enm.attrs, &enm.generics);\n                }\n                Api::CxxType(ety) => {\n                    let ident = &ety.name.rust;\n                    if !type_names.insert(ident)\n                        && (cxx.contains(ident)\n                            || !structs.contains_key(ident) && !enums.contains_key(ident))\n                    {\n                        // If already declared as an extern C++ type, or if\n                        // colliding with something which is neither struct nor\n                        // enum, then error.\n                        duplicate_name(cx, ety, ItemName::Type(ident));\n                    }\n                    cxx.insert(ident);\n                    if !ety.trusted {\n                        untrusted.insert(ident, ety);\n                    }\n                    add_resolution(&ety.name, &ety.attrs, &ety.generics);\n                }\n                Api::RustType(ety) => {\n                    let ident = &ety.name.rust;\n                    if !type_names.insert(ident) {\n                        duplicate_name(cx, ety, ItemName::Type(ident));\n                    }\n                    rust.insert(ident);\n                    add_resolution(&ety.name, &ety.attrs, &ety.generics);\n                }\n                Api::CxxFunction(efn) | Api::RustFunction(efn) => {\n                    // Note: duplication of the C++ name is fine because C++ has\n                    // function overloading.\n                    let self_type = efn.self_type();\n                    if let Some(self_type) = self_type {\n                        associated_fn\n                            .entry(self_type)\n                            .or_insert_with(Vec::new)\n                            .push(efn);\n                    }\n                    if !self_type.is_some_and(|self_type| self_type == \"Self\")\n                        && !function_names.insert((self_type, &efn.name.rust))\n                    {\n                        duplicate_name(cx, efn, ItemName::Function(self_type, &efn.name.rust));\n                    }\n                    for arg in &efn.args {\n                        visit(&mut all, &arg.ty, &efn.cfg);\n                    }\n                    if let Some(ret) = &efn.ret {\n                        visit(&mut all, ret, &efn.cfg);\n                    }\n                }\n                Api::TypeAlias(alias) => {\n                    let ident = &alias.name.rust;\n                    if !type_names.insert(ident) {\n                        duplicate_name(cx, alias, ItemName::Type(ident));\n                    }\n                    cxx.insert(ident);\n                    aliases.insert(ident, alias);\n                    add_resolution(&alias.name, &alias.attrs, &alias.generics);\n                }\n                Api::Impl(imp) => {\n                    visit(&mut all, &imp.ty, &imp.cfg);\n                }\n            }\n        }\n\n        for api in apis {\n            if let Api::Impl(imp) = api {\n                if let Some(key) = imp.ty.impl_key(&resolutions) {\n                    impls.insert(key, ConditionalImpl::from(imp));\n                }\n            }\n        }\n\n        // All these APIs may contain types passed by value. We need to ensure\n        // we check that this is permissible. We do this _after_ scanning all\n        // the APIs above, in case some function or struct references a type\n        // which is declared subsequently.\n        let required_trivial = trivial::required_trivial_reasons(\n            apis,\n            &all,\n            &structs,\n            &enums,\n            &cxx,\n            &aliases,\n            &impls,\n            &resolutions,\n        );\n\n        let required_unpin =\n            unpin::required_unpin_reasons(apis, &all, &structs, &enums, &cxx, &aliases);\n\n        let mut types = Types {\n            all,\n            structs,\n            enums,\n            cxx,\n            rust,\n            aliases,\n            untrusted,\n            required_trivial,\n            required_unpin,\n            impls,\n            resolutions,\n            associated_fn,\n            struct_improper_ctypes,\n            toposorted_structs,\n        };\n\n        types.toposorted_structs = toposort::sort(cx, apis, &types);\n\n        for (ty, cfg) in &types.all {\n            let Some(impl_key) = ty.impl_key(&types.resolutions) else {\n                continue;\n            };\n            if impl_key.is_implicit_impl_ok(&types) {\n                match types.impls.entry(impl_key) {\n                    Entry::Vacant(entry) => {\n                        entry.insert(ConditionalImpl::from(cfg.clone()));\n                    }\n                    Entry::Occupied(mut entry) => entry.get_mut().cfg.merge_or(cfg.clone()),\n                }\n            }\n        }\n\n        let mut unresolved_structs = types.structs.keys();\n        let mut new_information = true;\n        while new_information {\n            new_information = false;\n            unresolved_structs.retain(|ident| {\n                let mut retain = false;\n                for var in &types.structs[ident].fields {\n                    if match types.determine_improper_ctype(&var.ty) {\n                        ImproperCtype::Depends(inner) => {\n                            retain = true;\n                            types.struct_improper_ctypes.contains(inner)\n                        }\n                        ImproperCtype::Definite(improper) => improper,\n                    } {\n                        types.struct_improper_ctypes.insert(ident);\n                        new_information = true;\n                        return false;\n                    }\n                }\n                // If all fields definite false, remove from unresolved_structs.\n                retain\n            });\n        }\n\n        types\n    }\n\n    pub(crate) fn needs_indirect_abi(&self, ty: impl Into<TypeQuery<'a>>) -> bool {\n        let ty = ty.into();\n        match ty {\n            TypeQuery::RustBox\n            | TypeQuery::UniquePtr\n            | TypeQuery::Ref(_)\n            | TypeQuery::Ptr(_)\n            | TypeQuery::Str\n            | TypeQuery::Fn\n            | TypeQuery::SliceRef => false,\n            TypeQuery::Array(_) => true,\n            _ => !self.is_guaranteed_pod(ty) || self.is_considered_improper_ctype(ty),\n        }\n    }\n\n    // Types that trigger rustc's default #[warn(improper_ctypes)] lint, even if\n    // they may be otherwise unproblematic to mention in an extern signature.\n    // For example in a signature like `extern \"C\" fn(*const String)`, rustc\n    // refuses to believe that C could know how to supply us with a pointer to a\n    // Rust String, even though C could easily have obtained that pointer\n    // legitimately from a Rust call.\n    pub(crate) fn is_considered_improper_ctype(&self, ty: impl Into<TypeQuery<'a>>) -> bool {\n        match self.determine_improper_ctype(ty) {\n            ImproperCtype::Definite(improper) => improper,\n            ImproperCtype::Depends(ident) => self.struct_improper_ctypes.contains(ident),\n        }\n    }\n\n    // Types which we need to assume could possibly exist by value on the Rust\n    // side.\n    pub(crate) fn is_maybe_trivial(&self, ty: &Type) -> bool {\n        match ty {\n            Type::Ident(named_type) => {\n                let ident = &named_type.rust;\n                self.structs.contains_key(ident)\n                    || self.enums.contains_key(ident)\n                    || self.aliases.contains_key(ident)\n            }\n            Type::CxxVector(_) => false,\n            // No other type can appear as the inner type of CxxVector,\n            // UniquePtr, or SharedPtr.\n            _ => unreachable!(\"syntax/check.rs should reject other types\"),\n        }\n    }\n\n    pub(crate) fn contains_elided_lifetime(&self, ty: &Type) -> bool {\n        match ty {\n            Type::Ident(ty) => {\n                Atom::from(&ty.rust).is_none()\n                    && ty.generics.lifetimes.len()\n                        != self.resolve(&ty.rust).generics.lifetimes.len()\n            }\n            Type::RustBox(ty)\n            | Type::RustVec(ty)\n            | Type::UniquePtr(ty)\n            | Type::SharedPtr(ty)\n            | Type::WeakPtr(ty)\n            | Type::CxxVector(ty) => self.contains_elided_lifetime(&ty.inner),\n            Type::Ref(ty) => ty.lifetime.is_none() || self.contains_elided_lifetime(&ty.inner),\n            Type::Ptr(ty) => self.contains_elided_lifetime(&ty.inner),\n            Type::Str(ty) => ty.lifetime.is_none(),\n            Type::SliceRef(ty) => ty.lifetime.is_none() || self.contains_elided_lifetime(&ty.inner),\n            Type::Array(ty) => self.contains_elided_lifetime(&ty.inner),\n            Type::Fn(_) | Type::Void(_) => false,\n        }\n    }\n\n    /// Whether the current module is responsible for generic type\n    /// instantiations pertaining to the given type.\n    pub(crate) fn is_local(&self, ty: &Type) -> bool {\n        match ty {\n            Type::Ident(ident) => {\n                Atom::from(&ident.rust).is_none() && !self.aliases.contains_key(&ident.rust)\n            }\n            Type::RustBox(ty1) => {\n                // https://doc.rust-lang.org/reference/glossary.html#fundamental-type-constructors\n                // \"Any time a type T is considered local [...] Box<T> [... is]\n                // also considered local.\"\n                self.is_local(&ty1.inner)\n            }\n            Type::Array(_)\n            | Type::CxxVector(_)\n            | Type::Fn(_)\n            | Type::Void(_)\n            | Type::RustVec(_)\n            | Type::UniquePtr(_)\n            | Type::SharedPtr(_)\n            | Type::WeakPtr(_)\n            | Type::Ref(_)\n            | Type::Ptr(_)\n            | Type::Str(_)\n            | Type::SliceRef(_) => false,\n        }\n    }\n}\n\nimpl<'t, 'a> IntoIterator for &'t Types<'a> {\n    type Item = &'a Type;\n    type IntoIter = std::iter::Copied<indexmap::map::Keys<'t, &'a Type, ComputedCfg<'a>>>;\n    fn into_iter(self) -> Self::IntoIter {\n        self.all.keys().copied()\n    }\n}\n\nimpl<'a> From<ComputedCfg<'a>> for ConditionalImpl<'a> {\n    fn from(cfg: ComputedCfg<'a>) -> Self {\n        ConditionalImpl {\n            cfg,\n            explicit_impl: None,\n        }\n    }\n}\n\nimpl<'a> From<&'a Impl> for ConditionalImpl<'a> {\n    fn from(imp: &'a Impl) -> Self {\n        ConditionalImpl {\n            cfg: ComputedCfg::Leaf(&imp.cfg),\n            explicit_impl: Some(imp),\n        }\n    }\n}\n\nenum ItemName<'a> {\n    Type(&'a Ident),\n    Function(Option<&'a Ident>, &'a Ident),\n}\n\nfn duplicate_name(cx: &mut Errors, sp: impl ToTokens, name: ItemName) {\n    let description = match name {\n        ItemName::Type(name) => format!(\"type `{}`\", name),\n        ItemName::Function(Some(self_type), name) => {\n            format!(\"associated function `{}::{}`\", self_type, name)\n        }\n        ItemName::Function(None, name) => format!(\"function `{}`\", name),\n    };\n    let msg = format!(\"the {} is defined multiple times\", description);\n    cx.error(sp, msg);\n}\n"
  },
  {
    "path": "syntax/unpin.rs",
    "content": "use crate::syntax::cfg::ComputedCfg;\nuse crate::syntax::map::{OrderedMap, UnorderedMap};\nuse crate::syntax::set::UnorderedSet;\nuse crate::syntax::{Api, Enum, NamedType, Receiver, Ref, SliceRef, Struct, Type, TypeAlias};\nuse proc_macro2::Ident;\n\n#[cfg_attr(not(proc_macro), expect(dead_code))]\npub(crate) enum UnpinReason<'a> {\n    Receiver(&'a Receiver),\n    Ref(&'a Ref),\n    Slice(&'a SliceRef),\n}\n\npub(crate) fn required_unpin_reasons<'a>(\n    apis: &'a [Api],\n    all: &OrderedMap<&'a Type, ComputedCfg>,\n    structs: &UnorderedMap<&'a Ident, &'a Struct>,\n    enums: &UnorderedMap<&'a Ident, &'a Enum>,\n    cxx: &UnorderedSet<&'a Ident>,\n    aliases: &UnorderedMap<&'a Ident, &'a TypeAlias>,\n) -> UnorderedMap<&'a Ident, UnpinReason<'a>> {\n    let mut reasons = UnorderedMap::new();\n\n    let is_extern_type_alias = |ty: &NamedType| -> bool {\n        cxx.contains(&ty.rust)\n            && !structs.contains_key(&ty.rust)\n            && !enums.contains_key(&ty.rust)\n            && aliases.contains_key(&ty.rust)\n    };\n\n    for (ty, _cfgs) in all {\n        if let Type::SliceRef(slice) = ty {\n            if let Type::Ident(inner) = &slice.inner {\n                if slice.mutable && is_extern_type_alias(inner) {\n                    reasons.insert(&inner.rust, UnpinReason::Slice(slice));\n                }\n            }\n        }\n    }\n\n    for api in apis {\n        if let Api::CxxFunction(efn) | Api::RustFunction(efn) = api {\n            if let Some(receiver) = efn.receiver() {\n                if receiver.mutable && !receiver.pinned && is_extern_type_alias(&receiver.ty) {\n                    reasons.insert(&receiver.ty.rust, UnpinReason::Receiver(receiver));\n                }\n            }\n        }\n    }\n\n    for (ty, _cfg) in all {\n        if let Type::Ref(ty) = ty {\n            if let Type::Ident(inner) = &ty.inner {\n                if ty.mutable && !ty.pinned && is_extern_type_alias(inner) {\n                    reasons.insert(&inner.rust, UnpinReason::Ref(ty));\n                }\n            }\n        }\n    }\n\n    reasons\n}\n"
  },
  {
    "path": "syntax/visit.rs",
    "content": "use crate::syntax::Type;\n\npub(crate) trait Visit<'a> {\n    fn visit_type(&mut self, ty: &'a Type) {\n        visit_type(self, ty);\n    }\n}\n\npub(crate) fn visit_type<'a, V>(visitor: &mut V, ty: &'a Type)\nwhere\n    V: Visit<'a> + ?Sized,\n{\n    match ty {\n        Type::Ident(_) | Type::Str(_) | Type::Void(_) => {}\n        Type::RustBox(ty)\n        | Type::UniquePtr(ty)\n        | Type::SharedPtr(ty)\n        | Type::WeakPtr(ty)\n        | Type::CxxVector(ty)\n        | Type::RustVec(ty) => visitor.visit_type(&ty.inner),\n        Type::Ref(r) => visitor.visit_type(&r.inner),\n        Type::Ptr(p) => visitor.visit_type(&p.inner),\n        Type::Array(a) => visitor.visit_type(&a.inner),\n        Type::SliceRef(s) => visitor.visit_type(&s.inner),\n        Type::Fn(fun) => {\n            if let Some(ret) = &fun.ret {\n                visitor.visit_type(ret);\n            }\n            for arg in &fun.args {\n                visitor.visit_type(&arg.ty);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/BUCK",
    "content": "load(\"//tools/buck:rust_cxx_bridge.bzl\", \"rust_cxx_bridge\")\n\nrust_test(\n    name = \"test\",\n    srcs = [\"test.rs\"],\n    edition = \"2021\",\n    deps = [\n        \":ffi\",\n        \"//:cxx\",\n    ],\n)\n\nrust_library(\n    name = \"ffi\",\n    srcs = [\n        \"ffi/cast.rs\",\n        \"ffi/lib.rs\",\n        \"ffi/module.rs\",\n    ],\n    crate = \"cxx_test_suite\",\n    edition = \"2021\",\n    deps = [\n        \":impl\",\n        \"//:cxx\",\n        \"//third-party:serde\",\n    ],\n)\n\ncxx_library(\n    name = \"impl\",\n    srcs = [\n        \"ffi/tests.cc\",\n        \":bridge/source\",\n        \":module/source\",\n    ],\n    exported_deps = [\"//:core\"],\n    exported_headers = [\n        \":bridge/header\",\n        \":module/header\",\n        \"ffi/tests.h\",\n    ],\n    preferred_linkage = \"static\",\n)\n\nrust_cxx_bridge(\n    name = \"bridge\",\n    src = \"ffi/lib.rs\",\n    deps = [\n        \":impl\",\n    ],\n)\n\nrust_cxx_bridge(\n    name = \"module\",\n    src = \"ffi/module.rs\",\n    deps = [\n        \":impl\",\n    ],\n)\n"
  },
  {
    "path": "tests/BUILD.bazel",
    "content": "load(\"@rules_cc//cc:defs.bzl\", \"cc_library\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\", \"rust_test\")\nload(\"//tools/bazel:rust_cxx_bridge.bzl\", \"rust_cxx_bridge\")\n\nrust_test(\n    name = \"test\",\n    size = \"small\",\n    srcs = [\"test.rs\"],\n    edition = \"2021\",\n    deps = [\n        \":cxx_test_suite\",\n        \"//:cxx\",\n    ],\n)\n\nrust_library(\n    name = \"cxx_test_suite\",\n    testonly = True,\n    srcs = [\n        \"ffi/cast.rs\",\n        \"ffi/lib.rs\",\n        \"ffi/module.rs\",\n    ],\n    edition = \"2021\",\n    deps = [\n        \":impl\",\n        \"//:cxx\",\n        \"@crates.io//:serde\",\n    ],\n)\n\ncc_library(\n    name = \"impl\",\n    testonly = True,\n    srcs = [\n        \"ffi/tests.cc\",\n        \":bridge/source\",\n        \":module/source\",\n    ],\n    hdrs = [\"ffi/tests.h\"],\n    linkstatic = True,\n    deps = [\n        \":bridge/include\",\n        \":module/include\",\n        \"//:core\",\n    ],\n)\n\nrust_cxx_bridge(\n    name = \"bridge\",\n    testonly = True,\n    src = \"ffi/lib.rs\",\n    deps = [\":impl\"],\n)\n\nrust_cxx_bridge(\n    name = \"module\",\n    testonly = True,\n    src = \"ffi/module.rs\",\n    deps = [\":impl\"],\n)\n"
  },
  {
    "path": "tests/README.md",
    "content": "# Testing\n\nThis document provides an outline of different kinds of tests used by the `cxx`\nproject.\n\n## Errors from proc macro\n\nWe want to verify that the `#[cxx::bridge]` macro reports expected error\nmessages when invoked by `rustc` on certain inputs.\n\nSuch verification is handled by test cases underneath **tests/ui** directory and\ndriven by **tests/compiletest.rs**. The test cases consist of a pair of files:\n\n* **foo.rs** is the input\n* **foo.stderr** is the expected Rust compiler diagnostic\n\n## Errors from C++ compiler\n\nWe want to verify that cxx's generated C++ code triggers expected C++ compiler\ndiagnostics on certain inputs.\n\nSuch verification is covered by **tests/cpp_ui_tests.rs**.\n\n## End-to-end functionality\n\nEnd-to-end functional tests are structured as follows:\n\n* The code under test is contained underneath **tests/ffi** directory which\n  contains:\n    - Rust code under test &emdash; the `cxx-test-suite` crate (**lib.rs** and\n      **module.rs**) with:\n        - A few `#[cxx::bridge]` invocations\n        - Rust types (e.g. `struct R`)\n        - Rust functions and methods (e.g. `fn r_return_primitive`)\n    - C/C++ code under test (**tests.h** and **tests.cc**)\n        - C++ types (e.g. `class C`)\n        - C++ functions and methods (e.g. `c_return_primitive`)\n* The testcases can be found in:\n    - Rust calling into C++: **tests/test.rs**.\n    - C++ calling into Rust: **tests/ffi/test.cc**. These tests are manually\n      dispatched from the `cxx_run_test` function in **tests/ffi/test.cc**.\n"
  },
  {
    "path": "tests/compiletest.rs",
    "content": "#[allow(unused_attributes)]\n#[rustversion::attr(not(nightly), ignore = \"requires nightly\")]\n#[cfg_attr(skip_ui_tests, ignore = \"disabled by `--cfg=skip_ui_tests`\")]\n#[cfg_attr(miri, ignore = \"incompatible with miri\")]\n#[test]\nfn ui() {\n    let t = trybuild::TestCases::new();\n    t.compile_fail(\"tests/ui/*.rs\");\n}\n"
  },
  {
    "path": "tests/cpp_compile/mod.rs",
    "content": "//! This test harness is for verifying that the C++ code from cxx's C++ code\n//! generator (via `cxx_gen`) triggers the intended C++ compiler diagnostics.\n\n#![allow(unknown_lints, mismatched_lifetime_syntaxes)]\n\nuse proc_macro2::TokenStream;\nuse std::borrow::Cow;\nuse std::fs;\nuse std::path::{Path, PathBuf};\nuse std::process::{self, Stdio};\nuse tempfile::TempDir;\n\nmod smoke_test;\n\n/// 1. Takes a `#[cxx::bridge]` and generates `.cc` and `.h` files,\n/// 2. Places additional source files (typically handwritten header files),\n/// 3. Compiles the generated `.cc` file.\npub struct Test {\n    temp_dir: TempDir,\n\n    /// Path to the `.cc` file (in `temp_dir`) that is generated by the\n    /// `cxx_gen` crate out of the `cxx_bridge` argument passed to `Test::new`.\n    generated_cc: PathBuf,\n}\n\nimpl Test {\n    /// Creates a new test for the given `cxx_bridge`.\n    ///\n    /// Example:\n    ///\n    /// ```\n    /// let test = Test::new(quote!{\n    ///     #[cxx::bridge]\n    ///     mod ffi {\n    ///         unsafe extern \"C++\" {\n    ///             include!(\"include.h\");\n    ///             pub fn do_cpp_thing();\n    ///         }\n    ///     }\n    /// });\n    /// ```\n    ///\n    /// # Panics\n    ///\n    /// Panics if there is a failure when generating `.cc` and `.h` files from\n    /// the `cxx_bridge`.\n    #[must_use]\n    pub fn new(cxx_bridge: TokenStream) -> Self {\n        let prefix = concat!(env!(\"CARGO_CRATE_NAME\"), \"-\");\n        let scratch = scratch::path(\"cxx-test-suite\");\n        let temp_dir = TempDir::with_prefix_in(prefix, scratch).unwrap();\n        let generated_h = temp_dir.path().join(\"cxx_bridge.generated.h\");\n        let generated_cc = temp_dir.path().join(\"cxx_bridge.generated.cc\");\n\n        let opt = cxx_gen::Opt::default();\n        let generated = cxx_gen::generate_header_and_cc(cxx_bridge, &opt).unwrap();\n        fs::write(&generated_h, &generated.header).unwrap();\n        fs::write(&generated_cc, &generated.implementation).unwrap();\n\n        Self {\n            temp_dir,\n            generated_cc,\n        }\n    }\n\n    /// Writes a file to the temporary test directory.\n    ///\n    /// The new file will be present in the `-I` include path passed to the C++\n    /// compiler.\n    ///\n    /// # Panics\n    ///\n    /// Panics if there is an error when writing the file.\n    pub fn write_file(&self, filename: impl AsRef<Path>, contents: &str) {\n        fs::write(self.temp_dir.path().join(filename), contents).unwrap();\n    }\n\n    /// Compiles the `.cc` file generated in `Self::new`.\n    ///\n    /// # Panics\n    ///\n    /// Panics if there is a problem with spawning the C++ compiler.\n    /// (Compilation errors will *not* result in a panic.)\n    #[must_use]\n    pub fn compile(&self) -> CompilationResult {\n        let mut build = cc::Build::new();\n        build\n            .include(self.temp_dir.path())\n            .out_dir(self.temp_dir.path())\n            .cpp(true);\n\n        // Arbitrarily using C++20 for now. If some test cases require a\n        // specific C++ standard, we can make this configurable.\n        build.std(\"c++20\");\n\n        // Set info required by the `cc` crate.\n        //\n        // The correct host triple during execution of this test is the target\n        // triple from the Rust compilation of this test -- not the Rust host\n        // triple.\n        build\n            .opt_level(3)\n            .host(target_triple::TARGET)\n            .target(target_triple::TARGET);\n\n        // The `cc` crate does not currently expose the `Command` for building a\n        // single C++ source file. Work around that by passing `-c <file.cc>`.\n        let mut command = build.get_compiler().to_command();\n        command\n            .stdout(Stdio::piped())\n            .stderr(Stdio::piped())\n            .current_dir(self.temp_dir.path())\n            .arg(\"-c\")\n            .arg(&self.generated_cc);\n        let output = command.spawn().unwrap().wait_with_output().unwrap();\n        CompilationResult(output)\n    }\n}\n\n/// Wrapper around the output from a C++ compiler.\npub struct CompilationResult(process::Output);\n\nimpl CompilationResult {\n    fn stdout(&self) -> Cow<str> {\n        String::from_utf8_lossy(&self.0.stdout)\n    }\n\n    fn stderr(&self) -> Cow<str> {\n        String::from_utf8_lossy(&self.0.stderr)\n    }\n\n    fn dump_output_and_panic(&self, msg: &str) -> ! {\n        eprintln!(\"{}\", self.stdout());\n        eprintln!(\"{}\", self.stderr());\n        panic!(\"{msg}\");\n    }\n\n    fn error_lines(&self) -> Vec<String> {\n        assert!(!self.0.status.success());\n\n        // MSVC reports errors to stdout rather than stderr, so consider both.\n        let stdout = self.stdout();\n        let stderr = self.stderr();\n        let all_lines = stdout.lines().chain(stderr.lines());\n\n        all_lines\n            .filter(|line| {\n                // This should match MSVC error output\n                // (e.g. `file.cc(<line number>): error C2338: static_assert failed: ...`)\n                // as well as Clang or GCC error output\n                // (e.g. `file.cc:<line>:<column>: error: static assertion failed: ...`\n                line.contains(\": error\")\n            })\n            .map(str::to_owned)\n            .collect()\n    }\n\n    /// Asserts that the C++ compilation succeeded.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the C++ compiler reported an error.\n    pub fn assert_success(&self) {\n        if !self.0.status.success() {\n            self.dump_output_and_panic(\"Compiler reported an error\");\n        }\n    }\n\n    /// Verifies that the compilation failed with a single error, and return the\n    /// stderr line describing this error.\n    ///\n    /// Note that different compilers may return slightly different error\n    /// messages, so tests should be careful to only verify presence of some\n    /// substrings.\n    ///\n    /// # Panics\n    ///\n    /// Panics if there was no error, or if there was more than a single error.\n    #[must_use]\n    pub fn expect_single_error(&self) -> String {\n        let error_lines = self.error_lines();\n        if error_lines.is_empty() {\n            self.dump_output_and_panic(\"No error lines found, despite non-zero exit code?\");\n        }\n        if error_lines.len() > 1 {\n            self.dump_output_and_panic(\"Unexpectedly more than 1 error line was present\");\n        }\n\n        // `eprintln` to help with debugging test failues that may happen later.\n        let single_error_line = error_lines.into_iter().next().unwrap();\n        eprintln!(\"Got single error as expected: {single_error_line}\");\n        single_error_line\n    }\n}\n"
  },
  {
    "path": "tests/cpp_compile/smoke_test.rs",
    "content": "use crate::cpp_compile;\nuse indoc::indoc;\nuse quote::quote;\n\n#[test]\nfn test_success() {\n    let test = cpp_compile::Test::new(quote! {\n        #[cxx::bridge]\n        mod ffi {\n            unsafe extern \"C++\" {\n                include!(\"include.h\");\n                pub fn do_cpp_thing();\n            }\n        }\n    });\n    test.write_file(\n        \"include.h\",\n        indoc! {\"\n            void do_cpp_thing();\n        \"},\n    );\n    test.compile().assert_success();\n}\n\n#[test]\nfn test_failure() {\n    let test = cpp_compile::Test::new(quote! {\n        #[cxx::bridge]\n        mod ffi {\n            unsafe extern \"C++\" {\n                include!(\"include.h\");\n            }\n        }\n    });\n    test.write_file(\n        \"include.h\",\n        indoc! {r#\"\n            static_assert(false, \"This is a failure smoke test\");\n        \"#},\n    );\n    let err_msg = test.compile().expect_single_error();\n    assert!(err_msg.contains(\"This is a failure smoke test\"));\n}\n\n#[test]\n#[should_panic = \"Unexpectedly more than 1 error line was present\"]\nfn test_unexpected_extra_error() {\n    let test = cpp_compile::Test::new(quote! {\n        #[cxx::bridge]\n        mod ffi {\n            unsafe extern \"C++\" {\n                include!(\"include.h\");\n            }\n        }\n    });\n    test.write_file(\n        \"include.h\",\n        indoc! {r#\"\n            static_assert(false, \"First error line\");\n            static_assert(false, \"Second error line\");\n        \"#},\n    );\n\n    // We `should_panic` inside `expect_single_error` below:\n    let _ = test.compile().expect_single_error();\n}\n"
  },
  {
    "path": "tests/cpp_ui_tests.rs",
    "content": "mod cpp_compile;\n\nuse indoc::indoc;\nuse quote::quote;\n\n/// This is a regression test for `static_assert(::rust::is_complete...)`\n/// which we started to emit in <https://github.com/dtolnay/cxx/commit/534627667>\n#[test]\nfn test_unique_ptr_of_incomplete_foward_declared_pointee() {\n    let test = cpp_compile::Test::new(quote! {\n        #[cxx::bridge]\n        mod ffi {\n            unsafe extern \"C++\" {\n                include!(\"include.h\");\n                type ForwardDeclaredType;\n            }\n            impl UniquePtr<ForwardDeclaredType> {}\n        }\n    });\n    test.write_file(\n        \"include.h\",\n        indoc! {\"\n            class ForwardDeclaredType;\n        \"},\n    );\n    let err_msg = test.compile().expect_single_error();\n    assert!(err_msg.contains(\"definition of `::ForwardDeclaredType` is required\"));\n}\n"
  },
  {
    "path": "tests/cxx_gen.rs",
    "content": "use cxx_gen::{generate_header_and_cc, Opt};\nuse std::str;\n\nconst CXXPREFIX: &str = concat!(\"cxxbridge1$\", env!(\"CARGO_PKG_VERSION_PATCH\"));\n\nconst BRIDGE0: &str = r#\"\n    #[cxx::bridge]\n    mod ffi {\n        unsafe extern \"C++\" {\n            pub fn do_cpp_thing(foo: &str);\n        }\n    }\n\"#;\n\n#[test]\nfn test_extern_c_function() {\n    let opt = Opt::default();\n    let source = BRIDGE0.parse().unwrap();\n    let generated = generate_header_and_cc(source, &opt).unwrap();\n    let output = str::from_utf8(&generated.implementation).unwrap();\n    // To avoid continual breakage we won't test every byte.\n    // Let's look for the major features.\n    assert!(output.contains(&format!(\"void {CXXPREFIX}$do_cpp_thing(::rust::Str foo)\")));\n}\n\n#[test]\nfn test_impl_annotation() {\n    let mut opt = Opt::default();\n    opt.cxx_impl_annotations = Some(\"ANNOTATION\".to_owned());\n    let source = BRIDGE0.parse().unwrap();\n    let generated = generate_header_and_cc(source, &opt).unwrap();\n    let output = str::from_utf8(&generated.implementation).unwrap();\n    assert!(output.contains(&format!(\n        \"ANNOTATION void {CXXPREFIX}$do_cpp_thing(::rust::Str foo)\",\n    )));\n}\n\nconst BRIDGE1: &str = r#\"\n    #[cxx::bridge]\n    mod ffi {\n        extern \"C++\" {\n            type CppType;\n        }\n\n        extern \"Rust\" {\n            fn rust_method_cpp_receiver(self: Pin<&mut CppType>);\n        }\n    }\n\"#;\n\n// Ensure that implementing a Rust method on an opaque C++ type only causes\n// generation of the member function definition, not a member function\n// declaration in a class definition.\n//\n// The member function declaration will come from whichever header provides the\n// C++ class definition.\n//\n// This allows for developers and crates that are producing both C++ and Rust\n// code to have a C++ method implemented in Rust without having to use a free\n// function and passing through the C++ \"this\" as an argument.\n#[test]\nfn test_extern_rust_method_on_c_type() {\n    let opt = Opt::default();\n    let source = BRIDGE1.parse().unwrap();\n    let generated = generate_header_and_cc(source, &opt).unwrap();\n    let header = str::from_utf8(&generated.header).unwrap();\n    let implementation = str::from_utf8(&generated.implementation).unwrap();\n\n    // Check that the header doesn't have the Rust method.\n    assert!(!header.contains(\"rust_method_cpp_receiver\"));\n\n    // Check that there is a generated C signature bridging to the Rust method.\n    assert!(implementation.contains(&format!(\n        \"void {CXXPREFIX}$CppType$rust_method_cpp_receiver(::CppType &self) noexcept;\",\n    )));\n\n    // Check that there is an implementation on the C++ class calling the Rust method.\n    assert!(implementation.contains(\"void CppType::rust_method_cpp_receiver() noexcept {\"));\n    assert!(implementation.contains(&format!(\n        \"{CXXPREFIX}$CppType$rust_method_cpp_receiver(*this);\",\n    )));\n}\n"
  },
  {
    "path": "tests/cxx_string.rs",
    "content": "#![allow(\n    clippy::items_after_statements,\n    clippy::uninlined_format_args,\n    clippy::unused_async\n)]\n\nuse cxx::{let_cxx_string, CxxString};\nuse std::fmt::Write as _;\n\n#[test]\nfn test_async_cxx_string() {\n    async fn f() {\n        let_cxx_string!(s = \"...\");\n\n        async fn g(_: &CxxString) {}\n        g(&s).await;\n    }\n\n    // https://github.com/dtolnay/cxx/issues/693\n    fn assert_send(_: impl Send) {}\n    assert_send(f());\n}\n\n#[test]\nfn test_display() {\n    let_cxx_string!(s = b\"w\\\"x\\'y\\xF1\\x80\\xF1\\x80z\");\n\n    assert_eq!(format!(\"{}\", s), \"w\\\"x'y\\u{fffd}\\u{fffd}z\");\n}\n\n#[test]\nfn test_debug() {\n    let_cxx_string!(s = b\"w\\\"x\\'y\\xF1\\x80z\");\n\n    assert_eq!(format!(\"{:?}\", s), r#\"\"w\\\"x'y\\xf1\\x80z\"\"#);\n}\n\n#[test]\nfn test_fmt_write() {\n    let_cxx_string!(s = \"\");\n\n    let name = \"world\";\n    write!(s, \"Hello, {name}!\").unwrap();\n    assert_eq!(s.to_str(), Ok(\"Hello, world!\"));\n}\n\n#[test]\nfn test_io_write() {\n    let_cxx_string!(s = \"\");\n    let mut reader: &[u8] = b\"Hello, world!\";\n\n    std::io::copy(&mut reader, &mut s).unwrap();\n    assert_eq!(s.to_str(), Ok(\"Hello, world!\"));\n}\n"
  },
  {
    "path": "tests/cxx_vector.rs",
    "content": "use cxx::CxxVector;\n\n#[test]\nfn test_cxx_vector_new() {\n    let vector = CxxVector::<i32>::new();\n    assert!(vector.is_empty());\n}\n"
  },
  {
    "path": "tests/ffi/Cargo.toml",
    "content": "[package]\nname = \"cxx-test-suite\"\nversion = \"0.0.0\"\nauthors = [\"David Tolnay <dtolnay@gmail.com>\"]\nedition = \"2021\"\npublish = false\n\n[lib]\npath = \"lib.rs\"\n\n[dependencies]\ncxx = { path = \"../..\", default-features = false }\nserde = { version = \"1\", features = [\"derive\"] }\n\n[build-dependencies]\ncxx-build = { path = \"../../gen/build\" }\ncxxbridge-flags = { path = \"../../flags\" }\n"
  },
  {
    "path": "tests/ffi/build.rs",
    "content": "#![allow(unknown_lints)]\n#![allow(unexpected_cfgs)]\n\nuse cxx_build::CFG;\n\nfn main() {\n    if cfg!(trybuild) {\n        return;\n    }\n\n    CFG.include_prefix = \"tests/ffi\";\n    let sources = vec![\"lib.rs\", \"module.rs\"];\n    let mut build = cxx_build::bridges(sources);\n    build.file(\"tests.cc\");\n    build.std(cxxbridge_flags::STD);\n    build.warnings_into_errors(cfg!(deny_warnings));\n    if cfg!(not(target_env = \"msvc\")) {\n        build.define(\"CXX_TEST_INSTANTIATIONS\", None);\n    }\n    build.compile(\"cxx-test-suite\");\n\n    println!(\"cargo:rerun-if-changed=tests.cc\");\n    println!(\"cargo:rerun-if-changed=tests.h\");\n}\n"
  },
  {
    "path": "tests/ffi/cast.rs",
    "content": "use std::os::raw::c_char;\nuse std::slice;\n\npub fn c_char_to_unsigned(slice: &[c_char]) -> &[u8] {\n    let ptr = slice.as_ptr().cast::<u8>();\n    let len = slice.len();\n    unsafe { slice::from_raw_parts(ptr, len) }\n}\n\npub fn unsigned_to_c_char(slice: &[u8]) -> &[c_char] {\n    let ptr = slice.as_ptr().cast::<c_char>();\n    let len = slice.len();\n    unsafe { slice::from_raw_parts(ptr, len) }\n}\n"
  },
  {
    "path": "tests/ffi/lib.rs",
    "content": "#![allow(\n    clippy::boxed_local,\n    clippy::elidable_lifetime_names,\n    clippy::missing_errors_doc,\n    clippy::missing_safety_doc,\n    clippy::must_use_candidate,\n    clippy::needless_lifetimes,\n    clippy::needless_pass_by_value,\n    clippy::unnecessary_literal_bound,\n    clippy::unnecessary_wraps,\n    clippy::unused_self\n)]\n#![allow(unknown_lints)]\n#![warn(rust_2024_compatibility)]\n#![forbid(unsafe_op_in_unsafe_fn)]\n#![deny(warnings)] // Check that expansion of `cxx::bridge` doesn't trigger warnings.\n\npub mod cast;\npub mod module;\n\nuse cxx::{type_id, CxxString, CxxVector, ExternType, SharedPtr, UniquePtr};\nuse std::fmt::{self, Display};\nuse std::mem::MaybeUninit;\nuse std::os::raw::c_char;\n\n#[cxx::bridge(namespace = \"tests\")]\npub mod ffi {\n    extern \"C++\" {\n        include!(\"tests/ffi/tests.h\");\n\n        type Undefined;\n        type Private;\n        type Unmovable;\n        type Array;\n    }\n\n    #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]\n    #[serde(deny_unknown_fields)]\n    struct Shared {\n        #[serde(default)]\n        z: usize,\n    }\n\n    #[derive(PartialEq, PartialOrd)]\n    struct SharedString {\n        msg: String,\n    }\n\n    #[derive(Debug, Hash, PartialOrd, Ord, Default, BitAnd, BitOr, BitXor)]\n    enum Enum {\n        AVal,\n        #[default]\n        BVal = 2020,\n        #[cxx_name = \"CVal\"]\n        LastVal,\n    }\n\n    #[namespace = \"A\"]\n    #[derive(Copy, Clone, Default)]\n    struct AShared {\n        #[cxx_name = \"type\"]\n        z: usize,\n    }\n\n    #[namespace = \"A\"]\n    enum AEnum {\n        AAVal,\n        ABVal = 2020,\n        ACVal,\n    }\n\n    #[namespace = \"A::B\"]\n    enum ABEnum {\n        ABAVal,\n        ABBVal = 2020,\n        ABCVal = -2147483648i32,\n    }\n\n    #[namespace = \"A::B\"]\n    #[derive(Clone)]\n    struct ABShared {\n        z: usize,\n    }\n\n    #[namespace = \"first\"]\n    struct First {\n        second: Box<Second>,\n    }\n\n    #[namespace = \"second\"]\n    #[derive(Hash)]\n    struct Second {\n        i: i32,\n        e: COwnedEnum,\n    }\n\n    pub struct WithArray {\n        a: [i32; 4],\n        b: Buffer,\n    }\n\n    #[repr(align(4))]\n    pub struct OveralignedStruct {\n        b: [u8; 4],\n    }\n\n    #[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]\n    pub struct StructWithLifetime<'a> {\n        s: &'a str,\n    }\n\n    unsafe extern \"C++\" {\n        type C;\n\n        fn c_return_primitive() -> usize;\n        fn c_return_shared() -> Shared;\n        fn c_return_box() -> Box<R>;\n        fn c_return_unique_ptr() -> UniquePtr<C>;\n        fn c_return_shared_ptr() -> SharedPtr<C>;\n        fn c_return_ref(shared: &Shared) -> &usize;\n        fn c_return_mut(shared: &mut Shared) -> &mut usize;\n        fn c_return_str(shared: &Shared) -> &str;\n        fn c_return_slice_char(shared: &Shared) -> &[c_char];\n        fn c_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8];\n        fn c_return_rust_string() -> String;\n        fn c_return_rust_string_lossy() -> String;\n        fn c_return_unique_ptr_string() -> UniquePtr<CxxString>;\n        fn c_return_unique_ptr_vector_u8() -> UniquePtr<CxxVector<u8>>;\n        fn c_return_unique_ptr_vector_f64() -> UniquePtr<CxxVector<f64>>;\n        fn c_return_unique_ptr_vector_string() -> UniquePtr<CxxVector<CxxString>>;\n        fn c_return_unique_ptr_vector_shared() -> UniquePtr<CxxVector<Shared>>;\n        fn c_return_unique_ptr_vector_opaque() -> UniquePtr<CxxVector<C>>;\n        fn c_return_ref_vector(c: &C) -> &CxxVector<u8>;\n        fn c_return_mut_vector(c: Pin<&mut C>) -> Pin<&mut CxxVector<u8>>;\n        fn c_return_rust_vec_u8() -> Vec<u8>;\n        fn c_return_ref_rust_vec(c: &C) -> &Vec<u8>;\n        fn c_return_mut_rust_vec(c: Pin<&mut C>) -> &mut Vec<u8>;\n        fn c_return_rust_vec_string() -> Vec<String>;\n        fn c_return_rust_vec_bool() -> Vec<bool>;\n        fn c_return_identity(_: usize) -> usize;\n        fn c_return_sum(_: usize, _: usize) -> usize;\n        fn c_return_enum(n: u16) -> Enum;\n        fn c_return_ns_ref(shared: &AShared) -> &usize;\n        fn c_return_nested_ns_ref(shared: &ABShared) -> &usize;\n        fn c_return_ns_enum(n: u16) -> AEnum;\n        fn c_return_nested_ns_enum(n: u16) -> ABEnum;\n        fn c_return_const_ptr(n: usize) -> *const C;\n        fn c_return_mut_ptr(n: usize) -> *mut C;\n\n        fn c_take_primitive(n: usize);\n        fn c_take_shared(shared: Shared);\n        fn c_take_box(r: Box<R>);\n        fn c_take_ref_r(r: &R);\n        fn c_take_ref_c(c: &C);\n        fn c_take_str(s: &str);\n        fn c_take_slice_char(s: &[c_char]);\n        fn c_take_slice_shared(s: &[Shared]);\n        fn c_take_slice_shared_sort(s: &mut [Shared]);\n        fn c_take_slice_r(s: &[R]);\n        fn c_take_slice_r_sort(s: &mut [R]);\n        fn c_take_rust_string(s: String);\n        fn c_take_unique_ptr_string(s: UniquePtr<CxxString>);\n        fn c_take_unique_ptr_vector_u8(v: UniquePtr<CxxVector<u8>>);\n        fn c_take_unique_ptr_vector_f64(v: UniquePtr<CxxVector<f64>>);\n        fn c_take_unique_ptr_vector_string(v: UniquePtr<CxxVector<CxxString>>);\n        fn c_take_unique_ptr_vector_shared(v: UniquePtr<CxxVector<Shared>>);\n        fn c_take_ref_vector(v: &CxxVector<u8>);\n        fn c_take_rust_vec(v: Vec<u8>);\n        fn c_take_rust_vec_shared(v: Vec<Shared>);\n        fn c_take_rust_vec_string(v: Vec<String>);\n        fn c_take_rust_vec_index(v: Vec<u8>);\n        fn c_take_rust_vec_shared_index(v: Vec<Shared>);\n        fn c_take_rust_vec_shared_push(v: Vec<Shared>);\n        fn c_take_rust_vec_shared_truncate(v: Vec<Shared>);\n        fn c_take_rust_vec_shared_clear(v: Vec<Shared>);\n        fn c_take_rust_vec_shared_forward_iterator(v: Vec<Shared>);\n        fn c_take_rust_vec_shared_sort(v: Vec<Shared>);\n        fn c_take_ref_rust_vec(v: &Vec<u8>);\n        fn c_take_ref_rust_vec_string(v: &Vec<String>);\n        fn c_take_ref_rust_vec_index(v: &Vec<u8>);\n        fn c_take_ref_rust_vec_copy(v: &Vec<u8>);\n        fn c_take_ref_shared_string(s: &SharedString) -> &SharedString;\n        fn c_take_callback(callback: fn(String) -> usize);\n        fn c_take_callback_ref(callback: fn(&String));\n        #[cxx_name = \"c_take_callback_ref\"]\n        fn c_take_callback_ref_lifetime<'a>(callback: fn(&'a String));\n        fn c_take_callback_mut(callback: fn(&mut String));\n        fn c_take_enum(e: Enum);\n        fn c_take_ns_enum(e: AEnum);\n        fn c_take_nested_ns_enum(e: ABEnum);\n        fn c_take_ns_shared(shared: AShared);\n        fn c_take_nested_ns_shared(shared: ABShared);\n        fn c_take_rust_vec_ns_shared(v: Vec<AShared>);\n        fn c_take_rust_vec_nested_ns_shared(v: Vec<ABShared>);\n        unsafe fn c_take_const_ptr(c: *const C) -> usize;\n        unsafe fn c_take_mut_ptr(c: *mut C) -> usize;\n\n        fn c_try_return_void() -> Result<()>;\n        fn c_try_return_primitive() -> Result<usize>;\n        fn c_fail_return_primitive() -> Result<usize>;\n        fn c_try_return_box() -> Result<Box<R>>;\n        fn c_try_return_ref(s: &String) -> Result<&String>;\n        fn c_try_return_str(s: &str) -> Result<&str>;\n        fn c_try_return_sliceu8(s: &[u8]) -> Result<&[u8]>;\n        fn c_try_return_mutsliceu8(s: &mut [u8]) -> Result<&mut [u8]>;\n        fn c_try_return_rust_string() -> Result<String>;\n        fn c_try_return_unique_ptr_string() -> Result<UniquePtr<CxxString>>;\n        fn c_try_return_rust_vec() -> Result<Vec<u8>>;\n        fn c_try_return_rust_vec_string() -> Result<Vec<String>>;\n        fn c_try_return_ref_rust_vec(c: &C) -> Result<&Vec<u8>>;\n\n        fn get(self: &C) -> usize;\n        fn set(self: Pin<&mut C>, n: usize) -> usize;\n        fn get2(&self) -> usize;\n        fn getRef(self: &C) -> &usize;\n        fn getMut(self: Pin<&mut C>) -> &mut usize;\n        fn set_succeed(self: Pin<&mut C>, n: usize) -> Result<usize>;\n        fn get_fail(self: Pin<&mut C>) -> Result<usize>;\n        fn c_method_on_shared(self: &Shared) -> usize;\n        fn c_method_ref_on_shared(self: &Shared) -> &usize;\n        fn c_method_mut_on_shared(self: &mut Shared) -> &mut usize;\n        #[Self = \"Shared\"]\n        fn c_static_method_on_shared() -> usize;\n        fn c_set_array(self: &mut WithArray, value: i32);\n\n        fn c_get_use_count(weak: &WeakPtr<C>) -> usize;\n\n        #[rust_name = \"i32_overloaded_method\"]\n        fn cOverloadedMethod(&self, x: i32) -> String;\n        #[rust_name = \"str_overloaded_method\"]\n        fn cOverloadedMethod(&self, x: &str) -> String;\n        #[rust_name = \"i32_overloaded_function\"]\n        fn cOverloadedFunction(x: i32) -> String;\n        #[rust_name = \"str_overloaded_function\"]\n        fn cOverloadedFunction(x: &str) -> String;\n\n        #[namespace = \"other\"]\n        fn ns_c_take_ns_shared(shared: AShared);\n\n        #[Self = \"C\"]\n        fn c_static_method() -> usize;\n    }\n\n    struct ContainsOpaqueRust<'a> {\n        boxed: Box<OpaqueRust>,\n        vecked: Vec<OpaqueRust>,\n        referenced: &'a mut OpaqueRust,\n        sliced: &'a mut [OpaqueRust],\n    }\n\n    extern \"C++\" {\n        include!(\"tests/ffi/module.rs.h\");\n\n        type COwnedEnum;\n        type Job = crate::module::ffi::Job;\n        type OpaqueRust = crate::module::OpaqueRust;\n    }\n\n    extern \"Rust\" {\n        #[derive(ExternType)]\n        type Reference<'a>;\n    }\n\n    unsafe extern \"C++\" {\n        type Borrow<'a>;\n\n        fn c_return_borrow<'a>(s: &'a CxxString) -> UniquePtr<Borrow<'a>>;\n\n        #[rust_name = \"c_return_borrow_elided\"]\n        #[allow(unknown_lints, mismatched_lifetime_syntaxes)]\n        fn c_return_borrow(s: &CxxString) -> UniquePtr<Borrow>;\n\n        fn const_member(self: &Borrow);\n        fn nonconst_member(self: Pin<&mut Borrow>);\n    }\n\n    #[repr(u32)]\n    #[derive(Hash)]\n    enum COwnedEnum {\n        #[cxx_name = \"CVAL1\"]\n        CVal1,\n        #[cxx_name = \"CVAL2\"]\n        CVal2,\n    }\n\n    extern \"C++\" {\n        type Buffer = crate::Buffer;\n    }\n\n    extern \"Rust\" {\n        type R;\n\n        fn r_return_primitive() -> usize;\n        fn r_return_shared() -> Shared;\n        fn r_return_box() -> Box<R>;\n        fn r_return_unique_ptr() -> UniquePtr<C>;\n        fn r_return_shared_ptr() -> SharedPtr<C>;\n        fn r_return_ref(shared: &Shared) -> &usize;\n        fn r_return_mut(shared: &mut Shared) -> &mut usize;\n        fn r_return_str(shared: &Shared) -> &str;\n        unsafe fn r_return_str_via_out_param<'a>(shared: &'a Shared, out_param: &mut &'a str);\n        fn r_return_sliceu8(shared: &Shared) -> &[u8];\n        fn r_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8];\n        fn r_return_rust_string() -> String;\n        fn r_return_unique_ptr_string() -> UniquePtr<CxxString>;\n        fn r_return_rust_vec() -> Vec<u8>;\n        fn r_return_rust_vec_string() -> Vec<String>;\n        fn r_return_rust_vec_extern_struct() -> Vec<Job>;\n        #[allow(clippy::vec_box)]\n        fn r_return_rust_vec_box() -> Vec<Box<R>>;\n        #[allow(clippy::vec_box)]\n        fn r_return_rust_vec_box_other_module_type() -> Vec<Box<OpaqueRust>>;\n        fn r_return_ref_rust_vec(shared: &Shared) -> &Vec<u8>;\n        fn r_return_mut_rust_vec(shared: &mut Shared) -> &mut Vec<u8>;\n        fn r_return_identity(_: usize) -> usize;\n        fn r_return_sum(_: usize, _: usize) -> usize;\n        fn r_return_enum(n: u32) -> Enum;\n\n        fn r_take_primitive(n: usize);\n        fn r_take_shared(shared: Shared);\n        fn r_take_box(r: Box<R>);\n        fn r_take_unique_ptr(c: UniquePtr<C>);\n        fn r_take_shared_ptr(c: SharedPtr<C>);\n        fn r_take_ref_r(r: &R);\n        fn r_take_ref_c(c: &C);\n        fn r_take_str(s: &str);\n        fn r_take_slice_char(s: &[c_char]);\n        fn r_take_rust_string(s: String);\n        fn r_take_unique_ptr_string(s: UniquePtr<CxxString>);\n        fn r_take_ref_vector(v: &CxxVector<u8>);\n        fn r_take_ref_empty_vector(v: &CxxVector<u64>);\n        fn r_take_rust_vec(v: Vec<u8>);\n        fn r_take_rust_vec_string(v: Vec<String>);\n        fn r_take_ref_rust_vec(v: &Vec<u8>);\n        fn r_take_ref_rust_vec_string(v: &Vec<String>);\n        fn r_take_enum(e: Enum);\n\n        fn r_try_return_void() -> Result<()>;\n        fn r_try_return_primitive() -> Result<usize>;\n        fn r_try_return_box() -> Result<Box<R>>;\n        fn r_fail_return_primitive() -> Result<usize>;\n        fn r_try_return_sliceu8(s: &[u8]) -> Result<&[u8]>;\n        fn r_try_return_mutsliceu8(s: &mut [u8]) -> Result<&mut [u8]>;\n\n        fn get(self: &R) -> usize;\n        fn set(self: &mut R, n: usize) -> usize;\n        fn r_method_on_shared(self: &Shared) -> String;\n        fn r_get_array_sum(self: &WithArray) -> i32;\n        // Ensure that a Rust method can be implemented on an opaque C++ type.\n        fn r_method_on_c_get_mut(self: Pin<&mut C>) -> &mut usize;\n\n        #[cxx_name = \"rAliasedFunction\"]\n        fn r_aliased_function(x: i32) -> String;\n\n        #[Self = \"Shared\"]\n        fn r_static_method_on_shared() -> usize;\n\n        #[Self = \"R\"]\n        fn r_static_method() -> usize;\n    }\n\n    unsafe extern \"C++\" {\n        fn c_member_function_on_rust_type(self: &R);\n    }\n\n    struct Dag0 {\n        i: i32,\n    }\n\n    struct Dag1 {\n        dag2: Dag2,\n        vec: Vec<Dag3>,\n    }\n\n    struct Dag2 {\n        dag4: Dag4,\n    }\n\n    struct Dag3 {\n        dag1: Dag1,\n    }\n\n    struct Dag4 {\n        dag0: Dag0,\n    }\n\n    impl Box<Shared> {}\n    impl CxxVector<SharedString> {}\n    impl SharedPtr<Undefined> {}\n    impl SharedPtr<Private> {}\n    impl CxxVector<Unmovable> {}\n    impl UniquePtr<Array> {}\n}\n\n#[rustfmt::skip]\n#[cxx::bridge(namespace = \"tests\")]\npub mod ffi_no_rustfmt {\n    // Rustfmt would replace `StructWithLifetime2<>` by `StructWithLifetime2`,\n    // but the test is meant to cover specifically the former spelling.\n    pub struct StructWithLifetime2<'a> {\n        s: &'a str,\n    }\n    extern \"Rust\" {\n        fn r_take_unique_ptr_of_struct_with_lifetime2(_: UniquePtr<StructWithLifetime2<>>);\n    }\n}\n\nmod other {\n    use cxx::kind::{Opaque, Trivial};\n    use cxx::{type_id, CxxString, ExternType};\n\n    #[repr(C)]\n    pub struct D {\n        pub d: u64,\n    }\n\n    #[repr(C)]\n    pub struct E {\n        e: u64,\n        e_str: CxxString,\n    }\n\n    pub mod f {\n        use cxx::kind::Opaque;\n        use cxx::{type_id, CxxString, ExternType};\n\n        #[repr(C)]\n        pub struct F {\n            e: u64,\n            e_str: CxxString,\n        }\n\n        unsafe impl ExternType for F {\n            type Id = type_id!(\"F::F\");\n            type Kind = Opaque;\n        }\n    }\n\n    #[repr(C)]\n    pub struct G {\n        pub g: u64,\n    }\n\n    unsafe impl ExternType for G {\n        type Id = type_id!(\"G::G\");\n        type Kind = Trivial;\n    }\n\n    unsafe impl ExternType for D {\n        type Id = type_id!(\"tests::D\");\n        type Kind = Trivial;\n    }\n\n    unsafe impl ExternType for E {\n        type Id = type_id!(\"tests::E\");\n        type Kind = Opaque;\n    }\n}\n\n#[derive(PartialEq, Debug)]\npub struct R(pub usize);\n\nimpl R {\n    fn get(&self) -> usize {\n        self.0\n    }\n\n    fn set(&mut self, n: usize) -> usize {\n        self.0 = n;\n        n\n    }\n\n    fn r_static_method() -> usize {\n        2024\n    }\n}\n\npub struct Reference<'a>(pub &'a String);\n\nimpl ffi::Shared {\n    fn r_method_on_shared(&self) -> String {\n        \"2020\".to_owned()\n    }\n\n    fn r_static_method_on_shared() -> usize {\n        2023\n    }\n}\n\nimpl ffi::WithArray {\n    pub fn r_get_array_sum(&self) -> i32 {\n        self.a.iter().sum()\n    }\n}\n\n// A Rust method implemented on an opaque C++ type.\nimpl ffi::C {\n    pub fn r_method_on_c_get_mut(self: core::pin::Pin<&mut Self>) -> &mut usize {\n        self.getMut()\n    }\n}\n\n#[derive(Default)]\n#[repr(C)]\npub struct Buffer([c_char; 12]);\n\nunsafe impl ExternType for Buffer {\n    type Id = type_id!(\"tests::Buffer\");\n    type Kind = cxx::kind::Trivial;\n}\n\n#[derive(Debug)]\nstruct Error;\n\nimpl std::error::Error for Error {}\n\nimpl Display for Error {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.write_str(\"rust error\")\n    }\n}\n\nfn r_return_primitive() -> usize {\n    2020\n}\n\nfn r_return_shared() -> ffi::Shared {\n    ffi::Shared { z: 2020 }\n}\n\nfn r_return_box() -> Box<R> {\n    Box::new(R(2020))\n}\n\nfn r_return_unique_ptr() -> UniquePtr<ffi::C> {\n    #[allow(missing_unsafe_on_extern)]\n    extern \"C\" {\n        fn cxx_test_suite_get_unique_ptr() -> *mut ffi::C;\n    }\n    unsafe { UniquePtr::from_raw(cxx_test_suite_get_unique_ptr()) }\n}\n\nfn r_return_shared_ptr() -> SharedPtr<ffi::C> {\n    #[allow(missing_unsafe_on_extern)]\n    extern \"C\" {\n        fn cxx_test_suite_get_shared_ptr(repr: *mut SharedPtr<ffi::C>);\n    }\n    let mut shared_ptr = MaybeUninit::<SharedPtr<ffi::C>>::uninit();\n    let repr = shared_ptr.as_mut_ptr();\n    unsafe {\n        cxx_test_suite_get_shared_ptr(repr);\n        shared_ptr.assume_init()\n    }\n}\n\nfn r_return_ref(shared: &ffi::Shared) -> &usize {\n    &shared.z\n}\n\nfn r_return_mut(shared: &mut ffi::Shared) -> &mut usize {\n    &mut shared.z\n}\n\nfn r_return_str(shared: &ffi::Shared) -> &str {\n    let _ = shared;\n    \"2020\"\n}\n\nfn r_return_str_via_out_param<'a>(shared: &'a ffi::Shared, out_param: &mut &'a str) {\n    let _ = shared;\n    *out_param = \"2020\";\n}\n\nfn r_return_sliceu8(shared: &ffi::Shared) -> &[u8] {\n    let _ = shared;\n    b\"2020\"\n}\n\nfn r_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8] {\n    slice\n}\n\nfn r_return_rust_string() -> String {\n    \"2020\".to_owned()\n}\n\nfn r_return_unique_ptr_string() -> UniquePtr<CxxString> {\n    #[allow(missing_unsafe_on_extern)]\n    extern \"C\" {\n        fn cxx_test_suite_get_unique_ptr_string() -> *mut CxxString;\n    }\n    unsafe { UniquePtr::from_raw(cxx_test_suite_get_unique_ptr_string()) }\n}\n\nfn r_return_rust_vec() -> Vec<u8> {\n    Vec::new()\n}\n\nfn r_return_rust_vec_string() -> Vec<String> {\n    Vec::new()\n}\n\nfn r_return_rust_vec_extern_struct() -> Vec<ffi::Job> {\n    Vec::new()\n}\n\n#[allow(clippy::vec_box)]\nfn r_return_rust_vec_box() -> Vec<Box<R>> {\n    vec![Box::new(R(2020))]\n}\n\n#[allow(clippy::vec_box)]\nfn r_return_rust_vec_box_other_module_type() -> Vec<Box<module::OpaqueRust>> {\n    vec![Box::new(module::OpaqueRust(2025))]\n}\n\nfn r_return_ref_rust_vec(shared: &ffi::Shared) -> &Vec<u8> {\n    let _ = shared;\n    unimplemented!()\n}\n\nfn r_return_mut_rust_vec(shared: &mut ffi::Shared) -> &mut Vec<u8> {\n    let _ = shared;\n    unimplemented!()\n}\n\nfn r_return_identity(n: usize) -> usize {\n    n\n}\n\nfn r_return_sum(n1: usize, n2: usize) -> usize {\n    n1 + n2\n}\n\nfn r_return_enum(n: u32) -> ffi::Enum {\n    if n == 0 {\n        ffi::Enum::AVal\n    } else if n <= 2020 {\n        ffi::Enum::BVal\n    } else {\n        ffi::Enum::LastVal\n    }\n}\n\nfn r_take_primitive(n: usize) {\n    assert_eq!(n, 2020);\n}\n\nfn r_take_shared(shared: ffi::Shared) {\n    assert_eq!(shared.z, 2020);\n}\n\nfn r_take_box(r: Box<R>) {\n    let _ = r;\n}\n\nfn r_take_unique_ptr(c: UniquePtr<ffi::C>) {\n    let _ = c;\n}\n\nfn r_take_shared_ptr(c: SharedPtr<ffi::C>) {\n    let _ = c;\n}\n\nfn r_take_ref_r(r: &R) {\n    let _ = r;\n}\n\nfn r_take_ref_c(c: &ffi::C) {\n    let _ = c;\n}\n\nfn r_take_str(s: &str) {\n    assert_eq!(s, \"2020\");\n}\n\nfn r_take_rust_string(s: String) {\n    assert_eq!(s, \"2020\");\n}\n\nfn r_take_slice_char(s: &[c_char]) {\n    assert_eq!(s.len(), 5);\n    let s = cast::c_char_to_unsigned(s);\n    assert_eq!(std::str::from_utf8(s).unwrap(), \"2020\\0\");\n}\n\nfn r_take_unique_ptr_string(s: UniquePtr<CxxString>) {\n    assert_eq!(s.as_ref().unwrap().to_str().unwrap(), \"2020\");\n}\n\nfn r_take_ref_vector(v: &CxxVector<u8>) {\n    let slice = v.as_slice();\n    assert_eq!(slice, [20, 2, 0]);\n}\n\nfn r_take_ref_empty_vector(v: &CxxVector<u64>) {\n    assert!(v.as_slice().is_empty());\n    assert!(v.is_empty());\n}\n\nfn r_take_rust_vec(v: Vec<u8>) {\n    let _ = v;\n}\n\nfn r_take_rust_vec_string(v: Vec<String>) {\n    let _ = v;\n}\n\nfn r_take_ref_rust_vec(v: &Vec<u8>) {\n    let _ = v;\n}\n\nfn r_take_ref_rust_vec_string(v: &Vec<String>) {\n    let _ = v;\n}\n\nfn r_take_enum(e: ffi::Enum) {\n    let _ = e;\n}\n\nfn r_take_unique_ptr_of_struct_with_lifetime2(\n    _: cxx::UniquePtr<ffi_no_rustfmt::StructWithLifetime2>,\n) {\n}\n\nfn r_try_return_void() -> Result<(), Error> {\n    Ok(())\n}\n\nfn r_try_return_primitive() -> Result<usize, Error> {\n    Ok(2020)\n}\n\nfn r_try_return_box() -> Result<Box<R>, Error> {\n    Ok(Box::new(R(2020)))\n}\n\nfn r_fail_return_primitive() -> Result<usize, Error> {\n    Err(Error)\n}\n\nfn r_try_return_sliceu8(slice: &[u8]) -> Result<&[u8], Error> {\n    Ok(slice)\n}\n\nfn r_try_return_mutsliceu8(slice: &mut [u8]) -> Result<&mut [u8], Error> {\n    Ok(slice)\n}\n\nfn r_aliased_function(x: i32) -> String {\n    x.to_string()\n}\n"
  },
  {
    "path": "tests/ffi/module.rs",
    "content": "#![deny(warnings)] // Check that expansion of `cxx::bridge` doesn't trigger warnings.\n\npub struct OpaqueRust(pub i32);\n\n#[cxx::bridge(namespace = \"tests\")]\npub mod ffi {\n    struct Job {\n        raw: u32,\n    }\n\n    unsafe extern \"C++\" {\n        include!(\"tests/ffi/tests.h\");\n\n        type C = crate::ffi::C;\n\n        fn c_take_unique_ptr(c: UniquePtr<C>);\n        fn c_lifetime_elision_member_fn(self: &C) -> &CxxVector<u8>;\n        fn c_lifetime_elision_fn(c: &C) -> &CxxVector<u8>;\n    }\n\n    extern \"Rust\" {\n        #[derive(ExternType)]\n        type OpaqueRust;\n    }\n\n    impl Vec<Job> {}\n    impl Box<OpaqueRust> {}\n    impl Vec<OpaqueRust> {}\n    impl Vec<Box<OpaqueRust>> {}\n}\n\n#[cxx::bridge(namespace = \"tests\")]\npub mod ffi2 {\n    unsafe extern \"C++\" {\n        include!(\"tests/ffi/tests.h\");\n\n        type D = crate::other::D;\n        type E = crate::other::E;\n        #[namespace = \"F\"]\n        type F = crate::other::f::F;\n        #[namespace = \"G\"]\n        type G = crate::other::G;\n\n        #[namespace = \"H\"]\n        type H;\n\n        fn c_take_trivial_ptr(d: UniquePtr<D>);\n        fn c_take_trivial_ref(d: &D);\n        fn c_take_trivial_mut_ref(d: &mut D);\n        fn c_take_trivial_pin_ref(d: Pin<&D>);\n        fn c_take_trivial_pin_mut_ref(d: Pin<&mut D>);\n        fn c_take_trivial_ref_method(self: &D);\n        fn c_take_trivial_mut_ref_method(self: &mut D);\n        fn c_take_trivial(d: D);\n        fn c_take_trivial_ns_ptr(g: UniquePtr<G>);\n        fn c_take_trivial_ns_ref(g: &G);\n        fn c_take_trivial_ns(g: G);\n        fn c_take_opaque_ptr(e: UniquePtr<E>);\n        fn c_take_opaque_ref(e: &E);\n        fn c_take_opaque_ref_method(self: &E);\n        fn c_take_opaque_mut_ref_method(self: Pin<&mut E>);\n        fn c_take_opaque_ns_ptr(e: UniquePtr<F>);\n        fn c_take_opaque_ns_ref(e: &F);\n        fn c_return_trivial_ptr() -> UniquePtr<D>;\n        fn c_return_trivial() -> D;\n        fn c_return_trivial_ns_ptr() -> UniquePtr<G>;\n        fn c_return_trivial_ns() -> G;\n        fn c_return_opaque_ptr() -> UniquePtr<E>;\n        fn c_return_opaque_mut_pin(e: Pin<&mut E>) -> Pin<&mut E>;\n        fn c_return_ns_opaque_ptr() -> UniquePtr<F>;\n        fn c_return_ns_unique_ptr() -> UniquePtr<H>;\n        fn c_take_ref_ns_c(h: &H);\n\n        #[namespace = \"other\"]\n        fn ns_c_take_trivial(d: D);\n        #[namespace = \"other\"]\n        fn ns_c_return_trivial() -> D;\n\n        #[namespace = \"I\"]\n        type I;\n\n        fn get(self: &I) -> u32;\n\n        #[namespace = \"I\"]\n        fn ns_c_return_unique_ptr_ns() -> UniquePtr<I>;\n    }\n\n    impl UniquePtr<D> {}\n    impl UniquePtr<E> {}\n    impl UniquePtr<F> {}\n    impl UniquePtr<G> {}\n}\n"
  },
  {
    "path": "tests/ffi/tests.cc",
    "content": "#include \"tests/ffi/tests.h\"\n#include \"tests/ffi/lib.rs.h\"\n#include <array>\n#include <cstdlib>\n#include <cstring>\n#include <iterator>\n#include <memory>\n#include <numeric>\n#ifdef __cpp_lib_span\n#include <span>\n#endif // __cpp_lib_span\n#include <stdexcept>\n#include <string>\n#include <tuple>\n\n#ifdef __GNUC__\n#pragma GCC diagnostic ignored \"-Wshadow\"\n#endif\n\nextern \"C\" void cxx_test_suite_set_correct() noexcept;\nextern \"C\" tests::R *cxx_test_suite_get_box() noexcept;\nextern \"C\" bool cxx_test_suite_r_is_correct(const tests::R *) noexcept;\n\nnamespace tests {\n\nstatic_assert(4 == alignof(OveralignedStruct), \"expected 4 byte alignment\");\n\nstatic constexpr char SLICE_DATA[] = \"2020\";\n\nC::C(size_t n) : n(n) {}\n\nsize_t C::get() const { return this->n; }\n\nsize_t C::get2() const { return this->n; }\n\nconst size_t &C::getRef() const { return this->n; }\n\nsize_t &C::getMut() { return this->n; }\n\nsize_t C::set(size_t n) {\n  this->n = n;\n  return this->n;\n}\n\nsize_t C::set_succeed(size_t n) { return this->set(n); }\n\nsize_t C::get_fail() { throw std::runtime_error(\"unimplemented\"); }\n\nsize_t Shared::c_method_on_shared() const noexcept { return 2021; }\n\nconst size_t &Shared::c_method_ref_on_shared() const noexcept {\n  return this->z;\n}\n\nsize_t &Shared::c_method_mut_on_shared() noexcept { return this->z; }\n\nsize_t Shared::c_static_method_on_shared() noexcept { return 2025; }\n\nvoid WithArray::c_set_array(int32_t val) noexcept {\n  this->a = {val, val, val, val};\n}\n\nconst std::vector<uint8_t> &C::get_v() const { return this->v; }\n\nstd::vector<uint8_t> &C::get_v() { return this->v; }\n\nsize_t c_return_primitive() { return 2020; }\n\nShared c_return_shared() { return Shared{2020}; }\n\n::A::AShared c_return_ns_shared() { return ::A::AShared{2020}; }\n\n::A::B::ABShared c_return_nested_ns_shared() { return ::A::B::ABShared{2020}; }\n\nrust::Box<R> c_return_box() {\n  Shared shared{0};\n  rust::Box<Shared> box{shared}; // explicit constructor from const T&\n  rust::Box<Shared> other{std::move(shared)}; // explicit constructor from T&&\n  box = std::move(other);                     // move assignment\n  rust::Box<Shared> box2(*box);               // copy from another Box\n  rust::Box<Shared> other2(std::move(other)); // move constructor\n  rust::Box<Shared>::in_place(shared.z);      // placement static factory\n  rust::Box<Shared>::in_place<size_t>(0);\n  return rust::Box<R>::from_raw(cxx_test_suite_get_box());\n}\n\nstd::unique_ptr<C> c_return_unique_ptr() {\n  return std::unique_ptr<C>(new C{2020});\n}\n\nstd::shared_ptr<C> c_return_shared_ptr() {\n  return std::shared_ptr<C>(new C{2020});\n}\n\nstd::unique_ptr<::H::H> c_return_ns_unique_ptr() {\n  return std::unique_ptr<::H::H>(new ::H::H{\"hello\"});\n}\n\nconst size_t &c_return_ref(const Shared &shared) { return shared.z; }\n\nconst size_t &c_return_ns_ref(const ::A::AShared &shared) {\n  return shared.type;\n}\n\nconst size_t &c_return_nested_ns_ref(const ::A::B::ABShared &shared) {\n  return shared.z;\n}\n\nsize_t &c_return_mut(Shared &shared) { return shared.z; }\n\nrust::Str c_return_str(const Shared &shared) {\n  (void)shared;\n  return \"2020\";\n}\n\nrust::Slice<const char> c_return_slice_char(const Shared &shared) {\n  (void)shared;\n  return rust::Slice<const char>(SLICE_DATA, sizeof(SLICE_DATA));\n}\n\nrust::Slice<uint8_t> c_return_mutsliceu8(rust::Slice<uint8_t> slice) {\n  return slice;\n}\n\nrust::String c_return_rust_string() { return \"2020\"; }\n\nrust::String c_return_rust_string_lossy() {\n  return rust::String::lossy(\"Hello \\xf0\\x90\\x80World\");\n}\n\nstd::unique_ptr<std::string> c_return_unique_ptr_string() {\n  return std::unique_ptr<std::string>(new std::string(\"2020\"));\n}\n\nstd::unique_ptr<std::vector<uint8_t>> c_return_unique_ptr_vector_u8() {\n  auto vec = std::unique_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>());\n  vec->push_back(86);\n  vec->push_back(75);\n  vec->push_back(30);\n  vec->push_back(9);\n  return vec;\n}\n\nstd::unique_ptr<std::vector<double>> c_return_unique_ptr_vector_f64() {\n  auto vec = std::unique_ptr<std::vector<double>>(new std::vector<double>());\n  vec->push_back(86.0);\n  vec->push_back(75.0);\n  vec->push_back(30.0);\n  vec->push_back(9.5);\n  return vec;\n}\n\nstd::unique_ptr<std::vector<std::string>> c_return_unique_ptr_vector_string() {\n  return std::unique_ptr<std::vector<std::string>>(\n      new std::vector<std::string>());\n}\n\nstd::unique_ptr<std::vector<Shared>> c_return_unique_ptr_vector_shared() {\n  auto vec = std::unique_ptr<std::vector<Shared>>(new std::vector<Shared>());\n  vec->push_back(Shared{1010});\n  vec->push_back(Shared{1011});\n  return vec;\n}\n\nstd::unique_ptr<std::vector<C>> c_return_unique_ptr_vector_opaque() {\n  return std::unique_ptr<std::vector<C>>(new std::vector<C>());\n}\n\nconst std::vector<uint8_t> &c_return_ref_vector(const C &c) {\n  return c.get_v();\n}\n\nstd::vector<uint8_t> &c_return_mut_vector(C &c) { return c.get_v(); }\n\nrust::Vec<uint8_t> c_return_rust_vec_u8() {\n  rust::Vec<uint8_t> vec{2, 0, 2, 0};\n  return vec;\n}\n\nconst rust::Vec<uint8_t> &c_return_ref_rust_vec(const C &c) {\n  (void)c;\n  throw std::runtime_error(\"unimplemented\");\n}\n\nrust::Vec<uint8_t> &c_return_mut_rust_vec(C &c) {\n  (void)c;\n  throw std::runtime_error(\"unimplemented\");\n}\n\nrust::Vec<rust::String> c_return_rust_vec_string() {\n  return {\"2\", \"0\", \"2\", \"0\"};\n}\n\nrust::Vec<bool> c_return_rust_vec_bool() { return {true, true, false}; }\n\nsize_t c_return_identity(size_t n) { return n; }\n\nsize_t c_return_sum(size_t n1, size_t n2) { return n1 + n2; }\n\nEnum c_return_enum(uint16_t n) {\n  if (n <= static_cast<uint16_t>(Enum::AVal)) {\n    return Enum::AVal;\n  } else if (n <= static_cast<uint16_t>(Enum::BVal)) {\n    return Enum::BVal;\n  } else {\n    return Enum::CVal;\n  }\n}\n\n::A::AEnum c_return_ns_enum(uint16_t n) {\n  if (n <= static_cast<uint16_t>(::A::AEnum::AAVal)) {\n    return ::A::AEnum::AAVal;\n  } else if (n <= static_cast<uint16_t>(::A::AEnum::ABVal)) {\n    return ::A::AEnum::ABVal;\n  } else {\n    return ::A::AEnum::ACVal;\n  }\n}\n\n::A::B::ABEnum c_return_nested_ns_enum(uint16_t n) {\n  if (n <= static_cast<uint16_t>(::A::B::ABEnum::ABAVal)) {\n    return ::A::B::ABEnum::ABAVal;\n  } else if (n <= static_cast<uint16_t>(::A::B::ABEnum::ABBVal)) {\n    return ::A::B::ABEnum::ABBVal;\n  } else {\n    return ::A::B::ABEnum::ABCVal;\n  }\n}\n\nconst C *c_return_const_ptr(size_t c) { return new C(c); }\n\nC *c_return_mut_ptr(size_t c) { return new C(c); }\n\nBorrow::Borrow(const std::string &s) : s(s) {}\n\nvoid Borrow::const_member() const {}\n\nvoid Borrow::nonconst_member() {}\n\nstd::unique_ptr<Borrow> c_return_borrow(const std::string &s) {\n  return std::unique_ptr<Borrow>(new Borrow(s));\n}\n\nvoid c_take_primitive(size_t n) {\n  if (n == 2020) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_shared(Shared shared) {\n  if (shared.z == 2020) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_ns_shared(::A::AShared shared) {\n  if (shared.type == 2020) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_nested_ns_shared(::A::B::ABShared shared) {\n  if (shared.z == 2020) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_box(rust::Box<R> r) {\n  if (cxx_test_suite_r_is_correct(&*r)) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_unique_ptr(std::unique_ptr<C> c) {\n  if (c->get() == 2020) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_ref_r(const R &r) {\n  if (cxx_test_suite_r_is_correct(&r)) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_ref_c(const C &c) {\n  if (c.get() == 2020) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_ref_ns_c(const ::H::H &h) {\n  if (h.h == \"hello\") {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_str(rust::Str s) {\n  if (std::string(s) == \"2020\") {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_slice_char(rust::Slice<const char> s) {\n  if (std::string(s.data(), s.size()) == \"2020\") {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_slice_shared(rust::Slice<const Shared> s) {\n  if (s.size() == 2 && s.data()->z == 2020 && s[1].z == 2021 &&\n      s.at(1).z == 2021 && s.front().z == 2020 && s.back().z == 2021) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_slice_shared_sort(rust::Slice<Shared> s) {\n  // Exercise requirements of RandomAccessIterator.\n  // https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator\n  std::sort(s.begin(), s.end());\n  if (s[0].z == 0 && s[1].z == 2 && s[2].z == 4 && s[3].z == 7) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_slice_r(rust::Slice<const R> s) {\n  if (s.size() == 3 && s[0].get() == 2020 && s[1].get() == 2050) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nbool operator<(const R &a, const R &b) noexcept { return a.get() < b.get(); }\n\nvoid c_take_slice_r_sort(rust::Slice<R> s) {\n  std::qsort(s.data(), s.size(), rust::size_of<decltype(s)::value_type>(),\n             [](const void *fst, const void *snd) {\n               auto &a = *static_cast<const R *>(fst);\n               auto &b = *static_cast<const R *>(snd);\n               return a < b ? -1 : b < a ? 1 : 0;\n             });\n  if (s[0].get() == 2020 && s[1].get() == 2021 && s[2].get() == 2050) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_rust_string(rust::String s) {\n  if (std::string(s) == \"2020\") {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_unique_ptr_string(std::unique_ptr<std::string> s) {\n  if (*s == \"2020\") {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_unique_ptr_vector_u8(std::unique_ptr<std::vector<uint8_t>> v) {\n  if (v->size() == 3) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_unique_ptr_vector_f64(std::unique_ptr<std::vector<double>> v) {\n  if (v->size() == 5) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_unique_ptr_vector_string(\n    std::unique_ptr<std::vector<std::string>> v) {\n  (void)v;\n  cxx_test_suite_set_correct();\n}\n\nvoid c_take_unique_ptr_vector_shared(std::unique_ptr<std::vector<Shared>> v) {\n  if (v->size() == 3) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_ref_vector(const std::vector<uint8_t> &v) {\n  if (v.size() == 4) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_rust_vec(rust::Vec<uint8_t> v) { c_take_ref_rust_vec(v); }\n\nvoid c_take_rust_vec_index(rust::Vec<uint8_t> v) {\n  try {\n    v.at(100);\n  } catch (const std::out_of_range &ex) {\n    std::string expected = \"rust::Vec index out of range\";\n    if (ex.what() == expected) {\n      cxx_test_suite_set_correct();\n    }\n  }\n}\n\nvoid c_take_rust_vec_shared(rust::Vec<Shared> v) {\n  uint32_t sum = 0;\n  for (auto i : v) {\n    sum += i.z;\n  }\n  if (sum == 2021) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_rust_vec_ns_shared(rust::Vec<::A::AShared> v) {\n  uint32_t sum = 0;\n  for (auto i : v) {\n    sum += i.type;\n  }\n  if (sum == 2021) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_rust_vec_nested_ns_shared(rust::Vec<::A::B::ABShared> v) {\n  uint32_t sum = 0;\n  for (auto i : v) {\n    sum += i.z;\n  }\n  if (sum == 2021) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_rust_vec_string(rust::Vec<rust::String> v) {\n  (void)v;\n  cxx_test_suite_set_correct();\n}\n\nvoid c_take_rust_vec_shared_forward_iterator(rust::Vec<Shared> v) {\n  // Exercise requirements of ForwardIterator\n  // https://en.cppreference.com/w/cpp/named_req/ForwardIterator\n  uint32_t sum = 0, csum = 0;\n  for (auto it = v.begin(), it_end = v.end(); it != it_end; it++) {\n    sum += it->z;\n  }\n  for (auto it = v.cbegin(), it_end = v.cend(); it != it_end; it++) {\n    csum += it->z;\n  }\n  if (sum == 2021 && csum == 2021) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_rust_vec_shared_sort(rust::Vec<Shared> v) {\n  // Exercise requirements of RandomAccessIterator.\n  // https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator\n  std::sort(v.begin(), v.end());\n  if (v[0].z == 0 && v[1].z == 2 && v[2].z == 4 && v[3].z == 7) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_rust_vec_shared_index(rust::Vec<Shared> v) {\n  if (v[0].z == 1010 && v.at(0).z == 1010 && v.front().z == 1010 &&\n      v[1].z == 1011 && v.at(1).z == 1011 && v.back().z == 1011) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_rust_vec_shared_push(rust::Vec<Shared> v) {\n  v.push_back(Shared{3});\n  v.emplace_back(Shared{2});\n  if (v[v.size() - 2].z == 3 && v.back().z == 2) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_rust_vec_shared_truncate(rust::Vec<Shared> v) {\n  v.truncate(1);\n  if (v.size() == 1) {\n    v.truncate(0);\n    if (v.size() == 0) {\n      cxx_test_suite_set_correct();\n    }\n  }\n}\n\nvoid c_take_rust_vec_shared_clear(rust::Vec<Shared> v) {\n  v.clear();\n  if (v.size() == 0) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_ref_rust_vec(const rust::Vec<uint8_t> &v) {\n  uint8_t sum = std::accumulate(v.begin(), v.end(), 0);\n  if (sum == 200) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_ref_rust_vec_string(const rust::Vec<rust::String> &v) {\n  (void)v;\n  cxx_test_suite_set_correct();\n}\n\nvoid c_take_ref_rust_vec_index(const rust::Vec<uint8_t> &v) {\n  if (v[0] == 86 && v.at(0) == 86 && v.front() == 86 && v[1] == 75 &&\n      v.at(1) == 75 && v[3] == 9 && v.at(3) == 9 && v.back() == 9) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_ref_rust_vec_copy(const rust::Vec<uint8_t> &v) {\n  // The std::copy() will make sure rust::Vec<>::const_iterator satisfies the\n  // requirements for std::iterator_traits.\n  // https://en.cppreference.com/w/cpp/iterator/iterator_traits\n  std::vector<uint8_t> stdv;\n  std::copy(v.begin(), v.end(), std::back_inserter(stdv));\n  uint8_t sum = std::accumulate(stdv.begin(), stdv.end(), 0);\n  if (sum == 200) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nconst SharedString &c_take_ref_shared_string(const SharedString &s) {\n  if (std::string(s.msg) == \"2020\") {\n    cxx_test_suite_set_correct();\n  }\n  return s;\n}\n\nvoid c_take_callback(rust::Fn<size_t(rust::String)> callback) {\n  callback(\"2020\");\n}\n\nvoid c_take_callback_ref(rust::Fn<void(const rust::String &)> callback) {\n  const rust::String string = \"2020\";\n  callback(string);\n}\n\nvoid c_take_callback_mut(rust::Fn<void(rust::String &)> callback) {\n  rust::String string = \"2020\";\n  callback(string);\n}\n\nvoid c_take_enum(Enum e) {\n  if (e == Enum::AVal) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_ns_enum(::A::AEnum e) {\n  if (e == ::A::AEnum::AAVal) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_nested_ns_enum(::A::B::ABEnum e) {\n  if (e == ::A::B::ABEnum::ABAVal) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nsize_t c_take_const_ptr(const C *c) { return c->get(); }\n\nsize_t c_take_mut_ptr(C *c) {\n  size_t result = c->get();\n  delete c;\n  return result;\n}\n\nvoid c_try_return_void() {}\n\nsize_t c_try_return_primitive() { return 2020; }\n\nsize_t c_fail_return_primitive() { throw std::logic_error(\"logic error\"); }\n\nrust::Box<R> c_try_return_box() { return c_return_box(); }\n\nconst rust::String &c_try_return_ref(const rust::String &s) { return s; }\n\nrust::Str c_try_return_str(rust::Str s) { return s; }\n\nrust::Slice<const uint8_t> c_try_return_sliceu8(rust::Slice<const uint8_t> s) {\n  return s;\n}\n\nrust::Slice<uint8_t> c_try_return_mutsliceu8(rust::Slice<uint8_t> s) {\n  return s;\n}\n\nrust::String c_try_return_rust_string() { return c_return_rust_string(); }\n\nstd::unique_ptr<std::string> c_try_return_unique_ptr_string() {\n  return c_return_unique_ptr_string();\n}\n\nrust::Vec<uint8_t> c_try_return_rust_vec() {\n  throw std::runtime_error(\"unimplemented\");\n}\n\nrust::Vec<rust::String> c_try_return_rust_vec_string() {\n  throw std::runtime_error(\"unimplemented\");\n}\n\nconst rust::Vec<uint8_t> &c_try_return_ref_rust_vec(const C &c) {\n  (void)c;\n  throw std::runtime_error(\"unimplemented\");\n}\n\nsize_t c_get_use_count(const std::weak_ptr<C> &weak) noexcept {\n  return weak.use_count();\n}\n\nextern \"C\" C *cxx_test_suite_get_unique_ptr() noexcept {\n  return std::unique_ptr<C>(new C{2020}).release();\n}\n\nextern \"C\" void\ncxx_test_suite_get_shared_ptr(std::shared_ptr<C> *repr) noexcept {\n  new (repr) std::shared_ptr<C>(new C{2020});\n}\n\nextern \"C\" std::string *cxx_test_suite_get_unique_ptr_string() noexcept {\n  return std::unique_ptr<std::string>(new std::string(\"2020\")).release();\n}\n\nconst std::vector<uint8_t> &C::c_lifetime_elision_member_fn() const {\n  return this->get_v();\n}\n\nconst std::vector<uint8_t> &c_lifetime_elision_fn(const C &c) {\n  return c.get_v();\n}\n\nrust::String C::cOverloadedMethod(int32_t x) const {\n  return rust::String(std::to_string(x));\n}\n\nrust::String C::cOverloadedMethod(rust::Str x) const {\n  return rust::String(std::string(x));\n}\n\nrust::String cOverloadedFunction(int x) {\n  return rust::String(std::to_string(x));\n}\n\nrust::String cOverloadedFunction(rust::Str x) {\n  return rust::String(std::string(x));\n}\n\nsize_t C::c_static_method() { return 2026; }\n\nvoid c_take_trivial_ptr(std::unique_ptr<D> d) {\n  if (d->d == 30) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_trivial_ref(const D &d) {\n  if (d.d == 30) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_trivial_mut_ref(D &d) { (void)d; }\n\nvoid c_take_trivial_pin_ref(const D &d) { (void)d; }\n\nvoid c_take_trivial_pin_mut_ref(D &d) { (void)d; }\n\nvoid D::c_take_trivial_ref_method() const {\n  if (d == 30) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid D::c_take_trivial_mut_ref_method() {\n  if (d == 30) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_trivial(D d) {\n  if (d.d == 30) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_trivial_ns_ptr(std::unique_ptr<::G::G> g) {\n  if (g->g == 30) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_trivial_ns_ref(const ::G::G &g) {\n  if (g.g == 30) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_trivial_ns(::G::G g) {\n  if (g.g == 30) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_opaque_ptr(std::unique_ptr<E> e) {\n  if (e->e == 40) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_opaque_ns_ptr(std::unique_ptr<::F::F> f) {\n  if (f->f == 40) {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_opaque_ref(const E &e) {\n  if (e.e == 40 && e.e_str == \"hello\") {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid E::c_take_opaque_ref_method() const {\n  if (e == 40 && e_str == \"hello\") {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid E::c_take_opaque_mut_ref_method() {\n  if (e == 40 && e_str == \"hello\") {\n    cxx_test_suite_set_correct();\n  }\n}\n\nvoid c_take_opaque_ns_ref(const ::F::F &f) {\n  if (f.f == 40 && f.f_str == \"hello\") {\n    cxx_test_suite_set_correct();\n  }\n}\n\nstd::unique_ptr<D> c_return_trivial_ptr() {\n  auto d = std::unique_ptr<D>(new D());\n  d->d = 30;\n  return d;\n}\n\nD c_return_trivial() {\n  D d;\n  d.d = 30;\n  return d;\n}\n\nstd::unique_ptr<::G::G> c_return_trivial_ns_ptr() {\n  auto g = std::unique_ptr<::G::G>(new ::G::G());\n  g->g = 30;\n  return g;\n}\n\n::G::G c_return_trivial_ns() {\n  ::G::G g;\n  g.g = 30;\n  return g;\n}\n\nstd::unique_ptr<E> c_return_opaque_ptr() {\n  auto e = std::unique_ptr<E>(new E());\n  e->e = 40;\n  e->e_str = std::string(\"hello\");\n  return e;\n}\n\nE &c_return_opaque_mut_pin(E &e) { return e; }\n\nstd::unique_ptr<::F::F> c_return_ns_opaque_ptr() {\n  auto f = std::unique_ptr<::F::F>(new ::F::F());\n  f->f = 40;\n  f->f_str = std::string(\"hello\");\n  return f;\n}\n\nvoid R::c_member_function_on_rust_type() const noexcept {}\n\nextern \"C\" const char *cxx_run_test() noexcept {\n#define STRINGIFY(x) #x\n#define TOSTRING(x) STRINGIFY(x)\n#define ASSERT(x)                                                              \\\n  do {                                                                         \\\n    if (!(x)) {                                                                \\\n      return \"Assertion failed: `\" #x \"`, \" __FILE__ \":\" TOSTRING(__LINE__);   \\\n    }                                                                          \\\n  } while (false)\n\n  ASSERT(rust::size_of<R>() == sizeof(size_t));\n  ASSERT(rust::align_of<R>() == alignof(size_t));\n  ASSERT(rust::size_of<size_t>() == sizeof(size_t));\n  ASSERT(rust::align_of<size_t>() == alignof(size_t));\n\n  ASSERT(r_return_primitive() == 2020);\n  ASSERT(r_return_shared().z == 2020);\n  ASSERT(cxx_test_suite_r_is_correct(&*r_return_box()));\n  ASSERT(r_return_unique_ptr()->get() == 2020);\n  ASSERT(r_return_shared_ptr()->get() == 2020);\n  ASSERT(r_return_ref(Shared{2020}) == 2020);\n  ASSERT(std::string(r_return_str(Shared{2020})) == \"2020\");\n  ASSERT(std::string(r_return_rust_string()) == \"2020\");\n  ASSERT(*r_return_unique_ptr_string() == \"2020\");\n  ASSERT(r_return_identity(2020) == 2020);\n  ASSERT(r_return_sum(2020, 1) == 2021);\n  ASSERT(r_return_enum(0) == Enum::AVal);\n  ASSERT(r_return_enum(1) == Enum::BVal);\n  ASSERT(r_return_enum(2021) == Enum::CVal);\n  ASSERT(Shared::r_static_method_on_shared() == 2023);\n  ASSERT(R::r_static_method() == 2024);\n  ASSERT(r_return_rust_vec_box()[0]->get() == 2020);\n  ASSERT(r_return_rust_vec_box_other_module_type().size() == 1);\n\n  r_take_primitive(2020);\n  r_take_shared(Shared{2020});\n  r_take_unique_ptr(std::unique_ptr<C>(new C{2020}));\n  r_take_shared_ptr(std::shared_ptr<C>(new C{2020}));\n  r_take_ref_c(C{2020});\n  r_take_str(rust::Str(\"2020\"));\n  r_take_slice_char(rust::Slice<const char>(SLICE_DATA, sizeof(SLICE_DATA)));\n  r_take_rust_string(rust::String(\"2020\"));\n  r_take_unique_ptr_string(\n      std::unique_ptr<std::string>(new std::string(\"2020\")));\n  r_take_ref_vector(std::vector<uint8_t>{20, 2, 0});\n  std::vector<uint64_t> empty_vector;\n  r_take_ref_empty_vector(empty_vector);\n  empty_vector.reserve(10);\n  r_take_ref_empty_vector(empty_vector);\n  r_take_enum(Enum::AVal);\n\n  ASSERT(r_try_return_primitive() == 2020);\n  try {\n    r_fail_return_primitive();\n    ASSERT(false);\n  } catch (const rust::Error &e) {\n    ASSERT(std::strcmp(e.what(), \"rust error\") == 0);\n  }\n\n  auto r = r_return_box();\n  ASSERT(r->get() == 2020);\n  ASSERT(r->set(2021) == 2021);\n  ASSERT(r->get() == 2021);\n\n  using std::swap;\n  auto r2 = r_return_box();\n  swap(r, r2);\n  ASSERT(r->get() == 2020);\n  ASSERT(r2->get() == 2021);\n\n  ASSERT(std::string(Shared{0}.r_method_on_shared()) == \"2020\");\n\n  ASSERT(std::string(rAliasedFunction(2020)) == \"2020\");\n\n  ASSERT(Shared{1} == Shared{1});\n  ASSERT(Shared{1} != Shared{2});\n\n  rust::String first = \"first\", second = \"second\", sec = \"sec\";\n  bool (rust::String::*cmp)(const rust::String &) const;\n  bool first_first, first_second, sec_second, second_sec;\n  for (auto test : {\n           std::tuple<decltype(cmp), bool, bool, bool, bool>{\n               &rust::String::operator==, true, false, false, false},\n           {&rust::String::operator!=, false, true, true, true},\n           {&rust::String::operator<, false, true, true, false},\n           {&rust::String::operator<=, true, true, true, false},\n           {&rust::String::operator>, false, false, false, true},\n           {&rust::String::operator>=, true, false, false, true},\n       }) {\n    std::tie(cmp, first_first, first_second, sec_second, second_sec) = test;\n    ASSERT((first.*cmp)(first) == first_first);\n    ASSERT((first.*cmp)(second) == first_second);\n    ASSERT((sec.*cmp)(second) == sec_second);\n    ASSERT((second.*cmp)(sec) == second_sec);\n  }\n\n  rust::String cstring = \"test\";\n  ASSERT(cstring.length() == 4);\n  ASSERT(strncmp(cstring.data(), \"test\", 4) == 0);\n  ASSERT(strncmp(cstring.c_str(), \"test\", 5) == 0);\n  ASSERT(cstring.length() == 4);\n\n  rust::String other_cstring = \"foo\";\n  swap(cstring, other_cstring);\n  ASSERT(cstring == \"foo\");\n  ASSERT(other_cstring == \"test\");\n\n  ASSERT(cstring.capacity() == 3);\n  cstring.reserve(2);\n  ASSERT(cstring.capacity() == 3);\n  cstring.reserve(5);\n  ASSERT(cstring.capacity() >= 5);\n\n  {\n    rust::Str out_param;\n    r_return_str_via_out_param(Shared{2020}, out_param);\n    ASSERT(out_param == \"2020\");\n\n#if __cplusplus >= 201703L\n    std::string_view out_param_as_string_view{out_param};\n    ASSERT(out_param_as_string_view == \"2020\");\n#endif\n  }\n\n  rust::Str cstr = \"test\";\n  rust::Str other_cstr = \"foo\";\n  swap(cstr, other_cstr);\n  ASSERT(cstr == \"foo\");\n  ASSERT(other_cstr == \"test\");\n\n  // Auto because u8\"...\" is `const char*` before C++20, and `const char8_t*` since.\n  const auto *utf8_literal = u8\"Test string\";\n  const char16_t *utf16_literal = u\"Test string\";\n  rust::String utf8_rstring = utf8_literal;\n  rust::String utf16_rstring = utf16_literal;\n  ASSERT(utf8_rstring == utf16_rstring);\n\n  const char *bad_utf8_literal = \"test\\x80\";\n  const char16_t *bad_utf16_literal = u\"test\\xDD1E\";\n  rust::String bad_utf8_rstring = rust::String::lossy(bad_utf8_literal);\n  rust::String bad_utf16_rstring = rust::String::lossy(bad_utf16_literal);\n  ASSERT(bad_utf8_rstring == bad_utf16_rstring);\n\n  // Test Slice<T> explicit constructor from container\n  {\n    std::vector<int> cpp_vec{1, 2, 3};\n    rust::Slice<int> slice_of_cpp_vec(cpp_vec);\n    ASSERT(slice_of_cpp_vec.data() == cpp_vec.data());\n    ASSERT(slice_of_cpp_vec.size() == cpp_vec.size());\n    ASSERT(slice_of_cpp_vec[0] == 1);\n  }\n\n  // Test Slice<T> template deduction guides\n#ifdef __cpp_deduction_guides\n  {\n    // std::array<T> -> Slice<T>\n    std::array<int, 3> cpp_array{1, 2, 3};\n    auto auto_slice_of_cpp_array = rust::Slice(cpp_array);\n    static_assert(\n        std::is_same_v<decltype(auto_slice_of_cpp_array), rust::Slice<int>>);\n  }\n  {\n    // const std::array<T> -> Slice<const T>\n    const std::array<int, 3> cpp_array{1, 2, 3};\n    auto auto_slice_of_cpp_array = rust::Slice(cpp_array);\n    static_assert(std::is_same_v<decltype(auto_slice_of_cpp_array),\n                                 rust::Slice<const int>>);\n  }\n  {\n    // std::array<const T> -> Slice<const T>\n    std::array<const int, 3> cpp_array{1, 2, 3};\n    auto auto_slice_of_cpp_array = rust::Slice(cpp_array);\n    static_assert(std::is_same_v<decltype(auto_slice_of_cpp_array),\n                                 rust::Slice<const int>>);\n  }\n  {\n    // std::vector<T> -> Slice<T>\n    std::vector<int> cpp_vec{1, 2, 3};\n    auto auto_slice_of_cpp_vec = rust::Slice(cpp_vec);\n    static_assert(\n        std::is_same_v<decltype(auto_slice_of_cpp_vec), rust::Slice<int>>);\n  }\n  {\n    // const std::vector<T> -> Slice<const T>\n    const std::vector<int> cpp_vec{1, 2, 3};\n    auto auto_slice_of_cpp_vec = rust::Slice(cpp_vec);\n    static_assert(std::is_same_v<decltype(auto_slice_of_cpp_vec),\n                                 rust::Slice<const int>>);\n  }\n#ifdef __cpp_lib_span\n  {\n    // std::span<T> -> Slice<T>\n    std::array<int, 3> cpp_array{1, 2, 3};\n    std::span<int> cpp_span(cpp_array);\n    auto auto_slice_of_cpp_span = rust::Slice(cpp_span);\n    static_assert(\n        std::is_same_v<decltype(auto_slice_of_cpp_span), rust::Slice<int>>);\n  }\n  {\n    // std::span<const T> -> Slice<const T>\n    const std::array<int, 3> cpp_array{1, 2, 3};\n    std::span<const int> cpp_span(cpp_array);\n    auto auto_slice_of_cpp_span = rust::Slice(cpp_span);\n    static_assert(std::is_same_v<decltype(auto_slice_of_cpp_span),\n                                 rust::Slice<const int>>);\n  }\n#endif // __cpp_lib_span\n#endif // __cpp_deduction_guides\n\n  rust::Vec<int> vec1{1, 2};\n  rust::Vec<int> vec2{3, 4};\n  swap(vec1, vec2);\n  ASSERT(vec1[0] == 3 && vec1[1] == 4);\n  ASSERT(vec2[0] == 1 && vec2[1] == 2);\n\n  // Test Vec<usize> and Vec<isize>. These are weird because on Linux and\n  // Windows size_t is exactly the same C++ type as one of the sized integer\n  // types (typically uint64_t, both of which are defined as unsigned long),\n  // while on macOS it is a distinct type.\n  // https://github.com/dtolnay/cxx/issues/705\n  (void)rust::Vec<size_t>();\n  (void)rust::Vec<rust::isize>();\n\n  cxx_test_suite_set_correct();\n  return nullptr;\n}\n\n} // namespace tests\n\nnamespace other {\nvoid ns_c_take_trivial(::tests::D d) {\n  if (d.d == 30) {\n    cxx_test_suite_set_correct();\n  }\n}\n\n::tests::D ns_c_return_trivial() {\n  ::tests::D d;\n  d.d = 30;\n  return d;\n}\n\nvoid ns_c_take_ns_shared(::A::AShared shared) {\n  if (shared.type == 2020) {\n    cxx_test_suite_set_correct();\n  }\n}\n} // namespace other\n\nnamespace I {\nuint32_t I::get() const { return a; }\n\nstd::unique_ptr<I> ns_c_return_unique_ptr_ns() {\n  return std::unique_ptr<I>(new I());\n}\n} // namespace I\n\n// Instantiate any remaining class member functions not already covered above.\n// This is an easy way to at least typecheck anything missed by unit tests.\n// https://en.cppreference.com/w/cpp/language/class_template#Explicit_instantiation\n// > When an explicit instantiation names a class template specialization, it\n// > serves as an explicit instantiation of the same kind (declaration or\n// > definition) of each of its non-inherited non-template members that has not\n// > been previously explicitly specialized in the translation unit.\n#if defined(CXX_TEST_INSTANTIATIONS)\ntemplate class rust::Box<tests::Shared>;\ntemplate class rust::Slice<const char>;\ntemplate class rust::Slice<const uint8_t>;\ntemplate class rust::Slice<uint8_t>;\ntemplate class rust::Slice<const tests::Shared>;\ntemplate class rust::Slice<tests::Shared>;\ntemplate class rust::Slice<const tests::R>;\ntemplate class rust::Slice<tests::R>;\ntemplate class rust::Vec<uint8_t>;\ntemplate class rust::Vec<rust::String>;\ntemplate class rust::Vec<tests::Shared>;\ntemplate class rust::Fn<size_t(rust::String)>;\n#endif\n"
  },
  {
    "path": "tests/ffi/tests.h",
    "content": "#pragma once\n#include \"rust/cxx.h\"\n#include <memory>\n#include <string>\n\nnamespace A {\nstruct AShared;\nenum class AEnum : uint16_t;\nnamespace B {\nstruct ABShared;\nenum class ABEnum : int32_t;\n} // namespace B\n} // namespace A\n\nnamespace F {\nstruct F {\n  uint64_t f;\n  std::string f_str;\n};\n} // namespace F\n\nnamespace G {\nstruct G {\n  uint64_t g;\n};\n} // namespace G\n\nnamespace H {\nclass H {\npublic:\n  std::string h;\n};\n} // namespace H\n\nnamespace tests {\n\nclass Undefined;\n\nclass Private {\nprivate:\n  ~Private();\n};\n\nstruct Unmovable {\n  Unmovable(Unmovable &&) = delete;\n};\n\nusing Array = int[];\n\nstruct R;\nstruct Shared;\nstruct SharedString;\nenum class Enum : uint16_t;\n\nclass C {\npublic:\n  C(size_t n);\n  size_t get() const;\n  size_t set(size_t n);\n  size_t get2() const;\n  const size_t &getRef() const;\n  size_t &getMut();\n  size_t set_succeed(size_t n);\n  size_t get_fail();\n  const std::vector<uint8_t> &get_v() const;\n  std::vector<uint8_t> &get_v();\n  const std::vector<uint8_t> &c_lifetime_elision_member_fn() const;\n  rust::String cOverloadedMethod(int32_t x) const;\n  rust::String cOverloadedMethod(rust::Str x) const;\n  static size_t c_static_method();\n  // Unlike the other contents of this class, the C++ definition of this member\n  // function is generated by CXX and forwards to a Rust method implementation\n  // in an `impl ffi::C` block.\n  size_t &r_method_on_c_get_mut() noexcept;\n\nprivate:\n  size_t n;\n  std::vector<uint8_t> v;\n};\n\nstruct D {\n  uint64_t d;\n  void c_take_trivial_ref_method() const;\n  void c_take_trivial_mut_ref_method();\n};\n\nstruct E {\n  uint64_t e;\n  std::string e_str;\n  void c_take_opaque_ref_method() const;\n  void c_take_opaque_mut_ref_method();\n};\n\nenum COwnedEnum {\n  CVAL1,\n  CVAL2,\n};\n\nstruct Borrow {\n  Borrow(const std::string &s);\n  void const_member() const;\n  void nonconst_member();\n  const std::string &s;\n};\n\ntypedef char Buffer[12];\n\nsize_t c_return_primitive();\nShared c_return_shared();\n::A::AShared c_return_ns_shared();\n::A::B::ABShared c_return_nested_ns_shared();\nrust::Box<R> c_return_box();\nstd::unique_ptr<C> c_return_unique_ptr();\nstd::shared_ptr<C> c_return_shared_ptr();\nstd::unique_ptr<::H::H> c_return_ns_unique_ptr();\nconst size_t &c_return_ref(const Shared &shared);\nconst size_t &c_return_ns_ref(const ::A::AShared &shared);\nconst size_t &c_return_nested_ns_ref(const ::A::B::ABShared &shared);\nsize_t &c_return_mut(Shared &shared);\nrust::Str c_return_str(const Shared &shared);\nrust::Slice<const char> c_return_slice_char(const Shared &shared);\nrust::Slice<uint8_t> c_return_mutsliceu8(rust::Slice<uint8_t> slice);\nrust::String c_return_rust_string();\nrust::String c_return_rust_string_lossy();\nstd::unique_ptr<std::string> c_return_unique_ptr_string();\nstd::unique_ptr<std::vector<uint8_t>> c_return_unique_ptr_vector_u8();\nstd::unique_ptr<std::vector<double>> c_return_unique_ptr_vector_f64();\nstd::unique_ptr<std::vector<std::string>> c_return_unique_ptr_vector_string();\nstd::unique_ptr<std::vector<Shared>> c_return_unique_ptr_vector_shared();\nstd::unique_ptr<std::vector<C>> c_return_unique_ptr_vector_opaque();\nconst std::vector<uint8_t> &c_return_ref_vector(const C &c);\nstd::vector<uint8_t> &c_return_mut_vector(C &c);\nrust::Vec<uint8_t> c_return_rust_vec_u8();\nconst rust::Vec<uint8_t> &c_return_ref_rust_vec(const C &c);\nrust::Vec<uint8_t> &c_return_mut_rust_vec(C &c);\nrust::Vec<rust::String> c_return_rust_vec_string();\nrust::Vec<bool> c_return_rust_vec_bool();\nsize_t c_return_identity(size_t n);\nsize_t c_return_sum(size_t n1, size_t n2);\nEnum c_return_enum(uint16_t n);\n::A::AEnum c_return_ns_enum(uint16_t n);\n::A::B::ABEnum c_return_nested_ns_enum(uint16_t n);\nstd::unique_ptr<Borrow> c_return_borrow(const std::string &s);\nconst C *c_return_const_ptr(size_t n);\nC *c_return_mut_ptr(size_t n);\n\nvoid c_take_primitive(size_t n);\nvoid c_take_shared(Shared shared);\nvoid c_take_ns_shared(::A::AShared shared);\nvoid c_take_nested_ns_shared(::A::B::ABShared shared);\nvoid c_take_box(rust::Box<R> r);\nvoid c_take_unique_ptr(std::unique_ptr<C> c);\nvoid c_take_ref_r(const R &r);\nvoid c_take_ref_c(const C &c);\nvoid c_take_ref_ns_c(const ::H::H &h);\nvoid c_take_str(rust::Str s);\nvoid c_take_slice_char(rust::Slice<const char> s);\nvoid c_take_slice_shared(rust::Slice<const Shared> s);\nvoid c_take_slice_shared_sort(rust::Slice<Shared> s);\nvoid c_take_slice_r(rust::Slice<const R> s);\nvoid c_take_slice_r_sort(rust::Slice<R> s);\nvoid c_take_rust_string(rust::String s);\nvoid c_take_unique_ptr_string(std::unique_ptr<std::string> s);\nvoid c_take_unique_ptr_vector_u8(std::unique_ptr<std::vector<uint8_t>> v);\nvoid c_take_unique_ptr_vector_f64(std::unique_ptr<std::vector<double>> v);\nvoid c_take_unique_ptr_vector_string(\n    std::unique_ptr<std::vector<std::string>> v);\nvoid c_take_unique_ptr_vector_shared(std::unique_ptr<std::vector<Shared>> v);\nvoid c_take_ref_vector(const std::vector<uint8_t> &v);\nvoid c_take_rust_vec(rust::Vec<uint8_t> v);\nvoid c_take_rust_vec_index(rust::Vec<uint8_t> v);\nvoid c_take_rust_vec_shared(rust::Vec<Shared> v);\nvoid c_take_rust_vec_ns_shared(rust::Vec<::A::AShared> v);\nvoid c_take_rust_vec_nested_ns_shared(rust::Vec<::A::B::ABShared> v);\nvoid c_take_rust_vec_string(rust::Vec<rust::String> v);\nvoid c_take_rust_vec_shared_index(rust::Vec<Shared> v);\nvoid c_take_rust_vec_shared_push(rust::Vec<Shared> v);\nvoid c_take_rust_vec_shared_truncate(rust::Vec<Shared> v);\nvoid c_take_rust_vec_shared_clear(rust::Vec<Shared> v);\nvoid c_take_rust_vec_shared_forward_iterator(rust::Vec<Shared> v);\nvoid c_take_rust_vec_shared_sort(rust::Vec<Shared> v);\nvoid c_take_ref_rust_vec(const rust::Vec<uint8_t> &v);\nvoid c_take_ref_rust_vec_string(const rust::Vec<rust::String> &v);\nvoid c_take_ref_rust_vec_index(const rust::Vec<uint8_t> &v);\nvoid c_take_ref_rust_vec_copy(const rust::Vec<uint8_t> &v);\nconst SharedString &c_take_ref_shared_string(const SharedString &s);\nvoid c_take_callback(rust::Fn<size_t(rust::String)> callback);\nvoid c_take_callback_ref(rust::Fn<void(const rust::String &)> callback);\nvoid c_take_callback_mut(rust::Fn<void(rust::String &)> callback);\nvoid c_take_enum(Enum e);\nvoid c_take_ns_enum(::A::AEnum e);\nvoid c_take_nested_ns_enum(::A::B::ABEnum e);\nsize_t c_take_const_ptr(const C *c);\nsize_t c_take_mut_ptr(C *c);\n\nvoid c_try_return_void();\nsize_t c_try_return_primitive();\nsize_t c_fail_return_primitive();\nrust::Box<R> c_try_return_box();\nconst rust::String &c_try_return_ref(const rust::String &);\nrust::Str c_try_return_str(rust::Str);\nrust::Slice<const uint8_t> c_try_return_sliceu8(rust::Slice<const uint8_t>);\nrust::Slice<uint8_t> c_try_return_mutsliceu8(rust::Slice<uint8_t>);\nrust::String c_try_return_rust_string();\nstd::unique_ptr<std::string> c_try_return_unique_ptr_string();\nrust::Vec<uint8_t> c_try_return_rust_vec();\nrust::Vec<rust::String> c_try_return_rust_vec_string();\nconst rust::Vec<uint8_t> &c_try_return_ref_rust_vec(const C &c);\n\nsize_t c_get_use_count(const std::weak_ptr<C> &weak) noexcept;\n\nvoid c_take_trivial_ptr(std::unique_ptr<D> d);\nvoid c_take_trivial_ref(const D &d);\nvoid c_take_trivial_mut_ref(D &d);\nvoid c_take_trivial_pin_ref(const D &d);\nvoid c_take_trivial_pin_mut_ref(D &d);\nvoid c_take_trivial(D d);\n\nvoid c_take_trivial_ns_ptr(std::unique_ptr<::G::G> g);\nvoid c_take_trivial_ns_ref(const ::G::G &g);\nvoid c_take_trivial_ns(::G::G g);\nvoid c_take_opaque_ptr(std::unique_ptr<E> e);\nvoid c_take_opaque_ns_ptr(std::unique_ptr<::F::F> f);\nvoid c_take_opaque_ref(const E &e);\nvoid c_take_opaque_ns_ref(const ::F::F &f);\nstd::unique_ptr<D> c_return_trivial_ptr();\nD c_return_trivial();\nstd::unique_ptr<::G::G> c_return_trivial_ns_ptr();\n::G::G c_return_trivial_ns();\nstd::unique_ptr<E> c_return_opaque_ptr();\nE &c_return_opaque_mut_pin(E &e);\nstd::unique_ptr<::F::F> c_return_ns_opaque_ptr();\n\nconst std::vector<uint8_t> &c_lifetime_elision_fn(const C &c);\nrust::String cOverloadedFunction(int32_t x);\nrust::String cOverloadedFunction(rust::Str x);\n\n} // namespace tests\n\nnamespace other {\nvoid ns_c_take_trivial(::tests::D d);\n::tests::D ns_c_return_trivial();\nvoid ns_c_take_ns_shared(::A::AShared shared);\n} // namespace other\n\nnamespace I {\nclass I {\nprivate:\n  uint32_t a;\n\npublic:\n  I() : a(1000) {}\n  uint32_t get() const;\n};\n\nstd::unique_ptr<I> ns_c_return_unique_ptr_ns();\n} // namespace I\n"
  },
  {
    "path": "tests/test.rs",
    "content": "#![allow(\n    clippy::assertions_on_constants,\n    clippy::cast_possible_truncation,\n    clippy::cast_possible_wrap,\n    clippy::float_cmp,\n    clippy::needless_pass_by_value,\n    clippy::unit_cmp\n)]\n\nuse cxx::{CxxVector, SharedPtr, UniquePtr};\nuse cxx_test_suite::module::ffi2;\nuse cxx_test_suite::{cast, ffi, R};\nuse std::cell::Cell;\nuse std::ffi::CStr;\nuse std::panic::{self, RefUnwindSafe, UnwindSafe};\nuse std::ptr;\n\nthread_local! {\n    static CORRECT: Cell<bool> = const { Cell::new(false) };\n}\n\n#[no_mangle]\nextern \"C\" fn cxx_test_suite_set_correct() {\n    CORRECT.with(|correct| correct.set(true));\n}\n\nmacro_rules! check {\n    ($run:expr) => {{\n        CORRECT.with(|correct| correct.set(false));\n        $run;\n        assert!(CORRECT.with(Cell::get), \"{}\", stringify!($run));\n    }};\n}\n\n#[test]\nfn test_c_return() {\n    let shared = ffi::Shared { z: 2020 };\n    let ns_shared = ffi::AShared { z: 2020 };\n    let nested_ns_shared = ffi::ABShared { z: 2020 };\n\n    assert_eq!(2020, ffi::c_return_primitive());\n    assert_eq!(2020, ffi::c_return_shared().z);\n    assert_eq!(2020, ffi::c_return_box().0);\n    ffi::c_return_unique_ptr();\n    ffi2::c_return_ns_unique_ptr();\n    assert_eq!(2020, *ffi::c_return_ref(&shared));\n    assert_eq!(2020, *ffi::c_return_ns_ref(&ns_shared));\n    assert_eq!(2020, *ffi::c_return_nested_ns_ref(&nested_ns_shared));\n    assert_eq!(\"2020\", ffi::c_return_str(&shared));\n    assert_eq!(\n        b\"2020\\0\",\n        cast::c_char_to_unsigned(ffi::c_return_slice_char(&shared)),\n    );\n    assert_eq!(\"2020\", ffi::c_return_rust_string());\n    assert_eq!(\"Hello \\u{fffd}World\", ffi::c_return_rust_string_lossy());\n    assert_eq!(\"2020\", ffi::c_return_unique_ptr_string().to_str().unwrap());\n    assert_eq!(c\"2020\", ffi::c_return_unique_ptr_string().as_c_str());\n    assert_eq!(4, ffi::c_return_unique_ptr_vector_u8().len());\n    assert!(4 <= ffi::c_return_unique_ptr_vector_u8().capacity());\n    assert_eq!(\n        200_u8,\n        ffi::c_return_unique_ptr_vector_u8().into_iter().sum(),\n    );\n    assert_eq!(\n        200.5_f64,\n        ffi::c_return_unique_ptr_vector_f64().into_iter().sum(),\n    );\n    assert_eq!(2, ffi::c_return_unique_ptr_vector_shared().len());\n    assert!(2 <= ffi::c_return_unique_ptr_vector_shared().capacity());\n    assert_eq!(\n        2021_usize,\n        ffi::c_return_unique_ptr_vector_shared()\n            .into_iter()\n            .map(|o| o.z)\n            .sum(),\n    );\n    assert_eq!(b\"\\x02\\0\\x02\\0\"[..], ffi::c_return_rust_vec_u8());\n    assert_eq!([true, true, false][..], ffi::c_return_rust_vec_bool());\n    assert_eq!(2020, ffi::c_return_identity(2020));\n    assert_eq!(2021, ffi::c_return_sum(2020, 1));\n    match ffi::c_return_enum(0) {\n        enm @ ffi::Enum::AVal => assert_eq!(0, enm.repr),\n        _ => assert!(false),\n    }\n    match ffi::c_return_enum(1) {\n        enm @ ffi::Enum::BVal => assert_eq!(2020, enm.repr),\n        _ => assert!(false),\n    }\n    match ffi::c_return_enum(2021) {\n        enm @ ffi::Enum::LastVal => assert_eq!(2021, enm.repr),\n        _ => assert!(false),\n    }\n    match ffi::c_return_ns_enum(0) {\n        enm @ ffi::AEnum::AAVal => assert_eq!(0, enm.repr),\n        _ => assert!(false),\n    }\n    match ffi::c_return_nested_ns_enum(2021) {\n        enm @ ffi::ABEnum::ABCVal => assert_eq!(i32::MIN, enm.repr),\n        _ => assert!(false),\n    }\n}\n\n#[test]\nfn test_c_try_return() {\n    assert_eq!((), ffi::c_try_return_void().unwrap());\n    assert_eq!(2020, ffi::c_try_return_primitive().unwrap());\n    assert_eq!(\n        \"logic error\",\n        ffi::c_fail_return_primitive().unwrap_err().what(),\n    );\n    assert_eq!(2020, ffi::c_try_return_box().unwrap().0);\n    assert_eq!(\"2020\", *ffi::c_try_return_ref(&\"2020\".to_owned()).unwrap());\n    assert_eq!(\"2020\", ffi::c_try_return_str(\"2020\").unwrap());\n    assert_eq!(b\"2020\", ffi::c_try_return_sliceu8(b\"2020\").unwrap());\n    assert_eq!(\"2020\", ffi::c_try_return_rust_string().unwrap());\n    assert_eq!(\"2020\", &*ffi::c_try_return_unique_ptr_string().unwrap());\n}\n\n#[test]\nfn test_c_take() {\n    let unique_ptr = ffi::c_return_unique_ptr();\n    let unique_ptr_ns = ffi2::c_return_ns_unique_ptr();\n\n    check!(ffi::c_take_primitive(2020));\n    check!(ffi::c_take_shared(ffi::Shared { z: 2020 }));\n    check!(ffi::c_take_ns_shared(ffi::AShared { z: 2020 }));\n    check!(ffi::ns_c_take_ns_shared(ffi::AShared { z: 2020 }));\n    check!(ffi::c_take_nested_ns_shared(ffi::ABShared { z: 2020 }));\n    check!(ffi::c_take_box(Box::new(R(2020))));\n    check!(ffi::c_take_ref_c(&unique_ptr));\n    check!(ffi2::c_take_ref_ns_c(&unique_ptr_ns));\n    check!(cxx_test_suite::module::ffi::c_take_unique_ptr(unique_ptr));\n    check!(ffi::c_take_str(\"2020\"));\n    check!(ffi::c_take_slice_char(cast::unsigned_to_c_char(b\"2020\")));\n    check!(ffi::c_take_slice_shared(&[\n        ffi::Shared { z: 2020 },\n        ffi::Shared { z: 2021 },\n    ]));\n    let shared_sort_slice = &mut [\n        ffi::Shared { z: 2 },\n        ffi::Shared { z: 0 },\n        ffi::Shared { z: 7 },\n        ffi::Shared { z: 4 },\n    ];\n    check!(ffi::c_take_slice_shared_sort(shared_sort_slice));\n    assert_eq!(shared_sort_slice[0].z, 0);\n    assert_eq!(shared_sort_slice[1].z, 2);\n    assert_eq!(shared_sort_slice[2].z, 4);\n    assert_eq!(shared_sort_slice[3].z, 7);\n    let r_sort_slice = &mut [R(2020), R(2050), R(2021)];\n    check!(ffi::c_take_slice_r(r_sort_slice));\n    check!(ffi::c_take_slice_r_sort(r_sort_slice));\n    assert_eq!(r_sort_slice[0].0, 2020);\n    assert_eq!(r_sort_slice[1].0, 2021);\n    assert_eq!(r_sort_slice[2].0, 2050);\n    check!(ffi::c_take_rust_string(\"2020\".to_owned()));\n    check!(ffi::c_take_unique_ptr_string(\n        ffi::c_return_unique_ptr_string()\n    ));\n    let mut vector = ffi::c_return_unique_ptr_vector_u8();\n    assert_eq!(vector.pin_mut().pop(), Some(9));\n    check!(ffi::c_take_unique_ptr_vector_u8(vector));\n    let mut vector = ffi::c_return_unique_ptr_vector_f64();\n    vector.pin_mut().extend(Some(9.0));\n    assert!(vector.pin_mut().capacity() >= 1);\n    vector.pin_mut().reserve(100);\n    assert!(vector.pin_mut().capacity() >= 101);\n    check!(ffi::c_take_unique_ptr_vector_f64(vector));\n    let mut vector = ffi::c_return_unique_ptr_vector_shared();\n    vector.pin_mut().push(ffi::Shared { z: 9 });\n    check!(ffi::c_take_unique_ptr_vector_shared(vector));\n    check!(ffi::c_take_ref_vector(&ffi::c_return_unique_ptr_vector_u8()));\n    let test_vec = [86_u8, 75_u8, 30_u8, 9_u8].to_vec();\n    check!(ffi::c_take_rust_vec(test_vec.clone()));\n    check!(ffi::c_take_rust_vec_index(test_vec.clone()));\n    let shared_test_vec = vec![ffi::Shared { z: 1010 }, ffi::Shared { z: 1011 }];\n    check!(ffi::c_take_rust_vec_shared(shared_test_vec.clone()));\n    check!(ffi::c_take_rust_vec_shared_index(shared_test_vec.clone()));\n    check!(ffi::c_take_rust_vec_shared_push(shared_test_vec.clone()));\n    check!(ffi::c_take_rust_vec_shared_truncate(\n        shared_test_vec.clone()\n    ));\n    check!(ffi::c_take_rust_vec_shared_clear(shared_test_vec.clone()));\n    check!(ffi::c_take_rust_vec_shared_forward_iterator(\n        shared_test_vec,\n    ));\n    let shared_sort_vec = vec![\n        ffi::Shared { z: 2 },\n        ffi::Shared { z: 0 },\n        ffi::Shared { z: 7 },\n        ffi::Shared { z: 4 },\n    ];\n    check!(ffi::c_take_rust_vec_shared_sort(shared_sort_vec));\n    check!(ffi::c_take_ref_rust_vec(&test_vec));\n    check!(ffi::c_take_ref_rust_vec_index(&test_vec));\n    check!(ffi::c_take_ref_rust_vec_copy(&test_vec));\n    check!(ffi::c_take_ref_shared_string(&ffi::SharedString {\n        msg: \"2020\".to_owned()\n    }));\n    let ns_shared_test_vec = vec![ffi::AShared { z: 1010 }, ffi::AShared { z: 1011 }];\n    check!(ffi::c_take_rust_vec_ns_shared(ns_shared_test_vec));\n    let nested_ns_shared_test_vec = vec![ffi::ABShared { z: 1010 }, ffi::ABShared { z: 1011 }];\n    check!(ffi::c_take_rust_vec_nested_ns_shared(\n        nested_ns_shared_test_vec\n    ));\n\n    check!(ffi::c_take_enum(ffi::Enum::AVal));\n    check!(ffi::c_take_ns_enum(ffi::AEnum::AAVal));\n    check!(ffi::c_take_nested_ns_enum(ffi::ABEnum::ABAVal));\n}\n\n#[test]\nfn test_c_callback() {\n    fn callback(s: String) -> usize {\n        if s == \"2020\" {\n            cxx_test_suite_set_correct();\n        }\n        0\n    }\n\n    #[allow(clippy::ptr_arg)]\n    fn callback_ref(s: &String) {\n        if s == \"2020\" {\n            cxx_test_suite_set_correct();\n        }\n    }\n\n    fn callback_mut(s: &mut String) {\n        if s == \"2020\" {\n            cxx_test_suite_set_correct();\n        }\n    }\n\n    check!(ffi::c_take_callback(callback));\n    check!(ffi::c_take_callback_ref(callback_ref));\n    check!(ffi::c_take_callback_ref_lifetime(callback_ref));\n    check!(ffi::c_take_callback_mut(callback_mut));\n}\n\n#[test]\nfn test_c_call_r() {\n    fn cxx_run_test() {\n        extern \"C\" {\n            fn cxx_run_test() -> *const i8;\n        }\n        let failure = unsafe { cxx_run_test() };\n        if !failure.is_null() {\n            let msg = unsafe { CStr::from_ptr(failure.cast::<std::os::raw::c_char>().cast_mut()) };\n            eprintln!(\"{}\", msg.to_string_lossy());\n        }\n    }\n    check!(cxx_run_test());\n}\n\n#[test]\nfn test_c_method_calls() {\n    let mut unique_ptr = ffi::c_return_unique_ptr();\n\n    let old_value = unique_ptr.get();\n    assert_eq!(2020, old_value);\n    assert_eq!(2021, unique_ptr.pin_mut().set(2021));\n    assert_eq!(2021, unique_ptr.get());\n    assert_eq!(2021, unique_ptr.get2());\n    assert_eq!(2021, *unique_ptr.getRef());\n    assert_eq!(2021, unsafe { &mut *unique_ptr.as_mut_ptr() }.get());\n    assert_eq!(2021, unsafe { &*unique_ptr.as_ptr() }.get());\n    assert_eq!(2021, *unique_ptr.pin_mut().getMut());\n    assert_eq!(2022, unique_ptr.pin_mut().set_succeed(2022).unwrap());\n    assert!(unique_ptr.pin_mut().get_fail().is_err());\n    assert_eq!(2021, ffi::Shared { z: 0 }.c_method_on_shared());\n    assert_eq!(2022, *ffi::Shared { z: 2022 }.c_method_ref_on_shared());\n    assert_eq!(2023, *ffi::Shared { z: 2023 }.c_method_mut_on_shared());\n    assert_eq!(2025, ffi::Shared::c_static_method_on_shared());\n    assert_eq!(2026, ffi::C::c_static_method());\n\n    let val = 42;\n    let mut array = ffi::WithArray {\n        a: [0, 0, 0, 0],\n        b: ffi::Buffer::default(),\n    };\n    array.c_set_array(val);\n    assert_eq!(array.a.len() as i32 * val, array.r_get_array_sum());\n\n    R(2020).c_member_function_on_rust_type();\n}\n\n#[test]\nfn test_shared_ptr_weak_ptr() {\n    let shared_ptr = ffi::c_return_shared_ptr();\n    let weak_ptr = SharedPtr::downgrade(&shared_ptr);\n    assert_eq!(1, ffi::c_get_use_count(&weak_ptr));\n\n    assert!(!weak_ptr.upgrade().is_null());\n    assert_eq!(1, ffi::c_get_use_count(&weak_ptr));\n\n    drop(shared_ptr);\n    assert_eq!(0, ffi::c_get_use_count(&weak_ptr));\n    assert!(weak_ptr.upgrade().is_null());\n}\n\n#[test]\nfn test_unique_to_shared_ptr_string() {\n    let unique = ffi::c_return_unique_ptr_string();\n    let ptr = ptr::addr_of!(*unique);\n    let shared = SharedPtr::from(unique);\n    assert_eq!(ptr::addr_of!(*shared), ptr);\n    assert_eq!(*shared, *\"2020\");\n}\n\n#[test]\nfn test_unique_to_shared_ptr_cpp_type() {\n    let unique = ffi::c_return_unique_ptr();\n    let ptr = ptr::addr_of!(*unique);\n    let shared = SharedPtr::from(unique);\n    assert_eq!(ptr::addr_of!(*shared), ptr);\n}\n\n#[test]\nfn test_unique_to_shared_ptr_null() {\n    let unique = UniquePtr::<ffi::C>::null();\n    assert!(unique.is_null());\n    let shared = SharedPtr::from(unique);\n    assert!(shared.is_null());\n}\n\n#[test]\nfn test_shared_ptr_from_raw() {\n    let shared = unsafe { SharedPtr::<ffi::C>::from_raw(ptr::null_mut()) };\n    assert!(shared.is_null());\n}\n\n#[test]\n#[should_panic = \"tests::Undefined is not destructible\"]\nfn test_shared_ptr_from_raw_undefined() {\n    unsafe { SharedPtr::<ffi::Undefined>::from_raw(ptr::null_mut()) };\n}\n\n#[test]\n#[should_panic = \"tests::Private is not destructible\"]\nfn test_shared_ptr_from_raw_private() {\n    unsafe { SharedPtr::<ffi::Private>::from_raw(ptr::null_mut()) };\n}\n\n#[test]\n#[should_panic = \"tests::Unmovable is not move constructible\"]\nfn test_vector_reserve_unmovable() {\n    let mut vector = CxxVector::<ffi::Unmovable>::new();\n    vector.pin_mut().reserve(10);\n}\n\n#[test]\nfn test_c_ns_method_calls() {\n    let unique_ptr = ffi2::ns_c_return_unique_ptr_ns();\n\n    let old_value = unique_ptr.get();\n    assert_eq!(1000, old_value);\n}\n\n#[test]\nfn test_enum_representations() {\n    assert_eq!(0, ffi::Enum::AVal.repr);\n    assert_eq!(2020, ffi::Enum::BVal.repr);\n    assert_eq!(2021, ffi::Enum::LastVal.repr);\n}\n\n#[test]\nfn test_enum_default() {\n    assert_eq!(ffi::Enum::BVal, ffi::Enum::default());\n}\n\n#[test]\nfn test_struct_repr_align() {\n    assert_eq!(4, std::mem::align_of::<ffi::OveralignedStruct>());\n}\n\n#[test]\nfn test_debug() {\n    assert_eq!(\"Shared { z: 1 }\", format!(\"{:?}\", ffi::Shared { z: 1 }));\n    assert_eq!(\"BVal\", format!(\"{:?}\", ffi::Enum::BVal));\n    assert_eq!(\"Enum(9)\", format!(\"{:?}\", ffi::Enum { repr: 9 }));\n}\n\n#[no_mangle]\nextern \"C\" fn cxx_test_suite_get_box() -> *mut R {\n    Box::into_raw(Box::new(R(2020usize)))\n}\n\n#[no_mangle]\nunsafe extern \"C\" fn cxx_test_suite_r_is_correct(r: *const R) -> bool {\n    (*r).0 == 2020\n}\n\n#[test]\nfn test_rust_name_attribute() {\n    assert_eq!(\"2020\", ffi::i32_overloaded_function(2020));\n    assert_eq!(\"2020\", ffi::str_overloaded_function(\"2020\"));\n    let unique_ptr = ffi::c_return_unique_ptr();\n    assert_eq!(\"2020\", unique_ptr.i32_overloaded_method(2020));\n    assert_eq!(\"2020\", unique_ptr.str_overloaded_method(\"2020\"));\n}\n\n#[test]\nfn test_extern_trivial() {\n    let mut d = ffi2::c_return_trivial();\n    check!(ffi2::c_take_trivial_ref(&d));\n    check!(d.c_take_trivial_ref_method());\n    check!(d.c_take_trivial_mut_ref_method());\n    check!(ffi2::c_take_trivial(d));\n    let mut d = ffi2::c_return_trivial_ptr();\n    check!(d.c_take_trivial_ref_method());\n    check!(d.c_take_trivial_mut_ref_method());\n    check!(ffi2::c_take_trivial_ptr(d));\n    cxx::UniquePtr::new(ffi2::D { d: 42 });\n    let d = ffi2::ns_c_return_trivial();\n    check!(ffi2::ns_c_take_trivial(d));\n\n    let g = ffi2::c_return_trivial_ns();\n    check!(ffi2::c_take_trivial_ns_ref(&g));\n    check!(ffi2::c_take_trivial_ns(g));\n    let g = ffi2::c_return_trivial_ns_ptr();\n    check!(ffi2::c_take_trivial_ns_ptr(g));\n    cxx::UniquePtr::new(ffi2::G { g: 42 });\n}\n\n#[test]\nfn test_extern_opaque() {\n    let mut e = ffi2::c_return_opaque_ptr();\n    check!(ffi2::c_take_opaque_ref(e.as_ref().unwrap()));\n    check!(e.c_take_opaque_ref_method());\n    check!(e.pin_mut().c_take_opaque_mut_ref_method());\n    check!(ffi2::c_take_opaque_ptr(e));\n\n    let f = ffi2::c_return_ns_opaque_ptr();\n    check!(ffi2::c_take_opaque_ns_ref(f.as_ref().unwrap()));\n    check!(ffi2::c_take_opaque_ns_ptr(f));\n}\n\n#[test]\nfn test_raw_ptr() {\n    let c = ffi::c_return_mut_ptr(2023);\n    let mut c_unique = unsafe { cxx::UniquePtr::from_raw(c) };\n    assert_eq!(2023, c_unique.pin_mut().set_succeed(2023).unwrap());\n    // c will be dropped as it's now in a UniquePtr\n\n    let c2 = ffi::c_return_mut_ptr(2024);\n    assert_eq!(2024, unsafe { ffi::c_take_const_ptr(c2) });\n    assert_eq!(2024, unsafe { ffi::c_take_mut_ptr(c2) }); // deletes c2\n\n    let c3 = ffi::c_return_const_ptr(2025);\n    assert_eq!(2025, unsafe { ffi::c_take_const_ptr(c3) });\n    assert_eq!(2025, unsafe { ffi::c_take_mut_ptr(c3.cast_mut()) }); // deletes c3\n}\n\n#[test]\n#[allow(clippy::items_after_statements, clippy::no_effect_underscore_binding)]\nfn test_unwind_safe() {\n    fn inspect(_c: &ffi::C) {}\n    let _unwind_safe = |c: UniquePtr<ffi::C>| panic::catch_unwind(|| drop(c));\n    let _ref_unwind_safe = |c: &ffi::C| panic::catch_unwind(|| inspect(c));\n\n    fn require_unwind_safe<T: UnwindSafe>() {}\n    require_unwind_safe::<ffi::C>();\n\n    fn require_ref_unwind_safe<T: RefUnwindSafe>() {}\n    require_ref_unwind_safe::<ffi::C>();\n}\n"
  },
  {
    "path": "tests/ui/array_len_expr.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    struct Shared {\n        arraystr: [String; \"13\"],\n        arraysub: [String; 15 - 1],\n        arrayzero: [String; 0],\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/array_len_expr.stderr",
    "content": "error: array length must be an integer literal\n --> tests/ui/array_len_expr.rs:4:28\n  |\n4 |         arraystr: [String; \"13\"],\n  |                            ^^^^\n\nerror: unsupported expression, array length must be an integer literal\n --> tests/ui/array_len_expr.rs:5:28\n  |\n5 |         arraysub: [String; 15 - 1],\n  |                            ^^^^^^\n\nerror: array with zero size is not supported\n --> tests/ui/array_len_expr.rs:6:20\n  |\n6 |         arrayzero: [String; 0],\n  |                    ^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/array_len_suffix.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        fn array() -> [String; 12u16];\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/array_len_suffix.stderr",
    "content": "error[E0308]: mismatched types\n --> tests/ui/array_len_suffix.rs:4:32\n  |\n4 |         fn array() -> [String; 12u16];\n  |                                ^^^^^ expected `usize`, found `u16`\n  |\n  = note: array length can only be `usize`\nhelp: change the type of the numeric literal from `u16` to `usize`\n  |\n4 -         fn array() -> [String; 12u16];\n4 +         fn array() -> [String; 12usize];\n  |\n"
  },
  {
    "path": "tests/ui/async_fn.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        async fn f();\n    }\n\n    extern \"C++\" {\n        async fn g();\n    }\n}\n\nasync fn f() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/async_fn.stderr",
    "content": "error: async function is not directly supported yet, but see https://cxx.rs/async.html for a working approach, and https://github.com/pcwalton/cxx-async for some helpers; eventually what you wrote will work but it isn't integrated into the cxx::bridge macro yet\n --> tests/ui/async_fn.rs:4:9\n  |\n4 |         async fn f();\n  |         ^^^^^^^^^^^^^\n\nerror: async function is not directly supported yet, but see https://cxx.rs/async.html for a working approach, and https://github.com/pcwalton/cxx-async for some helpers; eventually what you wrote will work but it isn't integrated into the cxx::bridge macro yet\n --> tests/ui/async_fn.rs:8:9\n  |\n8 |         async fn g();\n  |         ^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/bad_explicit_impl.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    struct S {\n        x: u8,\n    }\n\n    impl fn() -> &S {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/bad_explicit_impl.stderr",
    "content": "error: unsupported Self type of explicit impl\n --> tests/ui/bad_explicit_impl.rs:7:5\n  |\n7 |     impl fn() -> &S {}\n  |     ^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/by_value_not_supported.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    struct S {\n        c: C,\n        r: R,\n        s: CxxString,\n    }\n\n    extern \"C++\" {\n        type C;\n    }\n\n    extern \"Rust\" {\n        type R;\n\n        fn f(c: C) -> C;\n        fn g(r: R) -> R;\n        fn h(s: CxxString) -> CxxString;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/by_value_not_supported.stderr",
    "content": "error: using opaque C++ type by value is not supported\n --> tests/ui/by_value_not_supported.rs:4:9\n  |\n4 |         c: C,\n  |         ^^^^\n\nerror: using opaque Rust type by value is not supported\n --> tests/ui/by_value_not_supported.rs:5:9\n  |\n5 |         r: R,\n  |         ^^^^\n\nerror: using C++ string by value is not supported\n --> tests/ui/by_value_not_supported.rs:6:9\n  |\n6 |         s: CxxString,\n  |         ^^^^^^^^^^^^\n\nerror: needs a cxx::ExternType impl in order to be used as a field of `S`, argument of `f` or return value of `f`\n  --> tests/ui/by_value_not_supported.rs:10:9\n   |\n10 |         type C;\n   |         ^^^^^^\n\nerror: passing opaque C++ type by value is not supported\n  --> tests/ui/by_value_not_supported.rs:16:14\n   |\n16 |         fn f(c: C) -> C;\n   |              ^^^^\n\nerror: returning opaque C++ type by value is not supported\n  --> tests/ui/by_value_not_supported.rs:16:23\n   |\n16 |         fn f(c: C) -> C;\n   |                       ^\n\nerror: passing opaque Rust type by value is not supported\n  --> tests/ui/by_value_not_supported.rs:17:14\n   |\n17 |         fn g(r: R) -> R;\n   |              ^^^^\n\nerror: returning opaque Rust type by value is not supported\n  --> tests/ui/by_value_not_supported.rs:17:23\n   |\n17 |         fn g(r: R) -> R;\n   |                       ^\n\nerror: passing C++ string by value is not supported\n  --> tests/ui/by_value_not_supported.rs:18:14\n   |\n18 |         fn h(s: CxxString) -> CxxString;\n   |              ^^^^^^^^^^^^\n\nerror: returning C++ string by value is not supported\n  --> tests/ui/by_value_not_supported.rs:18:31\n   |\n18 |         fn h(s: CxxString) -> CxxString;\n   |                               ^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/const_fn.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        const fn f();\n    }\n}\n\nconst fn f() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/const_fn.stderr",
    "content": "error: const extern function is not supported\n --> tests/ui/const_fn.rs:4:9\n  |\n4 |         const fn f();\n  |         ^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/cxx_crate_name_qualified_cxx_string.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        fn foo(x: CxxString);\n        fn bar(x: &cxx::CxxString);\n    }\n}\n\nfn foo(_: &cxx::CxxString) {\n    todo!()\n}\n\nfn bar(_: &cxx::CxxString) {\n    todo!()\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/cxx_crate_name_qualified_cxx_string.stderr",
    "content": "error: unexpected `cxx::` qualifier found in a `#[cxx::bridge]`\n --> tests/ui/cxx_crate_name_qualified_cxx_string.rs:5:20\n  |\n5 |         fn bar(x: &cxx::CxxString);\n  |                    ^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/data_enums.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    enum A {\n        Field(u64),\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/data_enums.stderr",
    "content": "error: enums with data are not supported yet\n --> tests/ui/data_enums.rs:4:9\n  |\n4 |         Field(u64),\n  |         ^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/deny_elided_lifetimes.rs",
    "content": "#![deny(elided_lifetimes_in_paths, mismatched_lifetime_syntaxes)]\n\nuse cxx::ExternType;\nuse std::marker::PhantomData;\n\n#[repr(C)]\nstruct Alias<'a> {\n    ptr: *const std::ffi::c_void,\n    lifetime: PhantomData<&'a str>,\n}\n\nunsafe impl<'a> ExternType for Alias<'a> {\n    type Id = cxx::type_id!(\"Alias\");\n    type Kind = cxx::kind::Trivial;\n}\n\n#[cxx::bridge]\nmod ffi {\n    #[derive(PartialEq, PartialOrd, Hash)]\n    struct Struct<'a> {\n        reference: &'a i32,\n    }\n\n    extern \"Rust\" {\n        type Rust<'a>;\n    }\n\n    unsafe extern \"C++\" {\n        type Cpp<'a>;\n        type Alias<'a> = crate::Alias<'a>;\n\n        fn lifetime_named<'a>(s: &'a i32) -> UniquePtr<Cpp<'a>>;\n\n        fn lifetime_underscore(s: &i32) -> UniquePtr<Cpp<'_>>;\n\n        fn lifetime_elided(s: &i32) -> UniquePtr<Cpp>;\n    }\n}\n\npub struct Rust<'a>(&'a i32);\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/deny_elided_lifetimes.stderr",
    "content": "error: hidden lifetime parameters in types are deprecated\n  --> tests/ui/deny_elided_lifetimes.rs:36:50\n   |\n36 |         fn lifetime_elided(s: &i32) -> UniquePtr<Cpp>;\n   |                                                  ^^^ expected lifetime parameter\n   |\nnote: the lint level is defined here\n  --> tests/ui/deny_elided_lifetimes.rs:1:9\n   |\n 1 | #![deny(elided_lifetimes_in_paths, mismatched_lifetime_syntaxes)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: indicate the anonymous lifetime\n   |\n36 |         fn lifetime_elided(s: &i32) -> UniquePtr<Cpp<'_>>;\n   |                                                     ++++\n\nerror: hiding a lifetime that's elided elsewhere is confusing\n  --> tests/ui/deny_elided_lifetimes.rs:36:31\n   |\n36 |         fn lifetime_elided(s: &i32) -> UniquePtr<Cpp>;\n   |                               ^^^^               ^^^ the same lifetime is hidden here\n   |                               |\n   |                               the lifetime is elided here\n   |\n   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing\nnote: the lint level is defined here\n  --> tests/ui/deny_elided_lifetimes.rs:1:36\n   |\n 1 | #![deny(elided_lifetimes_in_paths, mismatched_lifetime_syntaxes)]\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: use `'_` for type paths\n   |\n36 |         fn lifetime_elided(s: &i32) -> UniquePtr<Cpp<'_>>;\n   |                                                     ++++\n"
  },
  {
    "path": "tests/ui/deny_missing_docs.rs",
    "content": "// TODO: More work is needed so that the missing_docs lints produced by rustc\n// are properly positioned inside of the bridge.\n\n//! ...\n\n#![deny(missing_docs)]\n\n/// ...\n#[cxx::bridge]\npub mod ffi {\n    pub struct UndocumentedStruct {\n        pub undocumented_field: u8,\n    }\n\n    /// ...\n    pub struct DocumentedStruct {\n        /// ...\n        pub documented_field: u8,\n    }\n\n    pub enum UndocumentedEnum {\n        UndocumentedVariant = 0,\n    }\n\n    /// ...\n    pub enum DocumentedEnum {\n        /// ...\n        DocumentedVariant = 0,\n    }\n\n    extern \"Rust\" {\n        pub type UndocumentedRustType;\n\n        /// ...\n        pub type DocumentedRustType;\n\n        pub fn undocumented_rust_fn() -> u8;\n\n        /// ...\n        pub fn documented_rust_fn() -> u8;\n    }\n\n    unsafe extern \"C++\" {\n        pub type UndocumentedForeignType;\n\n        /// ...\n        pub type DocumentedForeignType;\n\n        pub type UndocumentedTypeAlias = crate::bindgen::UndocumentedTypeAlias;\n\n        /// ...\n        pub type DocumentedTypeAlias = crate::bindgen::DocumentedTypeAlias;\n\n        pub fn undocumented_foreign_fn() -> u8;\n\n        /// ...\n        pub fn documented_foreign_fn() -> u8;\n    }\n\n    #[allow(missing_docs)]\n    pub struct SuppressUndocumentedStruct {\n        pub undocumented_field: u8,\n    }\n}\n\nstruct UndocumentedRustType;\nstruct DocumentedRustType;\n\nmod bindgen {\n    use cxx::{type_id, ExternType};\n\n    pub struct UndocumentedTypeAlias;\n    pub struct DocumentedTypeAlias;\n\n    unsafe impl ExternType for UndocumentedTypeAlias {\n        type Id = type_id!(\"UndocumentedTypeAlias\");\n        type Kind = cxx::kind::Opaque;\n    }\n\n    unsafe impl ExternType for DocumentedTypeAlias {\n        type Id = type_id!(\"DocumentedTypeAlias\");\n        type Kind = cxx::kind::Opaque;\n    }\n}\n\nfn undocumented_rust_fn() -> u8 {\n    0\n}\n\nfn documented_rust_fn() -> u8 {\n    0\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/deny_missing_docs.stderr",
    "content": "error: missing documentation for a struct\n  --> tests/ui/deny_missing_docs.rs:11:5\n   |\n11 |     pub struct UndocumentedStruct {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/deny_missing_docs.rs:6:9\n   |\n 6 | #![deny(missing_docs)]\n   |         ^^^^^^^^^^^^\n\nerror: missing documentation for a struct field\n  --> tests/ui/deny_missing_docs.rs:12:9\n   |\n12 |         pub undocumented_field: u8,\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: missing documentation for a struct\n  --> tests/ui/deny_missing_docs.rs:21:5\n   |\n21 |     pub enum UndocumentedEnum {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui/deny_missing_docs.rs:22:9\n   |\n22 |         UndocumentedVariant = 0,\n   |         ^^^^^^^^^^^^^^^^^^^\n\nerror: missing documentation for a struct\n  --> tests/ui/deny_missing_docs.rs:44:9\n   |\n44 |         pub type UndocumentedForeignType;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: missing documentation for a type alias\n  --> tests/ui/deny_missing_docs.rs:49:9\n   |\n49 |         pub type UndocumentedTypeAlias = crate::bindgen::UndocumentedTypeAlias;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: missing documentation for a function\n  --> tests/ui/deny_missing_docs.rs:54:9\n   |\n54 |         pub fn undocumented_foreign_fn() -> u8;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/derive_bit_struct.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    #[derive(BitAnd, BitOr, BitXor)]\n    struct Struct {\n        x: i32,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_bit_struct.stderr",
    "content": "error: derive(BitAnd) is currently only supported on enums, not structs\n --> tests/ui/derive_bit_struct.rs:3:14\n  |\n3 |     #[derive(BitAnd, BitOr, BitXor)]\n  |              ^^^^^^\n\nerror: derive(BitOr) is currently only supported on enums, not structs\n --> tests/ui/derive_bit_struct.rs:3:22\n  |\n3 |     #[derive(BitAnd, BitOr, BitXor)]\n  |                      ^^^^^\n\nerror: derive(BitXor) is currently only supported on enums, not structs\n --> tests/ui/derive_bit_struct.rs:3:29\n  |\n3 |     #[derive(BitAnd, BitOr, BitXor)]\n  |                             ^^^^^^\n"
  },
  {
    "path": "tests/ui/derive_default.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    #[derive(Default)]\n    enum NoDefault {\n        Two,\n        Three,\n        Five,\n        Seven,\n    }\n\n    #[derive(Default)]\n    enum MultipleDefault {\n        #[default]\n        Two,\n        Three,\n        Five,\n        #[default]\n        Seven,\n    }\n}\n\n#[cxx::bridge]\nmod ffi2 {\n    #[derive(Default)]\n    enum BadDefault {\n        #[default(repr)]\n        Two,\n        #[default = 3]\n        Three,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_default.stderr",
    "content": "error: derive(Default) on enum requires exactly one variant to be marked with #[default]\n --> tests/ui/derive_default.rs:3:14\n  |\n3 |     #[derive(Default)]\n  |              ^^^^^^^\n\nerror: derive(Default) on enum requires exactly one variant to be marked with #[default] (found 2)\n  --> tests/ui/derive_default.rs:11:14\n   |\n11 |     #[derive(Default)]\n   |              ^^^^^^^\n\nerror: #[default] attribute does not accept an argument\n  --> tests/ui/derive_default.rs:26:18\n   |\n26 |         #[default(repr)]\n   |                  ^\n\nerror: #[default] attribute does not accept an argument\n  --> tests/ui/derive_default.rs:28:19\n   |\n28 |         #[default = 3]\n   |                   ^\n"
  },
  {
    "path": "tests/ui/derive_duplicate.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    #[derive(Clone, Clone)]\n    struct Struct {\n        x: usize,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_duplicate.stderr",
    "content": "error[E0119]: conflicting implementations of trait `Clone` for type `ffi::Struct`\n --> tests/ui/derive_duplicate.rs:3:21\n  |\n3 |     #[derive(Clone, Clone)]\n  |              -----  ^^^^^ conflicting implementation for `ffi::Struct`\n  |              |\n  |              first implementation here\n"
  },
  {
    "path": "tests/ui/derive_noncopy.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    #[derive(Copy)]\n    struct TryCopy {\n        other: Other,\n    }\n\n    struct Other {\n        x: usize,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_noncopy.stderr",
    "content": "error[E0204]: the trait `Copy` cannot be implemented for this type\n --> tests/ui/derive_noncopy.rs:4:12\n  |\n4 |     struct TryCopy {\n  |            ^^^^^^^\n5 |         other: Other,\n  |         ------------ this field does not implement `Copy`\n"
  },
  {
    "path": "tests/ui/drop_shared.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    struct Shared {\n        fd: i32,\n    }\n}\n\nimpl Drop for ffi::Shared {\n    fn drop(&mut self) {\n        println!(\"close({})\", self.fd);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/drop_shared.stderr",
    "content": "error[E0119]: conflicting implementations of trait `forbid::Drop` for type `Shared`\n --> tests/ui/drop_shared.rs:3:5\n  |\n1 | #[cxx::bridge]\n  | -------------- first implementation here\n2 | mod ffi {\n3 |     struct Shared {\n  |     ^^^^^^^^^^^^^ conflicting implementation for `Shared`\n"
  },
  {
    "path": "tests/ui/duplicate_method.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type T;\n        fn t_method(&self);\n        fn t_method(&self);\n    }\n}\n\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type U;\n        fn u_method(&self);\n        fn u_method(&mut self);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/duplicate_method.stderr",
    "content": "error: the associated function `T::t_method` is defined multiple times\n --> tests/ui/duplicate_method.rs:6:9\n  |\n6 |         fn t_method(&self);\n  |         ^^^^^^^^^^^^^^^^^^^\n\nerror: the associated function `U::u_method` is defined multiple times\n  --> tests/ui/duplicate_method.rs:15:9\n   |\n15 |         fn u_method(&mut self);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/empty_enum.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    enum A {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_enum.stderr",
    "content": "error: explicit #[repr(...)] is required for enum without any variants\n --> tests/ui/empty_enum.rs:3:5\n  |\n3 |     enum A {}\n  |     ^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/empty_struct.rs",
    "content": "#![allow(unexpected_cfgs)]\n\n#[cxx::bridge]\nmod ffi {\n    struct Empty {}\n}\n\n#[cxx::bridge]\nmod ffi2 {\n    struct ConditionallyEmpty {\n        #[cfg(target_os = \"nonexistent\")]\n        never: u8,\n        #[cfg(target_os = \"another\")]\n        another: u8,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_struct.stderr",
    "content": "error: structs without any fields are not supported\n --> tests/ui/empty_struct.rs:5:5\n  |\n5 |     struct Empty {}\n  |     ^^^^^^^^^^^^^^^\n\nerror: structs without any fields are not supported\n  --> tests/ui/empty_struct.rs:10:5\n   |\n10 |     struct ConditionallyEmpty {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/enum_assoc.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    enum Enum {\n        Variant,\n    }\n    extern \"Rust\" {\n        #[Self = \"Enum\"]\n        fn f();\n    }\n}\n\nimpl ffi::Enum {\n    fn f() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/enum_assoc.stderr",
    "content": "error: unsupported self type; C++ does not allow member functions on enums\n --> tests/ui/enum_assoc.rs:7:18\n  |\n7 |         #[Self = \"Enum\"]\n  |                  ^^^^^^\n"
  },
  {
    "path": "tests/ui/enum_inconsistent.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    enum Bad {\n        A = 1u16,\n        B = 2i64,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/enum_inconsistent.stderr",
    "content": "error: expected u16, found i64\n --> tests/ui/enum_inconsistent.rs:5:9\n  |\n5 |         B = 2i64,\n  |         ^^^^^^^^\n"
  },
  {
    "path": "tests/ui/enum_match_without_wildcard.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    enum A {\n        FieldA,\n        FieldB,\n    }\n}\n\nfn main() {}\n\nfn matcher(a: ffi::A) -> u32 {\n    match a {\n        ffi::A::FieldA => 2020,\n        ffi::A::FieldB => 2021,\n    }\n}\n"
  },
  {
    "path": "tests/ui/enum_match_without_wildcard.stderr",
    "content": "error[E0004]: non-exhaustive patterns: `A { repr: 2_u8..=u8::MAX }` not covered\n  --> tests/ui/enum_match_without_wildcard.rs:12:11\n   |\n12 |     match a {\n   |           ^ pattern `A { repr: 2_u8..=u8::MAX }` not covered\n   |\nnote: `A` defined here\n  --> tests/ui/enum_match_without_wildcard.rs:3:10\n   |\n 3 |     enum A {\n   |          ^\n   = note: the matched value is of type `A`\nhelp: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown\n   |\n14 ~         ffi::A::FieldB => 2021,\n15 ~         A { repr: 2_u8..=u8::MAX } => todo!(),\n   |\n"
  },
  {
    "path": "tests/ui/enum_out_of_bounds.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    #[repr(u32)]\n    enum Bad1 {\n        A = 0xFFFF_FFFF_FFFF_FFFF,\n    }\n    enum Bad2 {\n        A = 2000,\n        B = 1u8,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/enum_out_of_bounds.stderr",
    "content": "error: discriminant value `18446744073709551615` is outside the limits of u32\n --> tests/ui/enum_out_of_bounds.rs:5:9\n  |\n5 |         A = 0xFFFF_FFFF_FFFF_FFFF,\n  |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: discriminant value `2000` is outside the limits of u8\n --> tests/ui/enum_out_of_bounds.rs:9:9\n  |\n9 |         B = 1u8,\n  |         ^^^^^^^\n"
  },
  {
    "path": "tests/ui/enum_overflows.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    enum Good1 {\n        A = 0xFFFF_FFFF_FFFF_FFFF,\n    }\n    enum Good2 {\n        B = 0xFFFF_FFFF_FFFF_FFFF,\n        C = 2020,\n    }\n    enum Bad {\n        D = 0xFFFF_FFFF_FFFF_FFFE,\n        E,\n        F,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/enum_overflows.stderr",
    "content": "error: discriminant overflow on value after 18446744073709551615\n  --> tests/ui/enum_overflows.rs:13:9\n   |\n13 |         F,\n   |         ^\n"
  },
  {
    "path": "tests/ui/enum_receiver.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    enum Enum {\n        Variant,\n    }\n    extern \"Rust\" {\n        fn f(self: &Enum);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/enum_receiver.stderr",
    "content": "error: unsupported receiver type; C++ does not allow member functions on enums\n --> tests/ui/enum_receiver.rs:7:20\n  |\n7 |         fn f(self: &Enum);\n  |                    ^^^^^\n"
  },
  {
    "path": "tests/ui/enum_unsatisfiable.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    enum Bad {\n        A = -0xFFFF_FFFF_FFFF_FFFF,\n        B = 0xFFFF_FFFF_FFFF_FFFF,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/enum_unsatisfiable.stderr",
    "content": "error: these discriminant values do not fit in any supported enum repr type\n --> tests/ui/enum_unsatisfiable.rs:3:5\n  |\n3 | /     enum Bad {\n4 | |         A = -0xFFFF_FFFF_FFFF_FFFF,\n5 | |         B = 0xFFFF_FFFF_FFFF_FFFF,\n6 | |     }\n  | |_____^\n"
  },
  {
    "path": "tests/ui/expected_named.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type Borrowed<'a>;\n        fn borrowed() -> UniquePtr<Borrowed>;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/expected_named.stderr",
    "content": "error[E0106]: missing lifetime specifier\n --> tests/ui/expected_named.rs:5:36\n  |\n5 |         fn borrowed() -> UniquePtr<Borrowed>;\n  |                                    ^^^^^^^^ expected named lifetime parameter\n  |\n  = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from\nhelp: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values\n  |\n5 |         fn borrowed() -> UniquePtr<Borrowed<'static>>;\n  |                                            +++++++++\n"
  },
  {
    "path": "tests/ui/explicit_impl_of_bad_unique_ptr.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    impl UniquePtr<Vec<u8>> {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/explicit_impl_of_bad_unique_ptr.stderr",
    "content": "error: unsupported unique_ptr target type\n --> tests/ui/explicit_impl_of_bad_unique_ptr.rs:3:10\n  |\n3 |     impl UniquePtr<Vec<u8>> {}\n  |          ^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/extern_fn_abi.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        extern \"Java\" fn f();\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/extern_fn_abi.stderr",
    "content": "error: explicit ABI on extern function is not supported\n --> tests/ui/extern_fn_abi.rs:4:9\n  |\n4 |         extern \"Java\" fn f();\n  |         ^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/extern_shared_struct.rs",
    "content": "#![deny(deprecated)]\n\n#[cxx::bridge]\npub mod ffi {\n    struct StructX {\n        a: u64,\n    }\n\n    #[namespace = \"mine\"]\n    unsafe extern \"C++\" {\n        type StructX;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/extern_shared_struct.stderr",
    "content": "error: use of deprecated struct `ffi::_::StructX`:\n       Shared struct redeclared as an unsafe extern C++ type is deprecated.\n       If this is intended to be a shared struct, remove this `type StructX`.\n       If this is intended to be an extern type, change it to:\n\n           use cxx::ExternType;\n\n           #[repr(C)]\n           pub struct StructX {\n               ...\n           }\n\n           unsafe impl ExternType for StructX {\n               type Id = cxx::type_id!(\"mine::StructX\");\n               type Kind = cxx::kind::Trivial;\n           }\n\n           pub mod ffi {\n               #[namespace = \"mine\"]\n               extern \"C++\" {\n                   type StructX = crate::StructX;\n               }\n               ...\n           }\n  --> tests/ui/extern_shared_struct.rs:11:14\n   |\n11 |         type StructX;\n   |              ^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/extern_shared_struct.rs:1:9\n   |\n 1 | #![deny(deprecated)]\n   |         ^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/extern_type_bound.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        type Opaque: PartialEq + PartialOrd;\n    }\n}\n\n#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        type Opaque: for<'de> Deserialize<'de>;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/extern_type_bound.stderr",
    "content": "error: extern type bounds are not implemented yet\n --> tests/ui/extern_type_bound.rs:4:22\n  |\n4 |         type Opaque: PartialEq + PartialOrd;\n  |                      ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: unsupported trait\n  --> tests/ui/extern_type_bound.rs:11:22\n   |\n11 |         type Opaque: for<'de> Deserialize<'de>;\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/extern_type_generic.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        type Generic<T>;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/extern_type_generic.stderr",
    "content": "error: extern type with generic type parameter is not supported yet\n --> tests/ui/extern_type_generic.rs:4:22\n  |\n4 |         type Generic<T>;\n  |                      ^\n"
  },
  {
    "path": "tests/ui/extern_type_lifetime_bound.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        type Complex<'a, 'b: 'a>;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/extern_type_lifetime_bound.stderr",
    "content": "error: lifetime parameter with bounds is not supported yet\n --> tests/ui/extern_type_lifetime_bound.rs:4:26\n  |\n4 |         type Complex<'a, 'b: 'a>;\n  |                          ^^^^^^\n"
  },
  {
    "path": "tests/ui/fallible_fnptr.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        fn f(callback: fn() -> Result<()>);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/fallible_fnptr.stderr",
    "content": "error: function pointer returning Result is not supported yet\n --> tests/ui/fallible_fnptr.rs:4:24\n  |\n4 |         fn f(callback: fn() -> Result<()>);\n  |                        ^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/function_with_body.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        fn f() {}\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/function_with_body.stderr",
    "content": "error: expected `;`\n --> tests/ui/function_with_body.rs:4:16\n  |\n4 |         fn f() {}\n  |                ^\n"
  },
  {
    "path": "tests/ui/generic_enum.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    enum A<T> {\n        Field,\n    }\n\n    enum B<T> where T: Copy {\n        Field,\n    }\n\n    enum C where void: Copy {\n        Field,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/generic_enum.stderr",
    "content": "error: enum with generic parameters is not supported\n --> tests/ui/generic_enum.rs:3:5\n  |\n3 |     enum A<T> {\n  |     ^^^^^^^^^\n\nerror: enum with generic parameters is not supported\n --> tests/ui/generic_enum.rs:7:5\n  |\n7 |     enum B<T> where T: Copy {\n  |     ^^^^^^^^^\n\nerror: enum with where-clause is not supported\n  --> tests/ui/generic_enum.rs:11:12\n   |\n11 |     enum C where void: Copy {\n   |            ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/impl_trait_for_type.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    struct S {\n        x: u8,\n    }\n\n    impl UniquePtrTarget for S {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/impl_trait_for_type.stderr",
    "content": "error: unexpected impl, expected something like `impl UniquePtr<T> {}`\n --> tests/ui/impl_trait_for_type.rs:7:10\n  |\n7 |     impl UniquePtrTarget for S {}\n  |          ^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/include.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        include!(\"path/to\" what);\n        include!(<path/to> what);\n        include!(<path/to);\n        include!(<path[to]>);\n        include!(...);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/include.stderr",
    "content": "error: unexpected token\n --> tests/ui/include.rs:4:28\n  |\n4 |         include!(\"path/to\" what);\n  |                            ^^^^\n\nerror: unexpected token\n --> tests/ui/include.rs:5:28\n  |\n5 |         include!(<path/to> what);\n  |                            ^^^^\n\nerror: expected `>`\n --> tests/ui/include.rs:6:26\n  |\n6 |         include!(<path/to);\n  |                          ^\n\nerror: unexpected token in include path\n --> tests/ui/include.rs:7:23\n  |\n7 |         include!(<path[to]>);\n  |                       ^^^^\n\nerror: expected \"quoted/path/to\" or <bracketed/path/to>\n --> tests/ui/include.rs:8:18\n  |\n8 |         include!(...);\n  |                  ^\n"
  },
  {
    "path": "tests/ui/lifetime_extern_cxx.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        type Opaque;\n        unsafe fn f<'a>(&'a self, arg: &str) -> &'a str;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/lifetime_extern_cxx.stderr",
    "content": "error: extern C++ function with lifetimes must be declared in `unsafe extern \"C++\"` block\n --> tests/ui/lifetime_extern_cxx.rs:5:9\n  |\n5 |         unsafe fn f<'a>(&'a self, arg: &str) -> &'a str;\n  |         ^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/lifetime_extern_rust.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type Opaque;\n        fn f<'a>(&'a self, arg: &str) -> &'a str;\n    }\n}\n\npub struct Opaque;\n\nimpl Opaque {\n    fn f(&self, _arg: &str) -> &str {\n        \"\"\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/lifetime_extern_rust.stderr",
    "content": "error: must be `unsafe fn f` in order to expose explicit lifetimes to C++\n --> tests/ui/lifetime_extern_rust.rs:5:9\n  |\n5 |         fn f<'a>(&'a self, arg: &str) -> &'a str;\n  |         ^^^^^^^^\n"
  },
  {
    "path": "tests/ui/missing_unsafe.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        fn f(x: i32);\n    }\n}\n\nunsafe fn f(_x: i32) {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/missing_unsafe.stderr",
    "content": "error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block\n --> tests/ui/missing_unsafe.rs:4:12\n  |\n4 |         fn f(x: i32);\n  |            ^        - items do not inherit unsafety from separate enclosing items\n  |            |\n  |            call to unsafe function\n  |\n  = note: consult the function's documentation for information on how to avoid undefined behavior\n"
  },
  {
    "path": "tests/ui/multiple_parse_error.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    struct Monad<T>;\n\n    extern \"Haskell\" {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/multiple_parse_error.stderr",
    "content": "error: unit structs are not supported\n --> tests/ui/multiple_parse_error.rs:3:5\n  |\n3 |     struct Monad<T>;\n  |     ^^^^^^^^^^^^^^^^\n\nerror: unrecognized ABI, requires either \"C++\" or \"Rust\"\n --> tests/ui/multiple_parse_error.rs:5:5\n  |\n5 |     extern \"Haskell\" {}\n  |     ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/mut_return.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type Mut<'a>;\n    }\n\n    unsafe extern \"C++\" {\n        type Thing;\n\n        fn f(t: &Thing) -> Pin<&mut CxxString>;\n        unsafe fn g(t: &Thing) -> Pin<&mut CxxString>;\n        fn h(t: Box<Mut>) -> Pin<&mut CxxString>;\n        fn i<'a>(t: Box<Mut<'a>>) -> Pin<&'a mut CxxString>;\n        fn j(t: &Thing) -> &mut [u8];\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/mut_return.stderr",
    "content": "error: &mut return type is not allowed unless there is a &mut argument\n  --> tests/ui/mut_return.rs:10:9\n   |\n10 |         fn f(t: &Thing) -> Pin<&mut CxxString>;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: &mut return type is not allowed unless there is a &mut argument\n  --> tests/ui/mut_return.rs:14:9\n   |\n14 |         fn j(t: &Thing) -> &mut [u8];\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/non_integer_discriminant_enum.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    enum A {\n        Field = 2020 + 1,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/non_integer_discriminant_enum.stderr",
    "content": "error: enums with non-integer literal discriminants are not supported yet\n --> tests/ui/non_integer_discriminant_enum.rs:4:9\n  |\n4 |         Field = 2020 + 1,\n  |         ^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/nonempty_impl_block.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    struct S {\n        x: u8,\n    }\n\n    impl UniquePtr<S> {\n        fn new() -> Self;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/nonempty_impl_block.stderr",
    "content": "error: expected an empty impl block\n --> tests/ui/nonempty_impl_block.rs:7:23\n  |\n7 |       impl UniquePtr<S> {\n  |  _______________________^\n8 | |         fn new() -> Self;\n9 | |     }\n  | |_____^\n"
  },
  {
    "path": "tests/ui/nonlocal_rust_type.rs",
    "content": "pub struct MyBuilder<'a> {\n    _s: &'a str,\n}\n\ntype OptBuilder<'a> = Option<MyBuilder<'a>>;\n\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type OptBuilder<'a>;\n    }\n\n    struct MyBuilder<'a> {\n        rs: Box<OptBuilder<'a>>,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/nonlocal_rust_type.stderr",
    "content": "error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate\n  --> tests/ui/nonlocal_rust_type.rs:10:9\n   |\n10 |         type OptBuilder<'a>;\n   |         ^^^^^--------------\n   |              |\n   |              `Option` is not defined in the current crate\n   |\n   = note: impl doesn't have any local type before any uncovered type parameters\n   = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules\n   = note: define and implement a trait or new type instead\n\nerror[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate\n  --> tests/ui/nonlocal_rust_type.rs:14:13\n   |\n14 |         rs: Box<OptBuilder<'a>>,\n   |             ^^^^--------------\n   |                 |\n   |                 `Option` is not defined in the current crate\n   |\n   = note: impl doesn't have any local type before any uncovered type parameters\n   = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules\n   = note: define and implement a trait or new type instead\n"
  },
  {
    "path": "tests/ui/opaque_autotraits.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        type Opaque;\n    }\n}\n\nfn assert_send<T: Send>() {}\nfn assert_sync<T: Sync>() {}\nfn assert_unpin<T: Unpin>() {}\n\nfn main() {\n    assert_send::<ffi::Opaque>();\n    assert_sync::<ffi::Opaque>();\n    assert_unpin::<ffi::Opaque>();\n}\n"
  },
  {
    "path": "tests/ui/opaque_autotraits.stderr",
    "content": "error[E0277]: `*const cxx::void` cannot be sent between threads safely\n  --> tests/ui/opaque_autotraits.rs:13:19\n   |\n13 |     assert_send::<ffi::Opaque>();\n   |                   ^^^^^^^^^^^ `*const cxx::void` cannot be sent between threads safely\n   |\n   = help: within `ffi::Opaque`, the trait `Send` is not implemented for `*const cxx::void`\n   = note: required because it appears within the type `[*const cxx::void; 0]`\nnote: required because it appears within the type `cxx::private::Opaque`\n  --> src/opaque.rs\n   |\n   | pub struct Opaque {\n   |            ^^^^^^\nnote: required because it appears within the type `ffi::Opaque`\n  --> tests/ui/opaque_autotraits.rs:4:14\n   |\n 4 |         type Opaque;\n   |              ^^^^^^\nnote: required by a bound in `assert_send`\n  --> tests/ui/opaque_autotraits.rs:8:19\n   |\n 8 | fn assert_send<T: Send>() {}\n   |                   ^^^^ required by this bound in `assert_send`\n\nerror[E0277]: `*const cxx::void` cannot be shared between threads safely\n  --> tests/ui/opaque_autotraits.rs:14:19\n   |\n14 |     assert_sync::<ffi::Opaque>();\n   |                   ^^^^^^^^^^^ `*const cxx::void` cannot be shared between threads safely\n   |\n   = help: within `ffi::Opaque`, the trait `Sync` is not implemented for `*const cxx::void`\n   = note: required because it appears within the type `[*const cxx::void; 0]`\nnote: required because it appears within the type `cxx::private::Opaque`\n  --> src/opaque.rs\n   |\n   | pub struct Opaque {\n   |            ^^^^^^\nnote: required because it appears within the type `ffi::Opaque`\n  --> tests/ui/opaque_autotraits.rs:4:14\n   |\n 4 |         type Opaque;\n   |              ^^^^^^\nnote: required by a bound in `assert_sync`\n  --> tests/ui/opaque_autotraits.rs:9:19\n   |\n 9 | fn assert_sync<T: Sync>() {}\n   |                   ^^^^ required by this bound in `assert_sync`\n\nerror[E0277]: `PhantomPinned` cannot be unpinned\n  --> tests/ui/opaque_autotraits.rs:15:20\n   |\n15 |     assert_unpin::<ffi::Opaque>();\n   |                    ^^^^^^^^^^^ within `ffi::Opaque`, the trait `Unpin` is not implemented for `PhantomPinned`\n   |\n   = note: consider using the `pin!` macro\n           consider using `Box::pin` if you need to access the pinned value outside of the current scope\nnote: required because it appears within the type `PhantomData<PhantomPinned>`\n  --> $RUST/core/src/marker.rs\n   |\n   | pub struct PhantomData<T: PointeeSized>;\n   |            ^^^^^^^^^^^\nnote: required because it appears within the type `cxx::private::Opaque`\n  --> src/opaque.rs\n   |\n   | pub struct Opaque {\n   |            ^^^^^^\nnote: required because it appears within the type `ffi::Opaque`\n  --> tests/ui/opaque_autotraits.rs:4:14\n   |\n 4 |         type Opaque;\n   |              ^^^^^^\nnote: required by a bound in `assert_unpin`\n  --> tests/ui/opaque_autotraits.rs:10:20\n   |\n10 | fn assert_unpin<T: Unpin>() {}\n   |                    ^^^^^ required by this bound in `assert_unpin`\n"
  },
  {
    "path": "tests/ui/opaque_not_sized.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type TypeR;\n    }\n}\n\nstruct TypeR(str);\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/opaque_not_sized.stderr",
    "content": "error[E0277]: the size for values of type `str` cannot be known at compilation time\n --> tests/ui/opaque_not_sized.rs:4:14\n  |\n4 |         type TypeR;\n  |              ^^^^^ doesn't have a size known at compile-time\n  |\n  = help: within `TypeR`, the trait `Sized` is not implemented for `str`\nnote: required because it appears within the type `TypeR`\n --> tests/ui/opaque_not_sized.rs:8:8\n  |\n8 | struct TypeR(str);\n  |        ^^^^^\nnote: required by a bound in `__AssertSized`\n --> tests/ui/opaque_not_sized.rs:4:9\n  |\n4 |         type TypeR;\n  |         ^^^^^^^^^^^ required by this bound in `__AssertSized`\n"
  },
  {
    "path": "tests/ui/pin_mut_alias.rs",
    "content": "mod arg {\n    use cxx::ExternType;\n    use std::marker::{PhantomData, PhantomPinned};\n\n    struct Arg(PhantomPinned);\n\n    unsafe impl ExternType for Arg {\n        type Id = cxx::type_id!(\"Arg\");\n        type Kind = cxx::kind::Opaque;\n    }\n\n    struct ArgLife<'a>(PhantomPinned, PhantomData<&'a ()>);\n\n    unsafe impl<'a> ExternType for ArgLife<'a> {\n        type Id = cxx::type_id!(\"ArgLife\");\n        type Kind = cxx::kind::Opaque;\n    }\n\n    #[cxx::bridge]\n    mod ffi {\n        unsafe extern \"C++\" {\n            type Arg = crate::arg::Arg;\n            fn f(arg: &mut Arg);\n        }\n    }\n\n    #[cxx::bridge]\n    mod ffi_life {\n        unsafe extern \"C++\" {\n            type ArgLife<'a> = crate::arg::ArgLife<'a>;\n            fn fl<'b, 'c>(arg: &'b mut ArgLife<'c>);\n        }\n    }\n}\n\nmod receiver {\n    use cxx::ExternType;\n    use std::marker::{PhantomData, PhantomPinned};\n\n    struct Receiver(PhantomPinned);\n\n    unsafe impl ExternType for Receiver {\n        type Id = cxx::type_id!(\"Receiver\");\n        type Kind = cxx::kind::Opaque;\n    }\n\n    struct ReceiverLife<'a>(PhantomPinned, PhantomData<&'a ()>);\n\n    unsafe impl<'a> ExternType for ReceiverLife<'a> {\n        type Id = cxx::type_id!(\"ReceiverLife\");\n        type Kind = cxx::kind::Opaque;\n    }\n\n    #[cxx::bridge]\n    mod ffi {\n        unsafe extern \"C++\" {\n            type Receiver = crate::receiver::Receiver;\n            fn g(&mut self);\n        }\n    }\n\n    #[cxx::bridge]\n    mod ffi_life {\n        unsafe extern \"C++\" {\n            type ReceiverLife<'a> = crate::receiver::ReceiverLife<'a>;\n            fn g<'b>(&'b mut self);\n        }\n    }\n}\n\nmod receiver2 {\n    use cxx::ExternType;\n    use std::marker::{PhantomData, PhantomPinned};\n\n    struct Receiver2(PhantomPinned);\n\n    unsafe impl ExternType for Receiver2 {\n        type Id = cxx::type_id!(\"Receiver2\");\n        type Kind = cxx::kind::Opaque;\n    }\n\n    struct ReveiverLife2<'a>(PhantomPinned, PhantomData<&'a ()>);\n\n    unsafe impl<'a> ExternType for ReveiverLife2<'a> {\n        type Id = cxx::type_id!(\"ReveiverLife2\");\n        type Kind = cxx::kind::Opaque;\n    }\n\n    #[cxx::bridge]\n    mod ffi {\n        unsafe extern \"C++\" {\n            type Receiver2 = crate::receiver2::Receiver2;\n            fn h(self: &mut Receiver2);\n        }\n    }\n\n    #[cxx::bridge]\n    mod ffi_life {\n        unsafe extern \"C++\" {\n            type ReveiverLife2<'a> = crate::receiver2::ReveiverLife2<'a>;\n            fn h<'b, 'c>(self: &'b mut ReveiverLife2<'c>);\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/pin_mut_alias.stderr",
    "content": "error[E0277]: mutable reference to C++ type requires a pin -- use Pin<&mut Arg>\n  --> tests/ui/pin_mut_alias.rs:23:23\n   |\n23 |             fn f(arg: &mut Arg);\n   |                       ^^^^^^^^ use `Pin<&mut Arg>`\n   |\n   = help: the trait `ReferenceToUnpin_Arg` is not implemented for `&mut arg::Arg`\n\nerror[E0277]: mutable reference to C++ type requires a pin -- use Pin<&mut ArgLife>\n  --> tests/ui/pin_mut_alias.rs:31:32\n   |\n31 |             fn fl<'b, 'c>(arg: &'b mut ArgLife<'c>);\n   |                                ^^^^^^^^^^^^^^^^^^^ use `Pin<&'b mut ArgLife<'c>>`\n   |\n   = help: the trait `ReferenceToUnpin_ArgLife` is not implemented for `&mut arg::ArgLife<'_>`\n\nerror[E0277]: mutable reference to C++ type requires a pin -- use Pin<&mut Receiver>\n  --> tests/ui/pin_mut_alias.rs:58:18\n   |\n58 |             fn g(&mut self);\n   |                  ^^^^^^^^^ use `self: Pin<&mut Receiver>`\n   |\n   = help: the trait `ReferenceToUnpin_Receiver` is not implemented for `&mut receiver::Receiver`\n\nerror[E0277]: mutable reference to C++ type requires a pin -- use Pin<&mut ReceiverLife>\n  --> tests/ui/pin_mut_alias.rs:66:22\n   |\n66 |             fn g<'b>(&'b mut self);\n   |                      ^^^^^^^^^^^^ use `self: Pin<&'b mut ReceiverLife<'_>>`\n   |\n   = help: the trait `ReferenceToUnpin_ReceiverLife` is not implemented for `&mut receiver::ReceiverLife<'_>`\n\nerror[E0277]: mutable reference to C++ type requires a pin -- use Pin<&mut Receiver2>\n  --> tests/ui/pin_mut_alias.rs:93:24\n   |\n93 |             fn h(self: &mut Receiver2);\n   |                        ^^^^^^^^^^^^^^ use `Pin<&mut Receiver2>`\n   |\n   = help: the trait `ReferenceToUnpin_Receiver2` is not implemented for `&mut receiver2::Receiver2`\n\nerror[E0277]: mutable reference to C++ type requires a pin -- use Pin<&mut ReveiverLife2>\n   --> tests/ui/pin_mut_alias.rs:101:32\n    |\n101 |             fn h<'b, 'c>(self: &'b mut ReveiverLife2<'c>);\n    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^ use `Pin<&'b mut ReveiverLife2<'c>>`\n    |\n    = help: the trait `ReferenceToUnpin_ReveiverLife2` is not implemented for `&mut receiver2::ReveiverLife2<'_>`\n"
  },
  {
    "path": "tests/ui/pin_mut_opaque.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type Opaque;\n        fn f(arg: &mut Opaque);\n        fn g(&mut self);\n        fn h(self: &mut Opaque);\n        fn s(s: &mut CxxString);\n        fn v(v: &mut CxxVector<u8>);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/pin_mut_opaque.stderr",
    "content": "error: mutable reference to C++ type requires a pin -- use Pin<&mut Opaque>\n --> tests/ui/pin_mut_opaque.rs:5:19\n  |\n5 |         fn f(arg: &mut Opaque);\n  |                   ^^^^^^^^^^^\n\nerror: mutable reference to C++ type requires a pin -- use Pin<&mut CxxString>\n --> tests/ui/pin_mut_opaque.rs:8:17\n  |\n8 |         fn s(s: &mut CxxString);\n  |                 ^^^^^^^^^^^^^^\n\nerror: mutable reference to C++ type requires a pin -- use Pin<&mut CxxVector<...>>\n --> tests/ui/pin_mut_opaque.rs:9:17\n  |\n9 |         fn v(v: &mut CxxVector<u8>);\n  |                 ^^^^^^^^^^^^^^^^^^\n\nerror: mutable reference to opaque C++ type requires a pin -- use `self: Pin<&mut Opaque>`\n --> tests/ui/pin_mut_opaque.rs:6:14\n  |\n6 |         fn g(&mut self);\n  |              ^^^^^^^^^\n\nerror: mutable reference to opaque C++ type requires a pin -- use `self: Pin<&mut Opaque>`\n --> tests/ui/pin_mut_opaque.rs:7:20\n  |\n7 |         fn h(self: &mut Opaque);\n  |                    ^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/ptr_in_fnptr.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        fn f(callback: fn(p: *const u8));\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/ptr_in_fnptr.stderr",
    "content": "error: pointer argument requires that the function pointer be marked unsafe\n --> tests/ui/ptr_in_fnptr.rs:4:27\n  |\n4 |         fn f(callback: fn(p: *const u8));\n  |                           ^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/ptr_missing_unsafe.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type C;\n\n        fn not_unsafe_ptr(c: *mut C);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/ptr_missing_unsafe.stderr",
    "content": "error: pointer argument requires that the function be marked unsafe\n --> tests/ui/ptr_missing_unsafe.rs:6:27\n  |\n6 |         fn not_unsafe_ptr(c: *mut C);\n  |                           ^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/ptr_no_const_mut.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type C;\n\n        fn get_neither_const_nor_mut() -> *C;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/ptr_no_const_mut.stderr",
    "content": "error: expected `mut` or `const` keyword in raw pointer type\n --> tests/ui/ptr_no_const_mut.rs:6:43\n  |\n6 |         fn get_neither_const_nor_mut() -> *C;\n  |                                           ^\n  |\nhelp: add `mut` or `const` here\n  |\n6 |         fn get_neither_const_nor_mut() -> *mut C;\n  |                                            +++\n6 |         fn get_neither_const_nor_mut() -> *const C;\n  |                                            +++++\n\nerror: expected `const` or `mut`\n --> tests/ui/ptr_no_const_mut.rs:6:44\n  |\n6 |         fn get_neither_const_nor_mut() -> *C;\n  |                                            ^\n"
  },
  {
    "path": "tests/ui/ptr_unsupported.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type C;\n\n        fn get_ptr_to_reference() -> *mut &C;\n        fn get_uniqueptr_to_ptr() -> UniquePtr<*mut C>;\n        fn get_vector_of_ptr() -> UniquePtr<CxxVector<*mut C>>;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/ptr_unsupported.stderr",
    "content": "error: C++ does not allow pointer to reference as a type\n --> tests/ui/ptr_unsupported.rs:6:38\n  |\n6 |         fn get_ptr_to_reference() -> *mut &C;\n  |                                      ^^^^^^^\n\nerror: unsupported unique_ptr target type\n --> tests/ui/ptr_unsupported.rs:7:38\n  |\n7 |         fn get_uniqueptr_to_ptr() -> UniquePtr<*mut C>;\n  |                                      ^^^^^^^^^^^^^^^^^\n\nerror: unsupported vector element type\n --> tests/ui/ptr_unsupported.rs:8:45\n  |\n8 |         fn get_vector_of_ptr() -> UniquePtr<CxxVector<*mut C>>;\n  |                                             ^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/raw_ident_namespace.rs",
    "content": "use cxx::{type_id, ExternType};\n\n#[repr(transparent)]\npub struct QuotedRaw(usize);\n\nunsafe impl ExternType for QuotedRaw {\n    type Id = type_id!(\"org::r#box::implementation::QuotedRaw\");\n    type Kind = cxx::kind::Trivial;\n}\n\n#[repr(transparent)]\npub struct QuotedKeyword(usize);\n\nunsafe impl ExternType for QuotedKeyword {\n    type Id = type_id!(\"org::box::implementation::QuotedKeyword\");\n    type Kind = cxx::kind::Trivial;\n}\n\n#[repr(transparent)]\npub struct UnquotedRaw(usize);\n\nunsafe impl ExternType for UnquotedRaw {\n    type Id = type_id!(org::r#box::implementation::UnquotedRaw);\n    type Kind = cxx::kind::Trivial;\n}\n\n#[repr(transparent)]\npub struct UnquotedKeyword(usize);\n\nunsafe impl ExternType for UnquotedKeyword {\n    type Id = type_id!(org::box::implementation::UnquotedKeyword);\n    type Kind = cxx::kind::Trivial;\n}\n\n#[cxx::bridge]\npub mod ffi {\n    extern \"C++\" {\n        #[namespace = \"org::r#box::implementation\"]\n        type QuotedRaw = crate::QuotedRaw;\n\n        #[namespace = \"org::box::implementation\"]\n        type QuotedKeyword = crate::QuotedKeyword;\n\n        #[namespace = org::r#box::implementation]\n        type UnquotedRaw = crate::UnquotedRaw;\n\n        // Not allowed by rustc (independent of cxx):\n        // #[namespace = org::box::implementation]\n        // type UnquotedKeyword = crate::UnquotedKeyword;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/raw_ident_namespace.stderr",
    "content": "error: raw identifier `r#box` is not allowed in a quoted namespace; use `box`, or remove quotes\n --> tests/ui/raw_ident_namespace.rs:7:24\n  |\n7 |     type Id = type_id!(\"org::r#box::implementation::QuotedRaw\");\n  |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: raw identifier `r#box` is not allowed in a quoted namespace; use `box`, or remove quotes\n  --> tests/ui/raw_ident_namespace.rs:38:23\n   |\n38 |         #[namespace = \"org::r#box::implementation\"]\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/reference_to_reference.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type ThingC;\n        fn repro_c(t: &&ThingC);\n    }\n    extern \"Rust\" {\n        type ThingR;\n        fn repro_r(t: &&ThingR);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/reference_to_reference.stderr",
    "content": "error: C++ does not allow references to references\n --> tests/ui/reference_to_reference.rs:5:23\n  |\n5 |         fn repro_c(t: &&ThingC);\n  |                       ^^^^^^^^\n\nerror: C++ does not allow references to references\n --> tests/ui/reference_to_reference.rs:9:23\n  |\n9 |         fn repro_r(t: &&ThingR);\n  |                       ^^^^^^^^\n"
  },
  {
    "path": "tests/ui/repr_align_suffixed.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    #[repr(align(2int))]\n    struct StructSuffix {\n        i: i32,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/repr_align_suffixed.stderr",
    "content": "error: invalid suffix `int` for number literal\n --> tests/ui/repr_align_suffixed.rs:3:18\n  |\n3 |     #[repr(align(2int))]\n  |                  ^^^^ invalid suffix `int`\n  |\n  = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)\n"
  },
  {
    "path": "tests/ui/repr_unsupported.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    #[repr(align(2))]\n    enum EnumAlign {\n        A,\n    }\n\n    #[repr(i64)]\n    struct StructInt {\n        i: i32,\n    }\n\n    #[repr(align(1 << 10))]\n    struct StructExpr {\n        i: i32,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/repr_unsupported.stderr",
    "content": "error: C++ does not support custom alignment on an enum\n --> tests/ui/repr_unsupported.rs:3:18\n  |\n3 |     #[repr(align(2))]\n  |                  ^\n\nerror: unsupported alignment on a struct\n --> tests/ui/repr_unsupported.rs:8:12\n  |\n8 |     #[repr(i64)]\n  |            ^^^\n\nerror: invalid repr(align) attribute: an arithmetic expression is not supported\n  --> tests/ui/repr_unsupported.rs:13:18\n   |\n13 |     #[repr(align(1 << 10))]\n   |                  ^^^^^^^\n"
  },
  {
    "path": "tests/ui/reserved_lifetime.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type Logger;\n\n        fn logger<'static>() -> Pin<&'static Logger>;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/reserved_lifetime.stderr",
    "content": "error[E0262]: invalid lifetime parameter name: `'static`\n --> tests/ui/reserved_lifetime.rs:6:19\n  |\n6 |         fn logger<'static>() -> Pin<&'static Logger>;\n  |                   ^^^^^^^ 'static is a reserved lifetime name\n"
  },
  {
    "path": "tests/ui/reserved_name.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    struct UniquePtr {\n        val: usize,\n    }\n\n    extern \"C++\" {\n        type Box;\n    }\n\n    extern \"Rust\" {\n        type String;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/reserved_name.stderr",
    "content": "error: reserved name\n --> tests/ui/reserved_name.rs:3:12\n  |\n3 |     struct UniquePtr {\n  |            ^^^^^^^^^\n\nerror: reserved name\n --> tests/ui/reserved_name.rs:8:14\n  |\n8 |         type Box;\n  |              ^^^\n\nerror: reserved name\n  --> tests/ui/reserved_name.rs:12:14\n   |\n12 |         type String;\n   |              ^^^^^^\n"
  },
  {
    "path": "tests/ui/result_no_display.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        fn f() -> Result<()>;\n    }\n}\n\npub struct NonError;\n\nfn f() -> Result<(), NonError> {\n    Ok(())\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/result_no_display.stderr",
    "content": "error[E0277]: `NonError` doesn't implement `std::fmt::Display`\n --> tests/ui/result_no_display.rs:4:19\n  |\n4 |         fn f() -> Result<()>;\n  |                   ^^^^^^^^^^ unsatisfied trait bound\n  |\nhelp: the trait `std::fmt::Display` is not implemented for `NonError`\n --> tests/ui/result_no_display.rs:8:1\n  |\n8 | pub struct NonError;\n  | ^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/root_namespace.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    #[namespace = \"::\"]\n    extern \"Rust\" {}\n\n    #[namespace = \"\"]\n    extern \"Rust\" {}\n\n    #[namespace = ]\n    extern \"Rust\" {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/root_namespace.stderr",
    "content": "error: expected expression, found `]`\n --> tests/ui/root_namespace.rs:9:19\n  |\n9 |     #[namespace = ]\n  |                   ^ expected expression\n"
  },
  {
    "path": "tests/ui/rust_pinned.rs",
    "content": "use std::marker::PhantomPinned;\n\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type Pinned;\n    }\n}\n\npub struct Pinned {\n    _pinned: PhantomPinned,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/rust_pinned.stderr",
    "content": "error[E0277]: `PhantomPinned` cannot be unpinned\n  --> tests/ui/rust_pinned.rs:6:14\n   |\n 6 |         type Pinned;\n   |              ^^^^^^ within `Pinned`, the trait `Unpin` is not implemented for `PhantomPinned`\n   |\n   = note: consider using the `pin!` macro\n           consider using `Box::pin` if you need to access the pinned value outside of the current scope\nnote: required because it appears within the type `Pinned`\n  --> tests/ui/rust_pinned.rs:10:12\n   |\n10 | pub struct Pinned {\n   |            ^^^^^^\nnote: required by a bound in `cxx::private::require_unpin`\n  --> src/rust_type.rs\n   |\n   | pub fn require_unpin<T: ?Sized + Unpin>() {}\n   |                                  ^^^^^ required by this bound in `require_unpin`\n"
  },
  {
    "path": "tests/ui/self_lifetimes.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type Thing<'a, 'b>;\n\n        fn zero(self: &Thing<>);\n        fn one<'a>(self: &Thing<'a>);\n        fn three<'a, 'b, 'c>(self: &Thing<'a, 'b, 'c>);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/self_lifetimes.stderr",
    "content": "error[E0726]: implicit elided lifetime not allowed here\n --> tests/ui/self_lifetimes.rs:6:24\n  |\n6 |         fn zero(self: &Thing<>);\n  |                        ^^^^^^^ expected lifetime parameters\n  |\nhelp: indicate the anonymous lifetimes\n  |\n6 |         fn zero(self: &Thing<'_, '_, >);\n  |                              +++++++\n\nerror[E0107]: struct takes 2 lifetime arguments but 1 lifetime argument was supplied\n --> tests/ui/self_lifetimes.rs:7:27\n  |\n7 |         fn one<'a>(self: &Thing<'a>);\n  |                           ^^^^^ -- supplied 1 lifetime argument\n  |                           |\n  |                           expected 2 lifetime arguments\n  |\nnote: struct defined here, with 2 lifetime parameters: `'a`, `'b`\n --> tests/ui/self_lifetimes.rs:4:14\n  |\n4 |         type Thing<'a, 'b>;\n  |              ^^^^^ --  --\nhelp: add missing lifetime argument\n  |\n7 |         fn one<'a>(self: &Thing<'a, 'a>);\n  |                                   ++++\n\nerror[E0107]: struct takes 2 lifetime arguments but 3 lifetime arguments were supplied\n --> tests/ui/self_lifetimes.rs:8:37\n  |\n8 |         fn three<'a, 'b, 'c>(self: &Thing<'a, 'b, 'c>);\n  |                                     ^^^^^       ---- help: remove the lifetime argument\n  |                                     |\n  |                                     expected 2 lifetime arguments\n  |\nnote: struct defined here, with 2 lifetime parameters: `'a`, `'b`\n --> tests/ui/self_lifetimes.rs:4:14\n  |\n4 |         type Thing<'a, 'b>;\n  |              ^^^^^ --  --\n"
  },
  {
    "path": "tests/ui/self_type_and_receiver.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type T;\n\n        #[Self = \"T\"]\n        fn method(self: &T);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/self_type_and_receiver.stderr",
    "content": "error: function with Self type must not have a `self` argument\n --> tests/ui/self_type_and_receiver.rs:6:18\n  |\n6 |         #[Self = \"T\"]\n  |                  ^^^\n"
  },
  {
    "path": "tests/ui/slice_of_pinned.rs",
    "content": "use cxx::{type_id, ExternType};\nuse std::marker::PhantomPinned;\n\n#[repr(C)]\nstruct Pinned(usize, PhantomPinned);\n\n#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type Pinned = crate::Pinned;\n        fn f(_: &[Pinned], _: &mut [Pinned]);\n    }\n}\n\nunsafe impl ExternType for Pinned {\n    type Id = type_id!(\"Pinned\");\n    type Kind = cxx::kind::Trivial;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/slice_of_pinned.stderr",
    "content": "error[E0277]: mutable slice of pinned type is not supported\n  --> tests/ui/slice_of_pinned.rs:11:31\n   |\n11 |         fn f(_: &[Pinned], _: &mut [Pinned]);\n   |                               ^^^^^^^^^^^^^ requires `Pinned: Unpin`\n   |\n   = help: the trait `SliceOfUnpin_Pinned` is not implemented for `&mut [Pinned]`\n"
  },
  {
    "path": "tests/ui/slice_of_type_alias.rs",
    "content": "use cxx::{type_id, ExternType};\n\n#[repr(C)]\nstruct ElementTrivial(usize);\n\n#[repr(C)]\nstruct ElementOpaque(usize);\n\n#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type ElementTrivial = crate::ElementTrivial;\n        type ElementOpaque = crate::ElementOpaque;\n\n        fn f(slice: &mut [ElementTrivial]);\n        fn g(slice: &[ElementOpaque]);\n    }\n}\n\nunsafe impl ExternType for ElementTrivial {\n    type Id = type_id!(\"ElementTrivial\");\n    type Kind = cxx::kind::Trivial;\n}\n\nunsafe impl ExternType for ElementOpaque {\n    type Id = type_id!(\"ElementOpaque\");\n    type Kind = cxx::kind::Opaque;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/slice_of_type_alias.stderr",
    "content": "error[E0271]: type mismatch resolving `<&[ElementOpaque] as SliceOfExternType>::Kind == Trivial`\n  --> tests/ui/slice_of_type_alias.rs:16:21\n   |\n16 |         fn g(slice: &[ElementOpaque]);\n   |                     ^^^^^^^^^^^^^^^^ expected `Trivial`, found `Opaque`\n   |\nnote: required by a bound in `cxx::private::Without::check_slice`\n  --> src/rust_type.rs\n   |\n   |     pub const fn check_slice<U: SliceOfExternType<Kind = Trivial>>(&self) {}\n   |                                                   ^^^^^^^^^^^^^^ required by this bound in `Without::check_slice`\n"
  },
  {
    "path": "tests/ui/slice_unsupported.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type Opaque;\n\n        fn f(_: &mut [Opaque]);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/slice_unsupported.stderr",
    "content": "error: unsupported &mut [T] element type: opaque C++ type is not supported yet\n --> tests/ui/slice_unsupported.rs:6:17\n  |\n6 |         fn f(_: &mut [Opaque]);\n  |                 ^^^^^^^^^^^^^\n\nerror: needs a cxx::ExternType impl in order to be used as a slice element in &mut [Opaque]\n --> tests/ui/slice_unsupported.rs:4:9\n  |\n4 |         type Opaque;\n  |         ^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/struct_align.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    #[repr(align(3))]\n    struct SharedA {\n        b: [u8; 4],\n    }\n\n    // 1073741824 = 2^30\n    #[repr(align(1073741824))]\n    struct SharedB {\n        b: [u8; 4],\n    }\n\n    #[repr(align(-2))]\n    struct SharedC {\n        b: [u8; 4],\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/struct_align.stderr",
    "content": "error: invalid repr(align) attribute: not a power of two\n --> tests/ui/struct_align.rs:3:18\n  |\n3 |     #[repr(align(3))]\n  |                  ^\n\nerror: invalid repr(align) attribute: larger than 2^13\n --> tests/ui/struct_align.rs:9:18\n  |\n9 |     #[repr(align(1073741824))]\n  |                  ^^^^^^^^^^\n\nerror: invalid repr(align) attribute: an arithmetic expression is not supported\n  --> tests/ui/struct_align.rs:14:18\n   |\n14 |     #[repr(align(-2))]\n   |                  ^^\n"
  },
  {
    "path": "tests/ui/struct_cycle.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    struct Node0 {\n        i: i32,\n    }\n\n    struct Node1 {\n        node2: Node2,\n        vec: Vec<Node3>,\n    }\n\n    struct Node2 {\n        node4: Node4,\n    }\n\n    struct Node3 {\n        node1: Node1,\n    }\n\n    struct Node4 {\n        node0: Node0,\n        node5: Node5,\n    }\n\n    struct Node5 {\n        node2: Node2,\n    }\n\n    struct Node6 {\n        node2: Node2,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/struct_cycle.stderr",
    "content": "error: unsupported cyclic data structure\n  --> tests/ui/struct_cycle.rs:26:9\n   |\n26 |         node2: Node2,\n   |         ^^^^^^^^^^^^\n\nerror: unsupported cyclic data structure\n  --> tests/ui/struct_cycle.rs:22:9\n   |\n22 |         node5: Node5,\n   |         ^^^^^^^^^^^^\n\nerror: unsupported cyclic data structure\n  --> tests/ui/struct_cycle.rs:13:9\n   |\n13 |         node4: Node4,\n   |         ^^^^^^^^^^^^\n\nerror: unsupported cyclic data structure\n --> tests/ui/struct_cycle.rs:8:9\n  |\n8 |         node2: Node2,\n  |         ^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/type_alias_rust.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        /// Incorrect.\n        type Alias = crate::Type;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/type_alias_rust.stderr",
    "content": "error: type alias in extern \"Rust\" block is not supported\n --> tests/ui/type_alias_rust.rs:5:9\n  |\n5 |         type Alias = crate::Type;\n  |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/undeclared_lifetime.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        fn f0(_: &'a CxxString);\n        fn g0<'a>(_: &'b CxxString);\n\n        type This<'a>;\n        fn f1(self: &This, _: &'a CxxString);\n        fn g1<'a>(self: &This, _: &'b CxxString);\n        fn f2(self: &'a This);\n        fn g2<'a>(self: &'b This);\n        fn f3(self: &This<'a>);\n        fn g3<'a>(self: &This<'b>);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/undeclared_lifetime.stderr",
    "content": "error[E0261]: use of undeclared lifetime name `'a`\n --> tests/ui/undeclared_lifetime.rs:4:19\n  |\n4 |         fn f0(_: &'a CxxString);\n  |                   ^^ undeclared lifetime\n  |\nhelp: consider introducing lifetime `'a` here\n  |\n4 |         fn f0<'a>(_: &'a CxxString);\n  |              ++++\n\nerror[E0261]: use of undeclared lifetime name `'b`\n --> tests/ui/undeclared_lifetime.rs:5:23\n  |\n5 |         fn g0<'a>(_: &'b CxxString);\n  |                       ^^ undeclared lifetime\n  |\nhelp: consider introducing lifetime `'b` here\n  |\n5 |         fn g0<'b, 'a>(_: &'b CxxString);\n  |               +++\n\nerror[E0261]: use of undeclared lifetime name `'a`\n --> tests/ui/undeclared_lifetime.rs:8:32\n  |\n8 |         fn f1(self: &This, _: &'a CxxString);\n  |                                ^^ undeclared lifetime\n  |\nhelp: consider introducing lifetime `'a` here\n  |\n8 |         fn f1<'a>(self: &This, _: &'a CxxString);\n  |              ++++\nhelp: consider introducing lifetime `'a` here\n  |\n8 |         fn f1<'a>(self: &This, _: &'a CxxString);\n  |              ++++\n\nerror[E0261]: use of undeclared lifetime name `'b`\n --> tests/ui/undeclared_lifetime.rs:9:36\n  |\n9 |         fn g1<'a>(self: &This, _: &'b CxxString);\n  |                                    ^^ undeclared lifetime\n  |\nhelp: consider introducing lifetime `'b` here\n  |\n9 |         fn g1<'b, 'a>(self: &This, _: &'b CxxString);\n  |               +++\nhelp: consider introducing lifetime `'b` here\n  |\n9 |         fn g1<'b, 'a>(self: &This, _: &'b CxxString);\n  |               +++\n\nerror[E0261]: use of undeclared lifetime name `'a`\n  --> tests/ui/undeclared_lifetime.rs:10:22\n   |\n10 |         fn f2(self: &'a This);\n   |                      ^^ undeclared lifetime\n   |\nhelp: consider introducing lifetime `'a` here\n   |\n10 |         fn f2<'a>(self: &'a This);\n   |              ++++\nhelp: consider introducing lifetime `'a` here\n   |\n10 |         fn f2<'a>(self: &'a This);\n   |              ++++\n\nerror[E0261]: use of undeclared lifetime name `'b`\n  --> tests/ui/undeclared_lifetime.rs:11:26\n   |\n11 |         fn g2<'a>(self: &'b This);\n   |                          ^^ undeclared lifetime\n   |\nhelp: consider introducing lifetime `'b` here\n   |\n11 |         fn g2<'b, 'a>(self: &'b This);\n   |               +++\nhelp: consider introducing lifetime `'b` here\n   |\n11 |         fn g2<'b, 'a>(self: &'b This);\n   |               +++\n\nerror[E0261]: use of undeclared lifetime name `'a`\n  --> tests/ui/undeclared_lifetime.rs:12:27\n   |\n12 |         fn f3(self: &This<'a>);\n   |                           ^^ undeclared lifetime\n   |\nhelp: consider introducing lifetime `'a` here\n   |\n12 |         fn f3<'a>(self: &This<'a>);\n   |              ++++\n\nerror[E0261]: use of undeclared lifetime name `'b`\n  --> tests/ui/undeclared_lifetime.rs:13:31\n   |\n13 |         fn g3<'a>(self: &This<'b>);\n   |                               ^^ undeclared lifetime\n   |\nhelp: consider introducing lifetime `'b` here\n   |\n13 |         fn g3<'b, 'a>(self: &This<'b>);\n   |               +++\n"
  },
  {
    "path": "tests/ui/unique_ptr_as_mut.rs",
    "content": "use cxx::UniquePtr;\n\n#[cxx::bridge]\nmod ffi {\n    struct Shared {\n        x: i32,\n    }\n\n    extern \"C++\" {\n        type Opaque;\n    }\n\n    impl UniquePtr<Shared> {}\n    impl UniquePtr<Opaque> {}\n}\n\nfn main() {\n    let mut shared = UniquePtr::<ffi::Shared>::null();\n    let _: &mut ffi::Shared = &mut shared;\n\n    let mut opaque = UniquePtr::<ffi::Opaque>::null();\n    let _: &mut ffi::Opaque = &mut opaque;\n}\n"
  },
  {
    "path": "tests/ui/unique_ptr_as_mut.stderr",
    "content": "error[E0596]: cannot borrow data in dereference of `UniquePtr<ffi::Opaque>` as mutable\n  --> tests/ui/unique_ptr_as_mut.rs:22:31\n   |\n22 |     let _: &mut ffi::Opaque = &mut opaque;\n   |                               ^^^^^^^^^^^ cannot borrow as mutable\n   |\n   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `UniquePtr<ffi::Opaque>`\n"
  },
  {
    "path": "tests/ui/unique_ptr_to_opaque.rs",
    "content": "mod outside {\n    #[repr(C)]\n    pub struct C {\n        pub a: u8,\n    }\n    unsafe impl cxx::ExternType for C {\n        type Id = cxx::type_id!(\"C\");\n        type Kind = cxx::kind::Opaque;\n    }\n}\n\n#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        type C = crate::outside::C;\n    }\n\n    impl UniquePtr<C> {}\n}\n\nfn main() {\n    cxx::UniquePtr::new(outside::C { a: 4 });\n}\n"
  },
  {
    "path": "tests/ui/unique_ptr_to_opaque.stderr",
    "content": "error[E0271]: type mismatch resolving `<C as ExternType>::Kind == Trivial`\n  --> tests/ui/unique_ptr_to_opaque.rs:22:25\n   |\n22 |     cxx::UniquePtr::new(outside::C { a: 4 });\n   |     ------------------- ^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<C as ExternType>::Kind == Trivial`\n   |     |\n   |     required by a bound introduced by this call\n   |\nnote: expected this to be `Trivial`\n  --> tests/ui/unique_ptr_to_opaque.rs:8:21\n   |\n 8 |         type Kind = cxx::kind::Opaque;\n   |                     ^^^^^^^^^^^^^^^^^\nnote: required by a bound in `UniquePtr::<T>::new`\n  --> src/unique_ptr.rs\n   |\n   |     pub fn new(value: T) -> Self\n   |            --- required by a bound in this associated function\n   |     where\n   |         T: ExternType<Kind = Trivial>,\n   |                       ^^^^^^^^^^^^^^ required by this bound in `UniquePtr::<T>::new`\n"
  },
  {
    "path": "tests/ui/unique_ptr_twice.rs",
    "content": "#[cxx::bridge]\nmod here {\n    extern \"C++\" {\n        type C;\n    }\n\n    impl UniquePtr<C> {}\n}\n\n#[cxx::bridge]\nmod there {\n    extern \"C++\" {\n        type C = crate::here::C;\n    }\n\n    impl UniquePtr<C> {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unique_ptr_twice.stderr",
    "content": "error[E0119]: conflicting implementations of trait `UniquePtrTarget` for type `here::C`\n  --> tests/ui/unique_ptr_twice.rs:16:5\n   |\n 7 |     impl UniquePtr<C> {}\n   |     ---------------- first implementation here\n...\n16 |     impl UniquePtr<C> {}\n   |     ^^^^^^^^^^^^^^^^ conflicting implementation for `here::C`\n"
  },
  {
    "path": "tests/ui/unnamed_receiver.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        type One;\n        type Two;\n        fn f(&mut self);\n    }\n\n    extern \"Rust\" {\n        fn f(self: &Self);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unnamed_receiver.stderr",
    "content": "error: unnamed receiver type is only allowed if the surrounding extern block contains exactly one extern type; use `self: &mut TheType`\n --> tests/ui/unnamed_receiver.rs:6:14\n  |\n6 |         fn f(&mut self);\n  |              ^^^^^^^^^\n\nerror: unnamed receiver type is only allowed if the surrounding extern block contains exactly one extern type; use `self: &TheType`\n  --> tests/ui/unnamed_receiver.rs:10:20\n   |\n10 |         fn f(self: &Self);\n   |                    ^^^^^\n"
  },
  {
    "path": "tests/ui/unpin_impl.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        type Opaque;\n    }\n}\n\nimpl Unpin for ffi::Opaque {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unpin_impl.stderr",
    "content": "error[E0283]: type annotations needed\n --> tests/ui/unpin_impl.rs:4:14\n  |\n4 |         type Opaque;\n  |              ^^^^^^ cannot infer type\n  |\nnote: multiple `impl`s satisfying `ffi::Opaque: __AmbiguousIfImpl<_>` found\n --> tests/ui/unpin_impl.rs:1:1\n  |\n1 | #[cxx::bridge]\n  | ^^^^^^^^^^^^^^\n  = note: this error originates in the attribute macro `cxx::bridge` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "tests/ui/unrecognized_receiver.rs",
    "content": "#[cxx::bridge]\nmod ffi {\n    unsafe extern \"C++\" {\n        fn f(self: &Unrecognized);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unrecognized_receiver.stderr",
    "content": "error: unrecognized receiver type\n --> tests/ui/unrecognized_receiver.rs:4:20\n  |\n4 |         fn f(self: &Unrecognized);\n  |                    ^^^^^^^^^^^^^\n"
  },
  {
    "path": "tests/ui/unsupported_elided.rs",
    "content": "use std::marker::PhantomData;\n\n#[cxx::bridge]\nmod ffi {\n    extern \"Rust\" {\n        type T;\n\n        fn f(t: &T) -> &str;\n    }\n}\n\npub struct T<'a> {\n    _lifetime: PhantomData<&'a ()>,\n}\n\nfn f<'a>(_t: &T<'a>) -> &'a str {\n    \"\"\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unsupported_elided.stderr",
    "content": "error[E0726]: implicit elided lifetime not allowed here\n --> tests/ui/unsupported_elided.rs:6:14\n  |\n6 |         type T;\n  |              ^ expected lifetime parameter\n  |\nhelp: indicate the anonymous lifetime\n  |\n6 |         type T<'_>;\n  |               ++++\n\nerror[E0106]: missing lifetime specifier\n --> tests/ui/unsupported_elided.rs:8:24\n  |\n8 |         fn f(t: &T) -> &str;\n  |                 --     ^ expected named lifetime parameter\n  |\n  = help: this function's return type contains a borrowed value, but the signature does not say which one of `t`'s 2 lifetimes it is borrowed from\nhelp: consider introducing a named lifetime parameter\n  |\n8 |         fn f<'a>(t: &'a T<'a>) -> &'a str;\n  |             ++++     ++  ++++      ++\n"
  },
  {
    "path": "tests/ui/vec_opaque.rs",
    "content": "#[cxx::bridge]\nmod handle {\n    extern \"C++\" {\n        type Job;\n    }\n}\n\n#[cxx::bridge]\nmod ffi1 {\n    extern \"C++\" {\n        type Job;\n    }\n\n    extern \"Rust\" {\n        fn f() -> Vec<Job>;\n    }\n}\n\n#[cxx::bridge]\nmod ffi2 {\n    extern \"C++\" {\n        type Job = crate::handle::Job;\n    }\n\n    extern \"Rust\" {\n        fn f() -> Vec<Job>;\n    }\n}\n\nfn f() -> Vec<handle::Job> {\n    unimplemented!()\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/vec_opaque.stderr",
    "content": "error: Rust Vec containing C++ type is not supported yet\n  --> tests/ui/vec_opaque.rs:15:19\n   |\n15 |         fn f() -> Vec<Job>;\n   |                   ^^^^^^^^\n\nerror: needs a cxx::ExternType impl in order to be used as a vector element in Vec<Job>\n  --> tests/ui/vec_opaque.rs:11:9\n   |\n11 |         type Job;\n   |         ^^^^^^^^\n\nerror[E0277]: the trait bound `handle::Job: cxx::private::ImplVec` is not satisfied\n  --> tests/ui/vec_opaque.rs:22:14\n   |\n22 |         type Job = crate::handle::Job;\n   |              ^^^ unsatisfied trait bound\n   |\nhelp: the trait `cxx::private::ImplVec` is not implemented for `handle::Job`\n  --> tests/ui/vec_opaque.rs:4:9\n   |\n 4 |         type Job;\n   |         ^^^^^^^^\nnote: required by a bound in `cxx::private::require_vec`\n  --> src/rust_type.rs\n   |\n   | pub fn require_vec<T: ImplVec>() {}\n   |                       ^^^^^^^ required by this bound in `require_vec`\n"
  },
  {
    "path": "tests/ui/vector_autotraits.rs",
    "content": "use cxx::CxxVector;\n\n#[cxx::bridge]\nmod ffi {\n    extern \"C++\" {\n        type ThreadSafe;\n        type NotThreadSafe;\n    }\n\n    impl CxxVector<ThreadSafe> {}\n    impl CxxVector<NotThreadSafe> {}\n}\n\nunsafe impl Send for ffi::ThreadSafe {}\n\nfn assert_send<T: Send>() {}\n\nfn main() {\n    assert_send::<CxxVector<ffi::ThreadSafe>>();\n    assert_send::<CxxVector<ffi::NotThreadSafe>>();\n}\n"
  },
  {
    "path": "tests/ui/vector_autotraits.stderr",
    "content": "error[E0277]: `*const cxx::void` cannot be sent between threads safely\n  --> tests/ui/vector_autotraits.rs:20:19\n   |\n20 |     assert_send::<CxxVector<ffi::NotThreadSafe>>();\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const cxx::void` cannot be sent between threads safely\n   |\n   = help: within `CxxVector<NotThreadSafe>`, the trait `Send` is not implemented for `*const cxx::void`\n   = note: required because it appears within the type `[*const cxx::void; 0]`\nnote: required because it appears within the type `cxx::private::Opaque`\n  --> src/opaque.rs\n   |\n   | pub struct Opaque {\n   |            ^^^^^^\nnote: required because it appears within the type `NotThreadSafe`\n  --> tests/ui/vector_autotraits.rs:7:14\n   |\n 7 |         type NotThreadSafe;\n   |              ^^^^^^^^^^^^^\n   = note: required because it appears within the type `[NotThreadSafe]`\nnote: required because it appears within the type `PhantomData<[NotThreadSafe]>`\n  --> $RUST/core/src/marker.rs\n   |\n   | pub struct PhantomData<T: PointeeSized>;\n   |            ^^^^^^^^^^^\nnote: required because it appears within the type `CxxVector<NotThreadSafe>`\n  --> src/cxx_vector.rs\n   |\n   | pub struct CxxVector<T> {\n   |            ^^^^^^^^^\nnote: required by a bound in `assert_send`\n  --> tests/ui/vector_autotraits.rs:16:19\n   |\n16 | fn assert_send<T: Send>() {}\n   |                   ^^^^ required by this bound in `assert_send`\n"
  },
  {
    "path": "tests/ui/wrong_type_id.rs",
    "content": "#[cxx::bridge(namespace = \"folly\")]\nmod here {\n    extern \"C++\" {\n        type StringPiece;\n    }\n}\n\n#[cxx::bridge(namespace = \"folly\")]\nmod there {\n    extern \"C++\" {\n        type ByteRange = crate::here::StringPiece;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/wrong_type_id.stderr",
    "content": "error[E0271]: type mismatch resolving `<StringPiece as ExternType>::Id == (f, o, l, l, y, (), B, y, t, e, R, a, n, g, e)`\n  --> tests/ui/wrong_type_id.rs:11:14\n   |\n11 |         type ByteRange = crate::here::StringPiece;\n   |              ^^^^^^^^^ type mismatch resolving `<StringPiece as ExternType>::Id == (f, o, l, l, y, (), B, y, t, e, R, a, n, g, e)`\n   |\nnote: expected this to be `(cxx::f, cxx::o, cxx::l, cxx::l, cxx::y, (), cxx::B, cxx::y, cxx::t, cxx::e, cxx::R, cxx::a, cxx::n, cxx::g, cxx::e)`\n  --> tests/ui/wrong_type_id.rs:1:1\n   |\n 1 | #[cxx::bridge(namespace = \"folly\")]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: expected tuple `(cxx::f, cxx::o, cxx::l, cxx::l, cxx::y, (), cxx::B, cxx::y, cxx::t, cxx::e, cxx::R, cxx::a, cxx::n, cxx::g, cxx::e)`\n              found tuple `(cxx::f, cxx::o, cxx::l, cxx::l, cxx::y, (), cxx::S, cxx::t, cxx::r, cxx::i, cxx::n, cxx::g, cxx::P, cxx::i, cxx::e, cxx::c, cxx::e)`\nnote: required by a bound in `cxx::private::verify_extern_type`\n  --> src/extern_type.rs\n   |\n   | pub fn verify_extern_type<T: ExternType<Id = Id>, Id>() {}\n   |                                         ^^^^^^^ required by this bound in `verify_extern_type`\n   = note: this error originates in the attribute macro `cxx::bridge` (in Nightly builds, run with -Z macro-backtrace for more info)\n"
  },
  {
    "path": "tests/unique_ptr.rs",
    "content": "use cxx::{CxxString, UniquePtr};\n\n#[test]\n#[should_panic = \"called deref on a null UniquePtr<CxxString>\"]\nfn test_deref_null() {\n    let unique_ptr = UniquePtr::<CxxString>::null();\n    let _: &CxxString = &unique_ptr;\n}\n"
  },
  {
    "path": "third-party/.cargo/.gitignore",
    "content": "/.global-cache\n/.package-cache\n/.package-cache-mutate\n/config.toml\n/registry/\n"
  },
  {
    "path": "third-party/.gitignore",
    "content": "/target/\n/vendor/\n"
  },
  {
    "path": "third-party/BUCK",
    "content": "# @generated by `reindeer buckify`\n\nload(\"@prelude//rust:cargo_buildscript.bzl\", \"buildscript_run\")\nload(\"@prelude//rust:cargo_package.bzl\", \"cargo\")\n\nhttp_archive(\n    name = \"anstyle-1.0.13.crate\",\n    sha256 = \"5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78\",\n    strip_prefix = \"anstyle-1.0.13\",\n    urls = [\"https://static.crates.io/crates/anstyle/1.0.13/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"anstyle-1.0.13\",\n    srcs = [\":anstyle-1.0.13.crate\"],\n    crate = \"anstyle\",\n    crate_root = \"anstyle-1.0.13.crate/src/lib.rs\",\n    edition = \"2021\",\n    features = [\n        \"default\",\n        \"std\",\n    ],\n    visibility = [],\n)\n\nalias(\n    name = \"cc\",\n    actual = \":cc-1.2.53\",\n    visibility = [\"PUBLIC\"],\n)\n\nhttp_archive(\n    name = \"cc-1.2.53.crate\",\n    sha256 = \"755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932\",\n    strip_prefix = \"cc-1.2.53\",\n    urls = [\"https://static.crates.io/crates/cc/1.2.53/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"cc-1.2.53\",\n    srcs = [\":cc-1.2.53.crate\"],\n    crate = \"cc\",\n    crate_root = \"cc-1.2.53.crate/src/lib.rs\",\n    edition = \"2018\",\n    visibility = [],\n    deps = [\n        \":find-msvc-tools-0.1.8\",\n        \":shlex-1.3.0\",\n    ],\n)\n\nalias(\n    name = \"clap\",\n    actual = \":clap-4.5.54\",\n    visibility = [\"PUBLIC\"],\n)\n\nhttp_archive(\n    name = \"clap-4.5.54.crate\",\n    sha256 = \"c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394\",\n    strip_prefix = \"clap-4.5.54\",\n    urls = [\"https://static.crates.io/crates/clap/4.5.54/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"clap-4.5.54\",\n    srcs = [\":clap-4.5.54.crate\"],\n    crate = \"clap\",\n    crate_root = \"clap-4.5.54.crate/src/lib.rs\",\n    edition = \"2021\",\n    features = [\n        \"error-context\",\n        \"help\",\n        \"std\",\n        \"usage\",\n    ],\n    visibility = [],\n    deps = [\":clap_builder-4.5.54\"],\n)\n\nhttp_archive(\n    name = \"clap_builder-4.5.54.crate\",\n    sha256 = \"fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00\",\n    strip_prefix = \"clap_builder-4.5.54\",\n    urls = [\"https://static.crates.io/crates/clap_builder/4.5.54/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"clap_builder-4.5.54\",\n    srcs = [\":clap_builder-4.5.54.crate\"],\n    crate = \"clap_builder\",\n    crate_root = \"clap_builder-4.5.54.crate/src/lib.rs\",\n    edition = \"2021\",\n    features = [\n        \"error-context\",\n        \"help\",\n        \"std\",\n        \"usage\",\n    ],\n    visibility = [],\n    deps = [\n        \":anstyle-1.0.13\",\n        \":clap_lex-0.7.7\",\n    ],\n)\n\nhttp_archive(\n    name = \"clap_lex-0.7.7.crate\",\n    sha256 = \"c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32\",\n    strip_prefix = \"clap_lex-0.7.7\",\n    urls = [\"https://static.crates.io/crates/clap_lex/0.7.7/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"clap_lex-0.7.7\",\n    srcs = [\":clap_lex-0.7.7.crate\"],\n    crate = \"clap_lex\",\n    crate_root = \"clap_lex-0.7.7.crate/src/lib.rs\",\n    edition = \"2021\",\n    visibility = [],\n)\n\nalias(\n    name = \"codespan-reporting\",\n    actual = \":codespan-reporting-0.13.1\",\n    visibility = [\"PUBLIC\"],\n)\n\nhttp_archive(\n    name = \"codespan-reporting-0.13.1.crate\",\n    sha256 = \"af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681\",\n    strip_prefix = \"codespan-reporting-0.13.1\",\n    urls = [\"https://static.crates.io/crates/codespan-reporting/0.13.1/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"codespan-reporting-0.13.1\",\n    srcs = [\":codespan-reporting-0.13.1.crate\"],\n    crate = \"codespan_reporting\",\n    crate_root = \"codespan-reporting-0.13.1.crate/src/lib.rs\",\n    edition = \"2021\",\n    features = [\n        \"default\",\n        \"std\",\n        \"termcolor\",\n    ],\n    visibility = [],\n    deps = [\n        \":termcolor-1.4.1\",\n        \":unicode-width-0.2.2\",\n    ],\n)\n\nhttp_archive(\n    name = \"equivalent-1.0.2.crate\",\n    sha256 = \"877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f\",\n    strip_prefix = \"equivalent-1.0.2\",\n    urls = [\"https://static.crates.io/crates/equivalent/1.0.2/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"equivalent-1.0.2\",\n    srcs = [\":equivalent-1.0.2.crate\"],\n    crate = \"equivalent\",\n    crate_root = \"equivalent-1.0.2.crate/src/lib.rs\",\n    edition = \"2015\",\n    visibility = [],\n)\n\nhttp_archive(\n    name = \"find-msvc-tools-0.1.8.crate\",\n    sha256 = \"8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db\",\n    strip_prefix = \"find-msvc-tools-0.1.8\",\n    urls = [\"https://static.crates.io/crates/find-msvc-tools/0.1.8/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"find-msvc-tools-0.1.8\",\n    srcs = [\":find-msvc-tools-0.1.8.crate\"],\n    crate = \"find_msvc_tools\",\n    crate_root = \"find-msvc-tools-0.1.8.crate/src/lib.rs\",\n    edition = \"2018\",\n    visibility = [],\n)\n\nalias(\n    name = \"foldhash\",\n    actual = \":foldhash-0.2.0\",\n    visibility = [\"PUBLIC\"],\n)\n\nhttp_archive(\n    name = \"foldhash-0.2.0.crate\",\n    sha256 = \"77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb\",\n    strip_prefix = \"foldhash-0.2.0\",\n    urls = [\"https://static.crates.io/crates/foldhash/0.2.0/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"foldhash-0.2.0\",\n    srcs = [\":foldhash-0.2.0.crate\"],\n    crate = \"foldhash\",\n    crate_root = \"foldhash-0.2.0.crate/src/lib.rs\",\n    edition = \"2021\",\n    features = [\n        \"default\",\n        \"std\",\n    ],\n    visibility = [],\n)\n\nhttp_archive(\n    name = \"hashbrown-0.16.1.crate\",\n    sha256 = \"841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100\",\n    strip_prefix = \"hashbrown-0.16.1\",\n    urls = [\"https://static.crates.io/crates/hashbrown/0.16.1/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"hashbrown-0.16.1\",\n    srcs = [\":hashbrown-0.16.1.crate\"],\n    crate = \"hashbrown\",\n    crate_root = \"hashbrown-0.16.1.crate/src/lib.rs\",\n    edition = \"2021\",\n    visibility = [],\n)\n\nalias(\n    name = \"indexmap\",\n    actual = \":indexmap-2.13.0\",\n    visibility = [\"PUBLIC\"],\n)\n\nhttp_archive(\n    name = \"indexmap-2.13.0.crate\",\n    sha256 = \"7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017\",\n    strip_prefix = \"indexmap-2.13.0\",\n    urls = [\"https://static.crates.io/crates/indexmap/2.13.0/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"indexmap-2.13.0\",\n    srcs = [\":indexmap-2.13.0.crate\"],\n    crate = \"indexmap\",\n    crate_root = \"indexmap-2.13.0.crate/src/lib.rs\",\n    edition = \"2021\",\n    features = [\n        \"default\",\n        \"std\",\n    ],\n    visibility = [],\n    deps = [\n        \":equivalent-1.0.2\",\n        \":hashbrown-0.16.1\",\n    ],\n)\n\nalias(\n    name = \"proc-macro2\",\n    actual = \":proc-macro2-1.0.105\",\n    visibility = [\"PUBLIC\"],\n)\n\nhttp_archive(\n    name = \"proc-macro2-1.0.105.crate\",\n    sha256 = \"535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7\",\n    strip_prefix = \"proc-macro2-1.0.105\",\n    urls = [\"https://static.crates.io/crates/proc-macro2/1.0.105/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"proc-macro2-1.0.105\",\n    srcs = [\":proc-macro2-1.0.105.crate\"],\n    crate = \"proc_macro2\",\n    crate_root = \"proc-macro2-1.0.105.crate/src/lib.rs\",\n    edition = \"2021\",\n    env = {\n        \"OUT_DIR\": \"$(location :proc-macro2-1.0.105-build-script-run[out_dir])\",\n    },\n    features = [\n        \"default\",\n        \"proc-macro\",\n        \"span-locations\",\n    ],\n    rustc_flags = [\"@$(location :proc-macro2-1.0.105-build-script-run[rustc_flags])\"],\n    visibility = [],\n    deps = [\":unicode-ident-1.0.22\"],\n)\n\ncargo.rust_binary(\n    name = \"proc-macro2-1.0.105-build-script-build\",\n    srcs = [\":proc-macro2-1.0.105.crate\"],\n    crate = \"build_script_build\",\n    crate_root = \"proc-macro2-1.0.105.crate/build.rs\",\n    edition = \"2021\",\n    features = [\n        \"default\",\n        \"proc-macro\",\n        \"span-locations\",\n    ],\n    visibility = [],\n)\n\nbuildscript_run(\n    name = \"proc-macro2-1.0.105-build-script-run\",\n    package_name = \"proc-macro2\",\n    buildscript_rule = \":proc-macro2-1.0.105-build-script-build\",\n    features = [\n        \"default\",\n        \"proc-macro\",\n        \"span-locations\",\n    ],\n    version = \"1.0.105\",\n)\n\nalias(\n    name = \"quote\",\n    actual = \":quote-1.0.43\",\n    visibility = [\"PUBLIC\"],\n)\n\nhttp_archive(\n    name = \"quote-1.0.43.crate\",\n    sha256 = \"dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a\",\n    strip_prefix = \"quote-1.0.43\",\n    urls = [\"https://static.crates.io/crates/quote/1.0.43/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"quote-1.0.43\",\n    srcs = [\":quote-1.0.43.crate\"],\n    crate = \"quote\",\n    crate_root = \"quote-1.0.43.crate/src/lib.rs\",\n    edition = \"2021\",\n    env = {\n        \"OUT_DIR\": \"$(location :quote-1.0.43-build-script-run[out_dir])\",\n    },\n    features = [\n        \"default\",\n        \"proc-macro\",\n    ],\n    rustc_flags = [\"@$(location :quote-1.0.43-build-script-run[rustc_flags])\"],\n    visibility = [],\n    deps = [\":proc-macro2-1.0.105\"],\n)\n\ncargo.rust_binary(\n    name = \"quote-1.0.43-build-script-build\",\n    srcs = [\":quote-1.0.43.crate\"],\n    crate = \"build_script_build\",\n    crate_root = \"quote-1.0.43.crate/build.rs\",\n    edition = \"2021\",\n    features = [\n        \"default\",\n        \"proc-macro\",\n    ],\n    visibility = [],\n)\n\nbuildscript_run(\n    name = \"quote-1.0.43-build-script-run\",\n    package_name = \"quote\",\n    buildscript_rule = \":quote-1.0.43-build-script-build\",\n    features = [\n        \"default\",\n        \"proc-macro\",\n    ],\n    version = \"1.0.43\",\n)\n\nalias(\n    name = \"rustversion\",\n    actual = \":rustversion-1.0.22\",\n    visibility = [\"PUBLIC\"],\n)\n\nhttp_archive(\n    name = \"rustversion-1.0.22.crate\",\n    sha256 = \"b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d\",\n    strip_prefix = \"rustversion-1.0.22\",\n    urls = [\"https://static.crates.io/crates/rustversion/1.0.22/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"rustversion-1.0.22\",\n    srcs = [\":rustversion-1.0.22.crate\"],\n    crate = \"rustversion\",\n    crate_root = \"rustversion-1.0.22.crate/src/lib.rs\",\n    edition = \"2018\",\n    env = {\n        \"OUT_DIR\": \"$(location :rustversion-1.0.22-build-script-run[out_dir])\",\n    },\n    proc_macro = True,\n    rustc_flags = [\"@$(location :rustversion-1.0.22-build-script-run[rustc_flags])\"],\n    visibility = [],\n)\n\ncargo.rust_binary(\n    name = \"rustversion-1.0.22-build-script-build\",\n    srcs = [\":rustversion-1.0.22.crate\"],\n    crate = \"build_script_build\",\n    crate_root = \"rustversion-1.0.22.crate/build/build.rs\",\n    edition = \"2018\",\n    visibility = [],\n)\n\nbuildscript_run(\n    name = \"rustversion-1.0.22-build-script-run\",\n    package_name = \"rustversion\",\n    buildscript_rule = \":rustversion-1.0.22-build-script-build\",\n    version = \"1.0.22\",\n)\n\nalias(\n    name = \"scratch\",\n    actual = \":scratch-1.0.9\",\n    visibility = [\"PUBLIC\"],\n)\n\nhttp_archive(\n    name = \"scratch-1.0.9.crate\",\n    sha256 = \"d68f2ec51b097e4c1a75b681a8bec621909b5e91f15bb7b840c4f2f7b01148b2\",\n    strip_prefix = \"scratch-1.0.9\",\n    urls = [\"https://static.crates.io/crates/scratch/1.0.9/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"scratch-1.0.9\",\n    srcs = [\":scratch-1.0.9.crate\"],\n    crate = \"scratch\",\n    crate_root = \"scratch-1.0.9.crate/src/lib.rs\",\n    edition = \"2015\",\n    env = {\n        \"OUT_DIR\": \"$(location :scratch-1.0.9-build-script-run[out_dir])\",\n    },\n    rustc_flags = [\"@$(location :scratch-1.0.9-build-script-run[rustc_flags])\"],\n    visibility = [],\n)\n\ncargo.rust_binary(\n    name = \"scratch-1.0.9-build-script-build\",\n    srcs = [\":scratch-1.0.9.crate\"],\n    crate = \"build_script_build\",\n    crate_root = \"scratch-1.0.9.crate/build.rs\",\n    edition = \"2015\",\n    visibility = [],\n)\n\nbuildscript_run(\n    name = \"scratch-1.0.9-build-script-run\",\n    package_name = \"scratch\",\n    buildscript_rule = \":scratch-1.0.9-build-script-build\",\n    version = \"1.0.9\",\n)\n\nalias(\n    name = \"serde\",\n    actual = \":serde-1.0.228\",\n    visibility = [\"PUBLIC\"],\n)\n\nhttp_archive(\n    name = \"serde-1.0.228.crate\",\n    sha256 = \"9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e\",\n    strip_prefix = \"serde-1.0.228\",\n    urls = [\"https://static.crates.io/crates/serde/1.0.228/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"serde-1.0.228\",\n    srcs = [\":serde-1.0.228.crate\"],\n    crate = \"serde\",\n    crate_root = \"serde-1.0.228.crate/src/lib.rs\",\n    edition = \"2021\",\n    env = {\n        \"CARGO_PKG_VERSION_PATCH\": \"228\",\n        \"OUT_DIR\": \"$(location :serde-1.0.228-build-script-run[out_dir])\",\n    },\n    features = [\n        \"default\",\n        \"derive\",\n        \"serde_derive\",\n        \"std\",\n    ],\n    rustc_flags = [\"@$(location :serde-1.0.228-build-script-run[rustc_flags])\"],\n    visibility = [],\n    deps = [\n        \":serde_core-1.0.228\",\n        \":serde_derive-1.0.228\",\n    ],\n)\n\ncargo.rust_binary(\n    name = \"serde-1.0.228-build-script-build\",\n    srcs = [\":serde-1.0.228.crate\"],\n    crate = \"build_script_build\",\n    crate_root = \"serde-1.0.228.crate/build.rs\",\n    edition = \"2021\",\n    env = {\n        \"CARGO_PKG_VERSION_PATCH\": \"228\",\n    },\n    features = [\n        \"default\",\n        \"derive\",\n        \"serde_derive\",\n        \"std\",\n    ],\n    visibility = [],\n)\n\nbuildscript_run(\n    name = \"serde-1.0.228-build-script-run\",\n    package_name = \"serde\",\n    buildscript_rule = \":serde-1.0.228-build-script-build\",\n    env = {\n        \"CARGO_PKG_VERSION_PATCH\": \"228\",\n    },\n    features = [\n        \"default\",\n        \"derive\",\n        \"serde_derive\",\n        \"std\",\n    ],\n    version = \"1.0.228\",\n)\n\nhttp_archive(\n    name = \"serde_core-1.0.228.crate\",\n    sha256 = \"41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad\",\n    strip_prefix = \"serde_core-1.0.228\",\n    urls = [\"https://static.crates.io/crates/serde_core/1.0.228/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"serde_core-1.0.228\",\n    srcs = [\":serde_core-1.0.228.crate\"],\n    crate = \"serde_core\",\n    crate_root = \"serde_core-1.0.228.crate/src/lib.rs\",\n    edition = \"2021\",\n    env = {\n        \"CARGO_PKG_VERSION_PATCH\": \"228\",\n        \"OUT_DIR\": \"$(location :serde_core-1.0.228-build-script-run[out_dir])\",\n    },\n    features = [\n        \"result\",\n        \"std\",\n    ],\n    rustc_flags = [\"@$(location :serde_core-1.0.228-build-script-run[rustc_flags])\"],\n    visibility = [],\n)\n\ncargo.rust_binary(\n    name = \"serde_core-1.0.228-build-script-build\",\n    srcs = [\":serde_core-1.0.228.crate\"],\n    crate = \"build_script_build\",\n    crate_root = \"serde_core-1.0.228.crate/build.rs\",\n    edition = \"2021\",\n    env = {\n        \"CARGO_PKG_VERSION_PATCH\": \"228\",\n    },\n    features = [\n        \"result\",\n        \"std\",\n    ],\n    visibility = [],\n)\n\nbuildscript_run(\n    name = \"serde_core-1.0.228-build-script-run\",\n    package_name = \"serde_core\",\n    buildscript_rule = \":serde_core-1.0.228-build-script-build\",\n    env = {\n        \"CARGO_PKG_VERSION_PATCH\": \"228\",\n    },\n    features = [\n        \"result\",\n        \"std\",\n    ],\n    version = \"1.0.228\",\n)\n\nhttp_archive(\n    name = \"serde_derive-1.0.228.crate\",\n    sha256 = \"d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79\",\n    strip_prefix = \"serde_derive-1.0.228\",\n    urls = [\"https://static.crates.io/crates/serde_derive/1.0.228/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"serde_derive-1.0.228\",\n    srcs = [\":serde_derive-1.0.228.crate\"],\n    crate = \"serde_derive\",\n    crate_root = \"serde_derive-1.0.228.crate/src/lib.rs\",\n    edition = \"2021\",\n    env = {\n        \"CARGO_PKG_VERSION_PATCH\": \"228\",\n    },\n    features = [\"default\"],\n    proc_macro = True,\n    visibility = [],\n    deps = [\n        \":proc-macro2-1.0.105\",\n        \":quote-1.0.43\",\n        \":syn-2.0.114\",\n    ],\n)\n\nhttp_archive(\n    name = \"shlex-1.3.0.crate\",\n    sha256 = \"0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64\",\n    strip_prefix = \"shlex-1.3.0\",\n    urls = [\"https://static.crates.io/crates/shlex/1.3.0/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"shlex-1.3.0\",\n    srcs = [\":shlex-1.3.0.crate\"],\n    crate = \"shlex\",\n    crate_root = \"shlex-1.3.0.crate/src/lib.rs\",\n    edition = \"2015\",\n    features = [\n        \"default\",\n        \"std\",\n    ],\n    visibility = [],\n)\n\nalias(\n    name = \"syn\",\n    actual = \":syn-2.0.114\",\n    visibility = [\"PUBLIC\"],\n)\n\nhttp_archive(\n    name = \"syn-2.0.114.crate\",\n    sha256 = \"d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a\",\n    strip_prefix = \"syn-2.0.114\",\n    urls = [\"https://static.crates.io/crates/syn/2.0.114/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"syn-2.0.114\",\n    srcs = [\":syn-2.0.114.crate\"],\n    crate = \"syn\",\n    crate_root = \"syn-2.0.114.crate/src/lib.rs\",\n    edition = \"2021\",\n    features = [\n        \"clone-impls\",\n        \"default\",\n        \"derive\",\n        \"full\",\n        \"parsing\",\n        \"printing\",\n        \"proc-macro\",\n    ],\n    visibility = [],\n    deps = [\n        \":proc-macro2-1.0.105\",\n        \":quote-1.0.43\",\n        \":unicode-ident-1.0.22\",\n    ],\n)\n\nhttp_archive(\n    name = \"termcolor-1.4.1.crate\",\n    sha256 = \"06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755\",\n    strip_prefix = \"termcolor-1.4.1\",\n    urls = [\"https://static.crates.io/crates/termcolor/1.4.1/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"termcolor-1.4.1\",\n    srcs = [\":termcolor-1.4.1.crate\"],\n    crate = \"termcolor\",\n    crate_root = \"termcolor-1.4.1.crate/src/lib.rs\",\n    edition = \"2018\",\n    platform = {\n        \"windows-gnu\": dict(\n            deps = [\":winapi-util-0.1.11\"],\n        ),\n        \"windows-msvc\": dict(\n            deps = [\":winapi-util-0.1.11\"],\n        ),\n    },\n    visibility = [],\n)\n\nhttp_archive(\n    name = \"unicode-ident-1.0.22.crate\",\n    sha256 = \"9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5\",\n    strip_prefix = \"unicode-ident-1.0.22\",\n    urls = [\"https://static.crates.io/crates/unicode-ident/1.0.22/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"unicode-ident-1.0.22\",\n    srcs = [\":unicode-ident-1.0.22.crate\"],\n    crate = \"unicode_ident\",\n    crate_root = \"unicode-ident-1.0.22.crate/src/lib.rs\",\n    edition = \"2018\",\n    visibility = [],\n)\n\nhttp_archive(\n    name = \"unicode-width-0.2.2.crate\",\n    sha256 = \"b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254\",\n    strip_prefix = \"unicode-width-0.2.2\",\n    urls = [\"https://static.crates.io/crates/unicode-width/0.2.2/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"unicode-width-0.2.2\",\n    srcs = [\":unicode-width-0.2.2.crate\"],\n    crate = \"unicode_width\",\n    crate_root = \"unicode-width-0.2.2.crate/src/lib.rs\",\n    edition = \"2021\",\n    features = [\n        \"cjk\",\n        \"default\",\n    ],\n    visibility = [],\n)\n\nhttp_archive(\n    name = \"winapi-util-0.1.11.crate\",\n    sha256 = \"c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22\",\n    strip_prefix = \"winapi-util-0.1.11\",\n    urls = [\"https://static.crates.io/crates/winapi-util/0.1.11/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"winapi-util-0.1.11\",\n    srcs = [\":winapi-util-0.1.11.crate\"],\n    crate = \"winapi_util\",\n    crate_root = \"winapi-util-0.1.11.crate/src/lib.rs\",\n    edition = \"2021\",\n    target_compatible_with = [\"prelude//os:windows\"],\n    visibility = [],\n    deps = [\":windows-sys-0.61.2\"],\n)\n\nhttp_archive(\n    name = \"windows-link-0.2.1.crate\",\n    sha256 = \"f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5\",\n    strip_prefix = \"windows-link-0.2.1\",\n    urls = [\"https://static.crates.io/crates/windows-link/0.2.1/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"windows-link-0.2.1\",\n    srcs = [\":windows-link-0.2.1.crate\"],\n    crate = \"windows_link\",\n    crate_root = \"windows-link-0.2.1.crate/src/lib.rs\",\n    edition = \"2021\",\n    visibility = [],\n)\n\nhttp_archive(\n    name = \"windows-sys-0.61.2.crate\",\n    sha256 = \"ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc\",\n    strip_prefix = \"windows-sys-0.61.2\",\n    urls = [\"https://static.crates.io/crates/windows-sys/0.61.2/download\"],\n    visibility = [],\n)\n\ncargo.rust_library(\n    name = \"windows-sys-0.61.2\",\n    srcs = [\":windows-sys-0.61.2.crate\"],\n    crate = \"windows_sys\",\n    crate_root = \"windows-sys-0.61.2.crate/src/lib.rs\",\n    edition = \"2021\",\n    features = [\n        \"Win32\",\n        \"Win32_Foundation\",\n        \"Win32_Storage\",\n        \"Win32_Storage_FileSystem\",\n        \"Win32_System\",\n        \"Win32_System_Console\",\n        \"Win32_System_SystemInformation\",\n        \"default\",\n    ],\n    target_compatible_with = [\"prelude//os:windows\"],\n    visibility = [],\n    deps = [\":windows-link-0.2.1\"],\n)\n"
  },
  {
    "path": "third-party/BUILD.bazel",
    "content": "load(\"@rules_rust//crate_universe:defs.bzl\", \"crates_vendor\")\n\ncrates_vendor(\n    name = \"vendor\",\n    cargo_lockfile = \"//third-party:Cargo.lock\",\n    generate_build_scripts = True,\n    manifests = [\"//third-party:Cargo.toml\"],\n    mode = \"remote\",\n    tags = [\"manual\"],\n    vendor_path = \"bazel\",\n)\n"
  },
  {
    "path": "third-party/Cargo.toml",
    "content": "[workspace]\n[package]\nname = \"third-party\"\nversion = \"0.0.0\"\nedition = \"2021\"\npublish = false\nrust-version = \"1.85\"\n\n[dependencies]\ncc = \"1.0.101\"\nclap = { version = \"4\", default-features = false, features = [\"error-context\", \"help\", \"std\", \"usage\"] }\ncodespan-reporting = \"0.13.1\"\nfoldhash = \"0.2\"\nindexmap = \"2.9.0\"\nproc-macro2 = { version = \"1.0.58\", features = [\"span-locations\"] }\nquote = \"1.0.4\"\nrustversion = \"1\"\nscratch = \"1\"\nserde = { version = \"1\", features = [\"derive\"] }\nsyn = { version = \"2.0.1\", features = [\"full\"] }\n"
  },
  {
    "path": "third-party/bazel/BUILD.anstyle-1.0.13.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"anstyle\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"default\",\n        \"std\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=anstyle\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.0.13\",\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files(\n    [\n        \"cargo-bazel.json\",\n        \"crates.bzl\",\n        \"defs.bzl\",\n    ] + glob(\n        include = [\"*.bazel\"],\n        allow_empty = True,\n    ),\n)\n\nfilegroup(\n    name = \"srcs\",\n    srcs = glob(\n        include = [\n            \"*.bazel\",\n            \"*.bzl\",\n        ],\n        allow_empty = True,\n    ),\n)\n\n# Workspace Member Dependencies\nalias(\n    name = \"cc-1.2.53\",\n    actual = \"@vendor__cc-1.2.53//:cc\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"cc\",\n    actual = \"@vendor__cc-1.2.53//:cc\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"clap-4.5.54\",\n    actual = \"@vendor__clap-4.5.54//:clap\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"clap\",\n    actual = \"@vendor__clap-4.5.54//:clap\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"codespan-reporting-0.13.1\",\n    actual = \"@vendor__codespan-reporting-0.13.1//:codespan_reporting\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"codespan-reporting\",\n    actual = \"@vendor__codespan-reporting-0.13.1//:codespan_reporting\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"foldhash-0.2.0\",\n    actual = \"@vendor__foldhash-0.2.0//:foldhash\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"foldhash\",\n    actual = \"@vendor__foldhash-0.2.0//:foldhash\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"indexmap-2.13.0\",\n    actual = \"@vendor__indexmap-2.13.0//:indexmap\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"indexmap\",\n    actual = \"@vendor__indexmap-2.13.0//:indexmap\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"proc-macro2-1.0.105\",\n    actual = \"@vendor__proc-macro2-1.0.105//:proc_macro2\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"proc-macro2\",\n    actual = \"@vendor__proc-macro2-1.0.105//:proc_macro2\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"quote-1.0.43\",\n    actual = \"@vendor__quote-1.0.43//:quote\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"quote\",\n    actual = \"@vendor__quote-1.0.43//:quote\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"rustversion-1.0.22\",\n    actual = \"@vendor__rustversion-1.0.22//:rustversion\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"rustversion\",\n    actual = \"@vendor__rustversion-1.0.22//:rustversion\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"scratch-1.0.9\",\n    actual = \"@vendor__scratch-1.0.9//:scratch\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"scratch\",\n    actual = \"@vendor__scratch-1.0.9//:scratch\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"serde-1.0.228\",\n    actual = \"@vendor__serde-1.0.228//:serde\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"serde\",\n    actual = \"@vendor__serde-1.0.228//:serde\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"syn-2.0.114\",\n    actual = \"@vendor__syn-2.0.114//:syn\",\n    tags = [\"manual\"],\n)\n\nalias(\n    name = \"syn\",\n    actual = \"@vendor__syn-2.0.114//:syn\",\n    tags = [\"manual\"],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.cc-1.2.53.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"cc\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_root = \"src/lib.rs\",\n    edition = \"2018\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=cc\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.2.53\",\n    deps = [\n        \"@vendor__find-msvc-tools-0.1.8//:find_msvc_tools\",\n        \"@vendor__shlex-1.3.0//:shlex\",\n    ],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.clap-4.5.54.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"clap\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"error-context\",\n        \"help\",\n        \"std\",\n        \"usage\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=clap\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"4.5.54\",\n    deps = [\n        \"@vendor__clap_builder-4.5.54//:clap_builder\",\n    ],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.clap_builder-4.5.54.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"clap_builder\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"error-context\",\n        \"help\",\n        \"std\",\n        \"usage\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=clap_builder\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"4.5.54\",\n    deps = [\n        \"@vendor__anstyle-1.0.13//:anstyle\",\n        \"@vendor__clap_lex-0.7.7//:clap_lex\",\n    ],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.clap_lex-0.7.7.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"clap_lex\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=clap_lex\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"0.7.7\",\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.codespan-reporting-0.13.1.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"codespan_reporting\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"default\",\n        \"std\",\n        \"termcolor\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=codespan-reporting\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"0.13.1\",\n    deps = [\n        \"@vendor__termcolor-1.4.1//:termcolor\",\n        \"@vendor__unicode-width-0.2.2//:unicode_width\",\n    ],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.equivalent-1.0.2.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"equivalent\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_root = \"src/lib.rs\",\n    edition = \"2015\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=equivalent\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.0.2\",\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.find-msvc-tools-0.1.8.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"find_msvc_tools\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_root = \"src/lib.rs\",\n    edition = \"2018\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=find-msvc-tools\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"0.1.8\",\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.foldhash-0.2.0.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"foldhash\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"default\",\n        \"std\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=foldhash\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"0.2.0\",\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.hashbrown-0.16.1.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"hashbrown\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=hashbrown\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"0.16.1\",\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.indexmap-2.13.0.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"indexmap\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"default\",\n        \"std\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=indexmap\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"2.13.0\",\n    deps = [\n        \"@vendor__equivalent-1.0.2//:equivalent\",\n        \"@vendor__hashbrown-0.16.1//:hashbrown\",\n    ],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.proc-macro2-1.0.105.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\n    \"@rules_rust//cargo:defs.bzl\",\n    \"cargo_build_script\",\n    \"cargo_toml_env_vars\",\n)\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"proc_macro2\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"default\",\n        \"proc-macro\",\n        \"span-locations\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=proc-macro2\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.0.105\",\n    deps = [\n        \"@vendor__proc-macro2-1.0.105//:build_script_build\",\n        \"@vendor__unicode-ident-1.0.22//:unicode_ident\",\n    ],\n)\n\ncargo_build_script(\n    name = \"_bs\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \"**/*.rs\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"default\",\n        \"proc-macro\",\n        \"span-locations\",\n    ],\n    crate_name = \"build_script_build\",\n    crate_root = \"build.rs\",\n    data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    edition = \"2021\",\n    pkg_name = \"proc-macro2\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=proc-macro2\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    version = \"1.0.105\",\n    visibility = [\"//visibility:private\"],\n)\n\nalias(\n    name = \"build_script_build\",\n    actual = \":_bs\",\n    tags = [\"manual\"],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.quote-1.0.43.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\n    \"@rules_rust//cargo:defs.bzl\",\n    \"cargo_build_script\",\n    \"cargo_toml_env_vars\",\n)\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"quote\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"default\",\n        \"proc-macro\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=quote\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.0.43\",\n    deps = [\n        \"@vendor__proc-macro2-1.0.105//:proc_macro2\",\n        \"@vendor__quote-1.0.43//:build_script_build\",\n    ],\n)\n\ncargo_build_script(\n    name = \"_bs\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \"**/*.rs\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"default\",\n        \"proc-macro\",\n    ],\n    crate_name = \"build_script_build\",\n    crate_root = \"build.rs\",\n    data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    edition = \"2021\",\n    pkg_name = \"quote\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=quote\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    version = \"1.0.43\",\n    visibility = [\"//visibility:private\"],\n)\n\nalias(\n    name = \"build_script_build\",\n    actual = \":_bs\",\n    tags = [\"manual\"],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.rustversion-1.0.22.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\n    \"@rules_rust//cargo:defs.bzl\",\n    \"cargo_build_script\",\n    \"cargo_toml_env_vars\",\n)\nload(\"@rules_rust//rust:defs.bzl\", \"rust_proc_macro\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_proc_macro(\n    name = \"rustversion\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_root = \"src/lib.rs\",\n    edition = \"2018\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=rustversion\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.0.22\",\n    deps = [\n        \"@vendor__rustversion-1.0.22//:build_script_build\",\n    ],\n)\n\ncargo_build_script(\n    name = \"_bs\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \"**/*.rs\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_name = \"build_script_build\",\n    crate_root = \"build/build.rs\",\n    data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    edition = \"2018\",\n    pkg_name = \"rustversion\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=rustversion\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    version = \"1.0.22\",\n    visibility = [\"//visibility:private\"],\n)\n\nalias(\n    name = \"build_script_build\",\n    actual = \":_bs\",\n    tags = [\"manual\"],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.scratch-1.0.9.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\n    \"@rules_rust//cargo:defs.bzl\",\n    \"cargo_build_script\",\n    \"cargo_toml_env_vars\",\n)\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"scratch\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_root = \"src/lib.rs\",\n    edition = \"2015\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=scratch\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.0.9\",\n    deps = [\n        \"@vendor__scratch-1.0.9//:build_script_build\",\n    ],\n)\n\ncargo_build_script(\n    name = \"_bs\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \"**/*.rs\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_name = \"build_script_build\",\n    crate_root = \"build.rs\",\n    data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    edition = \"2015\",\n    pkg_name = \"scratch\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=scratch\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    version = \"1.0.9\",\n    visibility = [\"//visibility:private\"],\n)\n\nalias(\n    name = \"build_script_build\",\n    actual = \":_bs\",\n    tags = [\"manual\"],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.serde-1.0.228.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\n    \"@rules_rust//cargo:defs.bzl\",\n    \"cargo_build_script\",\n    \"cargo_toml_env_vars\",\n)\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"serde\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"default\",\n        \"derive\",\n        \"serde_derive\",\n        \"std\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    proc_macro_deps = [\n        \"@vendor__serde_derive-1.0.228//:serde_derive\",\n    ],\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=serde\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.0.228\",\n    deps = [\n        \"@vendor__serde-1.0.228//:build_script_build\",\n        \"@vendor__serde_core-1.0.228//:serde_core\",\n    ],\n)\n\ncargo_build_script(\n    name = \"_bs\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \"**/*.rs\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"default\",\n        \"derive\",\n        \"serde_derive\",\n        \"std\",\n    ],\n    crate_name = \"build_script_build\",\n    crate_root = \"build.rs\",\n    data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    edition = \"2021\",\n    pkg_name = \"serde\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=serde\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    version = \"1.0.228\",\n    visibility = [\"//visibility:private\"],\n)\n\nalias(\n    name = \"build_script_build\",\n    actual = \":_bs\",\n    tags = [\"manual\"],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.serde_core-1.0.228.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\n    \"@rules_rust//cargo:defs.bzl\",\n    \"cargo_build_script\",\n    \"cargo_toml_env_vars\",\n)\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"serde_core\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"result\",\n        \"std\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=serde_core\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.0.228\",\n    deps = [\n        \"@vendor__serde_core-1.0.228//:build_script_build\",\n    ],\n)\n\ncargo_build_script(\n    name = \"_bs\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \"**/*.rs\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"result\",\n        \"std\",\n    ],\n    crate_name = \"build_script_build\",\n    crate_root = \"build.rs\",\n    data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    edition = \"2021\",\n    pkg_name = \"serde_core\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=serde_core\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    version = \"1.0.228\",\n    visibility = [\"//visibility:private\"],\n)\n\nalias(\n    name = \"build_script_build\",\n    actual = \":_bs\",\n    tags = [\"manual\"],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.serde_derive-1.0.228.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_proc_macro\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_proc_macro(\n    name = \"serde_derive\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"default\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=serde_derive\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.0.228\",\n    deps = [\n        \"@vendor__proc-macro2-1.0.105//:proc_macro2\",\n        \"@vendor__quote-1.0.43//:quote\",\n        \"@vendor__syn-2.0.114//:syn\",\n    ],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.shlex-1.3.0.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"shlex\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"default\",\n        \"std\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2015\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=shlex\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.3.0\",\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.syn-2.0.114.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"syn\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"clone-impls\",\n        \"default\",\n        \"derive\",\n        \"full\",\n        \"parsing\",\n        \"printing\",\n        \"proc-macro\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=syn\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"2.0.114\",\n    deps = [\n        \"@vendor__proc-macro2-1.0.105//:proc_macro2\",\n        \"@vendor__quote-1.0.43//:quote\",\n        \"@vendor__unicode-ident-1.0.22//:unicode_ident\",\n    ],\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.termcolor-1.4.1.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"termcolor\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_root = \"src/lib.rs\",\n    edition = \"2018\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=termcolor\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.4.1\",\n    deps = select({\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [\n            \"@vendor__winapi-util-0.1.11//:winapi_util\",  # cfg(windows)\n        ],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [\n            \"@vendor__winapi-util-0.1.11//:winapi_util\",  # cfg(windows)\n        ],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [\n            \"@vendor__winapi-util-0.1.11//:winapi_util\",  # cfg(windows)\n        ],\n        \"//conditions:default\": [],\n    }),\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.unicode-ident-1.0.22.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"unicode_ident\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_root = \"src/lib.rs\",\n    edition = \"2018\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=unicode-ident\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"1.0.22\",\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.unicode-width-0.2.2.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"unicode_width\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"cjk\",\n        \"default\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=unicode-width\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"0.2.2\",\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.winapi-util-0.1.11.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"winapi_util\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=winapi-util\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"0.1.11\",\n    deps = select({\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [\n            \"@vendor__windows-sys-0.61.2//:windows_sys\",  # cfg(windows)\n        ],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [\n            \"@vendor__windows-sys-0.61.2//:windows_sys\",  # cfg(windows)\n        ],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [\n            \"@vendor__windows-sys-0.61.2//:windows_sys\",  # cfg(windows)\n        ],\n        \"//conditions:default\": [],\n    }),\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.windows-link-0.2.1.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"windows_link\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=windows-link\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"0.2.1\",\n)\n"
  },
  {
    "path": "third-party/bazel/BUILD.windows-sys-0.61.2.bazel",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n    name = \"cargo_toml_env_vars\",\n    src = \"Cargo.toml\",\n)\n\nrust_library(\n    name = \"windows_sys\",\n    srcs = glob(\n        include = [\"**/*.rs\"],\n        allow_empty = True,\n    ),\n    compile_data = glob(\n        include = [\"**\"],\n        allow_empty = True,\n        exclude = [\n            \"**/* *\",\n            \".tmp_git_root/**/*\",\n            \"BUILD\",\n            \"BUILD.bazel\",\n            \"WORKSPACE\",\n            \"WORKSPACE.bazel\",\n        ],\n    ),\n    crate_features = [\n        \"Win32\",\n        \"Win32_Foundation\",\n        \"Win32_Storage\",\n        \"Win32_Storage_FileSystem\",\n        \"Win32_System\",\n        \"Win32_System_Console\",\n        \"Win32_System_SystemInformation\",\n        \"default\",\n    ],\n    crate_root = \"src/lib.rs\",\n    edition = \"2021\",\n    rustc_env_files = [\n        \":cargo_toml_env_vars\",\n    ],\n    rustc_flags = [\n        \"--cap-lints=allow\",\n    ],\n    tags = [\n        \"cargo-bazel\",\n        \"crate-name=windows-sys\",\n        \"manual\",\n        \"noclippy\",\n        \"norustfmt\",\n    ],\n    target_compatible_with = select({\n        \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios\": [],\n        \"@rules_rust//rust/platform:aarch64-apple-ios-sim\": [],\n        \"@rules_rust//rust/platform:aarch64-linux-android\": [],\n        \"@rules_rust//rust/platform:aarch64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\": [],\n        \"@rules_rust//rust/platform:aarch64-unknown-uefi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:arm-unknown-linux-musleabi\": [],\n        \"@rules_rust//rust/platform:armv7-linux-androideabi\": [],\n        \"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\": [],\n        \"@rules_rust//rust/platform:i686-apple-darwin\": [],\n        \"@rules_rust//rust/platform:i686-linux-android\": [],\n        \"@rules_rust//rust/platform:i686-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:i686-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:i686-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\": [],\n        \"@rules_rust//rust/platform:s390x-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:thumbv7em-none-eabi\": [],\n        \"@rules_rust//rust/platform:thumbv8m.main-none-eabi\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-emscripten\": [],\n        \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip1-threads\": [],\n        \"@rules_rust//rust/platform:wasm32-wasip2\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-darwin\": [],\n        \"@rules_rust//rust/platform:x86_64-apple-ios\": [],\n        \"@rules_rust//rust/platform:x86_64-linux-android\": [],\n        \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-freebsd\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-fuchsia\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-none\": [],\n        \"@rules_rust//rust/platform:x86_64-unknown-uefi\": [],\n        \"//conditions:default\": [\"@platforms//:incompatible\"],\n    }),\n    version = \"0.61.2\",\n    deps = [\n        \"@vendor__windows-link-0.2.1//:windows_link\",\n    ],\n)\n"
  },
  {
    "path": "third-party/bazel/alias_rules.bzl",
    "content": "\"\"\"Alias that transitions its target to `compilation_mode=opt`.  Use `transition_alias=\"opt\"` to enable.\"\"\"\n\nload(\"@rules_cc//cc:defs.bzl\", \"CcInfo\")\nload(\"@rules_rust//rust:rust_common.bzl\", \"COMMON_PROVIDERS\")\n\ndef _transition_alias_impl(ctx):\n    # `ctx.attr.actual` is a list of 1 item due to the transition\n    providers = [ctx.attr.actual[0][provider] for provider in COMMON_PROVIDERS]\n    if CcInfo in ctx.attr.actual[0]:\n        providers.append(ctx.attr.actual[0][CcInfo])\n    return providers\n\ndef _change_compilation_mode(compilation_mode):\n    def _change_compilation_mode_impl(_settings, _attr):\n        return {\n            \"//command_line_option:compilation_mode\": compilation_mode,\n        }\n\n    return transition(\n        implementation = _change_compilation_mode_impl,\n        inputs = [],\n        outputs = [\n            \"//command_line_option:compilation_mode\",\n        ],\n    )\n\ndef _transition_alias_rule(compilation_mode):\n    return rule(\n        implementation = _transition_alias_impl,\n        provides = COMMON_PROVIDERS,\n        attrs = {\n            \"actual\": attr.label(\n                mandatory = True,\n                doc = \"`rust_library()` target to transition to `compilation_mode=opt`.\",\n                providers = COMMON_PROVIDERS,\n                cfg = _change_compilation_mode(compilation_mode),\n            ),\n            \"_allowlist_function_transition\": attr.label(\n                default = \"@bazel_tools//tools/allowlists/function_transition_allowlist\",\n            ),\n        },\n        doc = \"Transitions a Rust library crate to the `compilation_mode=opt`.\",\n    )\n\ntransition_alias_dbg = _transition_alias_rule(\"dbg\")\ntransition_alias_fastbuild = _transition_alias_rule(\"fastbuild\")\ntransition_alias_opt = _transition_alias_rule(\"opt\")\n"
  },
  {
    "path": "third-party/bazel/crates.bzl",
    "content": "###############################################################################\n# @generated\n# This file is auto-generated by the cargo-bazel tool.\n#\n# DO NOT MODIFY: Local changes may be replaced in future executions.\n###############################################################################\n\"\"\"Rules for defining repositories for remote `crates_vendor` repositories\"\"\"\n\nload(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:crates_vendor.bzl\", \"crates_vendor_remote_repository\")\n\n# buildifier: disable=bzl-visibility\nload(\"//third-party/bazel:defs.bzl\", _crate_repositories = \"crate_repositories\")\n\ndef crate_repositories():\n    \"\"\"Generates repositories for vendored crates.\n\n    Returns:\n      A list of repos visible to the module through the module extension.\n    \"\"\"\n    maybe(\n        crates_vendor_remote_repository,\n        name = \"vendor\",\n        build_file = Label(\"//third-party/bazel:BUILD.bazel\"),\n        defs_module = Label(\"//third-party/bazel:defs.bzl\"),\n    )\n\n    direct_deps = [struct(repo = \"vendor\", is_dev_dep = False)]\n    direct_deps.extend(_crate_repositories())\n    return direct_deps\n"
  },
  {
    "path": "third-party/bazel/defs.bzl",
    "content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To\n# regenerate this file, run the following:\n#\n#     bazel run @@//third-party:vendor\n###############################################################################\n\"\"\"\n# `crates_repository` API\n\n- [aliases](#aliases)\n- [crate_deps](#crate_deps)\n- [all_crate_deps](#all_crate_deps)\n- [crate_repositories](#crate_repositories)\n\n\"\"\"\n\nload(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\nload(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")\n\n###############################################################################\n# MACROS API\n###############################################################################\n\n# An identifier that represent common dependencies (unconditional).\n_COMMON_CONDITION = \"\"\n\ndef _flatten_dependency_maps(all_dependency_maps):\n    \"\"\"Flatten a list of dependency maps into one dictionary.\n\n    Dependency maps have the following structure:\n\n    ```python\n    DEPENDENCIES_MAP = {\n        # The first key in the map is a Bazel package\n        # name of the workspace this file is defined in.\n        \"workspace_member_package\": {\n\n            # Not all dependencies are supported for all platforms.\n            # the condition key is the condition required to be true\n            # on the host platform.\n            \"condition\": {\n\n                # An alias to a crate target.     # The label of the crate target the\n                # Aliases are only crate names.   # package name refers to.\n                \"package_name\":                   \"@full//:label\",\n            }\n        }\n    }\n    ```\n\n    Args:\n        all_dependency_maps (list): A list of dicts as described above\n\n    Returns:\n        dict: A dictionary as described above\n    \"\"\"\n    dependencies = {}\n\n    for workspace_deps_map in all_dependency_maps:\n        for pkg_name, conditional_deps_map in workspace_deps_map.items():\n            if pkg_name not in dependencies:\n                non_frozen_map = dict()\n                for key, values in conditional_deps_map.items():\n                    non_frozen_map.update({key: dict(values.items())})\n                dependencies.setdefault(pkg_name, non_frozen_map)\n                continue\n\n            for condition, deps_map in conditional_deps_map.items():\n                # If the condition has not been recorded, do so and continue\n                if condition not in dependencies[pkg_name]:\n                    dependencies[pkg_name].setdefault(condition, dict(deps_map.items()))\n                    continue\n\n                # Alert on any miss-matched dependencies\n                inconsistent_entries = []\n                for crate_name, crate_label in deps_map.items():\n                    existing = dependencies[pkg_name][condition].get(crate_name)\n                    if existing and existing != crate_label:\n                        inconsistent_entries.append((crate_name, existing, crate_label))\n                    dependencies[pkg_name][condition].update({crate_name: crate_label})\n\n    return dependencies\n\ndef crate_deps(deps, package_name = None):\n    \"\"\"Finds the fully qualified label of the requested crates for the package where this macro is called.\n\n    Args:\n        deps (list): The desired list of crate targets.\n        package_name (str, optional): The package name of the set of dependencies to look up.\n            Defaults to `native.package_name()`.\n\n    Returns:\n        list: A list of labels to generated rust targets (str)\n    \"\"\"\n\n    if not deps:\n        return []\n\n    if package_name == None:\n        package_name = native.package_name()\n\n    # Join both sets of dependencies\n    dependencies = _flatten_dependency_maps([\n        _NORMAL_DEPENDENCIES,\n        _NORMAL_DEV_DEPENDENCIES,\n        _PROC_MACRO_DEPENDENCIES,\n        _PROC_MACRO_DEV_DEPENDENCIES,\n        _BUILD_DEPENDENCIES,\n        _BUILD_PROC_MACRO_DEPENDENCIES,\n    ]).pop(package_name, {})\n\n    # Combine all conditional packages so we can easily index over a flat list\n    # TODO: Perhaps this should actually return select statements and maintain\n    # the conditionals of the dependencies\n    flat_deps = {}\n    for deps_set in dependencies.values():\n        for crate_name, crate_label in deps_set.items():\n            flat_deps.update({crate_name: crate_label})\n\n    missing_crates = []\n    crate_targets = []\n    for crate_target in deps:\n        if crate_target not in flat_deps:\n            missing_crates.append(crate_target)\n        else:\n            crate_targets.append(flat_deps[crate_target])\n\n    if missing_crates:\n        fail(\"Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`\".format(\n            missing_crates,\n            package_name,\n            dependencies,\n        ))\n\n    return crate_targets\n\ndef all_crate_deps(\n        normal = False,\n        normal_dev = False,\n        proc_macro = False,\n        proc_macro_dev = False,\n        build = False,\n        build_proc_macro = False,\n        package_name = None):\n    \"\"\"Finds the fully qualified label of all requested direct crate dependencies \\\n    for the package where this macro is called.\n\n    If no parameters are set, all normal dependencies are returned. Setting any one flag will\n    otherwise impact the contents of the returned list.\n\n    Args:\n        normal (bool, optional): If True, normal dependencies are included in the\n            output list.\n        normal_dev (bool, optional): If True, normal dev dependencies will be\n            included in the output list.\n        proc_macro (bool, optional): If True, proc_macro dependencies are included\n            in the output list.\n        proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n            included in the output list.\n        build (bool, optional): If True, build dependencies are included\n            in the output list.\n        build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n            included in the output list.\n        package_name (str, optional): The package name of the set of dependencies to look up.\n            Defaults to `native.package_name()` when unset.\n\n    Returns:\n        list: A list of labels to generated rust targets (str)\n    \"\"\"\n\n    if package_name == None:\n        package_name = native.package_name()\n\n    # Determine the relevant maps to use\n    all_dependency_maps = []\n    if normal:\n        all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n    if normal_dev:\n        all_dependency_maps.append(_NORMAL_DEV_DEPENDENCIES)\n    if proc_macro:\n        all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES)\n    if proc_macro_dev:\n        all_dependency_maps.append(_PROC_MACRO_DEV_DEPENDENCIES)\n    if build:\n        all_dependency_maps.append(_BUILD_DEPENDENCIES)\n    if build_proc_macro:\n        all_dependency_maps.append(_BUILD_PROC_MACRO_DEPENDENCIES)\n\n    # Default to always using normal dependencies\n    if not all_dependency_maps:\n        all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n\n    dependencies = _flatten_dependency_maps(all_dependency_maps).pop(package_name, None)\n\n    if not dependencies:\n        if dependencies == None:\n            fail(\"Tried to get all_crate_deps for package \" + package_name + \" but that package had no Cargo.toml file\")\n        else:\n            return []\n\n    crate_deps = list(dependencies.pop(_COMMON_CONDITION, {}).values())\n    for condition, deps in dependencies.items():\n        crate_deps += selects.with_or({\n            tuple(_CONDITIONS[condition]): deps.values(),\n            \"//conditions:default\": [],\n        })\n\n    return crate_deps\n\ndef aliases(\n        normal = False,\n        normal_dev = False,\n        proc_macro = False,\n        proc_macro_dev = False,\n        build = False,\n        build_proc_macro = False,\n        package_name = None):\n    \"\"\"Produces a map of Crate alias names to their original label\n\n    If no dependency kinds are specified, `normal` and `proc_macro` are used by default.\n    Setting any one flag will otherwise determine the contents of the returned dict.\n\n    Args:\n        normal (bool, optional): If True, normal dependencies are included in the\n            output list.\n        normal_dev (bool, optional): If True, normal dev dependencies will be\n            included in the output list..\n        proc_macro (bool, optional): If True, proc_macro dependencies are included\n            in the output list.\n        proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n            included in the output list.\n        build (bool, optional): If True, build dependencies are included\n            in the output list.\n        build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n            included in the output list.\n        package_name (str, optional): The package name of the set of dependencies to look up.\n            Defaults to `native.package_name()` when unset.\n\n    Returns:\n        dict: The aliases of all associated packages\n    \"\"\"\n    if package_name == None:\n        package_name = native.package_name()\n\n    # Determine the relevant maps to use\n    all_aliases_maps = []\n    if normal:\n        all_aliases_maps.append(_NORMAL_ALIASES)\n    if normal_dev:\n        all_aliases_maps.append(_NORMAL_DEV_ALIASES)\n    if proc_macro:\n        all_aliases_maps.append(_PROC_MACRO_ALIASES)\n    if proc_macro_dev:\n        all_aliases_maps.append(_PROC_MACRO_DEV_ALIASES)\n    if build:\n        all_aliases_maps.append(_BUILD_ALIASES)\n    if build_proc_macro:\n        all_aliases_maps.append(_BUILD_PROC_MACRO_ALIASES)\n\n    # Default to always using normal aliases\n    if not all_aliases_maps:\n        all_aliases_maps.append(_NORMAL_ALIASES)\n        all_aliases_maps.append(_PROC_MACRO_ALIASES)\n\n    aliases = _flatten_dependency_maps(all_aliases_maps).pop(package_name, None)\n\n    if not aliases:\n        return dict()\n\n    common_items = aliases.pop(_COMMON_CONDITION, {}).items()\n\n    # If there are only common items in the dictionary, immediately return them\n    if not len(aliases.keys()) == 1:\n        return dict(common_items)\n\n    # Build a single select statement where each conditional has accounted for the\n    # common set of aliases.\n    crate_aliases = {\"//conditions:default\": dict(common_items)}\n    for condition, deps in aliases.items():\n        condition_triples = _CONDITIONS[condition]\n        for triple in condition_triples:\n            if triple in crate_aliases:\n                crate_aliases[triple].update(deps)\n            else:\n                crate_aliases.update({triple: dict(deps.items() + common_items)})\n\n    return select(crate_aliases)\n\n###############################################################################\n# WORKSPACE MEMBER DEPS AND ALIASES\n###############################################################################\n\n_NORMAL_DEPENDENCIES = {\n    \"third-party\": {\n        _COMMON_CONDITION: {\n            \"cc\": Label(\"@vendor//:cc-1.2.53\"),\n            \"clap\": Label(\"@vendor//:clap-4.5.54\"),\n            \"codespan-reporting\": Label(\"@vendor//:codespan-reporting-0.13.1\"),\n            \"foldhash\": Label(\"@vendor//:foldhash-0.2.0\"),\n            \"indexmap\": Label(\"@vendor//:indexmap-2.13.0\"),\n            \"proc-macro2\": Label(\"@vendor//:proc-macro2-1.0.105\"),\n            \"quote\": Label(\"@vendor//:quote-1.0.43\"),\n            \"scratch\": Label(\"@vendor//:scratch-1.0.9\"),\n            \"serde\": Label(\"@vendor//:serde-1.0.228\"),\n            \"syn\": Label(\"@vendor//:syn-2.0.114\"),\n        },\n    },\n}\n\n_NORMAL_ALIASES = {\n    \"third-party\": {\n        _COMMON_CONDITION: {\n        },\n    },\n}\n\n_NORMAL_DEV_DEPENDENCIES = {\n    \"third-party\": {\n    },\n}\n\n_NORMAL_DEV_ALIASES = {\n    \"third-party\": {\n    },\n}\n\n_PROC_MACRO_DEPENDENCIES = {\n    \"third-party\": {\n        _COMMON_CONDITION: {\n            \"rustversion\": Label(\"@vendor//:rustversion-1.0.22\"),\n        },\n    },\n}\n\n_PROC_MACRO_ALIASES = {\n    \"third-party\": {\n    },\n}\n\n_PROC_MACRO_DEV_DEPENDENCIES = {\n    \"third-party\": {\n    },\n}\n\n_PROC_MACRO_DEV_ALIASES = {\n    \"third-party\": {\n    },\n}\n\n_BUILD_DEPENDENCIES = {\n    \"third-party\": {\n    },\n}\n\n_BUILD_ALIASES = {\n    \"third-party\": {\n    },\n}\n\n_BUILD_PROC_MACRO_DEPENDENCIES = {\n    \"third-party\": {\n    },\n}\n\n_BUILD_PROC_MACRO_ALIASES = {\n    \"third-party\": {\n    },\n}\n\n_CONDITIONS = {\n    \"aarch64-apple-darwin\": [\"@rules_rust//rust/platform:aarch64-apple-darwin\"],\n    \"aarch64-apple-ios\": [\"@rules_rust//rust/platform:aarch64-apple-ios\"],\n    \"aarch64-apple-ios-sim\": [\"@rules_rust//rust/platform:aarch64-apple-ios-sim\"],\n    \"aarch64-linux-android\": [\"@rules_rust//rust/platform:aarch64-linux-android\"],\n    \"aarch64-pc-windows-msvc\": [\"@rules_rust//rust/platform:aarch64-pc-windows-msvc\"],\n    \"aarch64-unknown-fuchsia\": [\"@rules_rust//rust/platform:aarch64-unknown-fuchsia\"],\n    \"aarch64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\"],\n    \"aarch64-unknown-nixos-gnu\": [\"@rules_rust//rust/platform:aarch64-unknown-nixos-gnu\"],\n    \"aarch64-unknown-nto-qnx710\": [\"@rules_rust//rust/platform:aarch64-unknown-nto-qnx710\"],\n    \"aarch64-unknown-uefi\": [\"@rules_rust//rust/platform:aarch64-unknown-uefi\"],\n    \"arm-unknown-linux-gnueabi\": [\"@rules_rust//rust/platform:arm-unknown-linux-gnueabi\"],\n    \"arm-unknown-linux-musleabi\": [\"@rules_rust//rust/platform:arm-unknown-linux-musleabi\"],\n    \"armv7-linux-androideabi\": [\"@rules_rust//rust/platform:armv7-linux-androideabi\"],\n    \"armv7-unknown-linux-gnueabi\": [\"@rules_rust//rust/platform:armv7-unknown-linux-gnueabi\"],\n    \"cfg(any())\": [],\n    \"cfg(windows)\": [\"@rules_rust//rust/platform:aarch64-pc-windows-msvc\", \"@rules_rust//rust/platform:i686-pc-windows-msvc\", \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\"],\n    \"i686-apple-darwin\": [\"@rules_rust//rust/platform:i686-apple-darwin\"],\n    \"i686-linux-android\": [\"@rules_rust//rust/platform:i686-linux-android\"],\n    \"i686-pc-windows-msvc\": [\"@rules_rust//rust/platform:i686-pc-windows-msvc\"],\n    \"i686-unknown-freebsd\": [\"@rules_rust//rust/platform:i686-unknown-freebsd\"],\n    \"i686-unknown-linux-gnu\": [\"@rules_rust//rust/platform:i686-unknown-linux-gnu\"],\n    \"powerpc-unknown-linux-gnu\": [\"@rules_rust//rust/platform:powerpc-unknown-linux-gnu\"],\n    \"riscv32imc-unknown-none-elf\": [\"@rules_rust//rust/platform:riscv32imc-unknown-none-elf\"],\n    \"riscv64gc-unknown-linux-gnu\": [\"@rules_rust//rust/platform:riscv64gc-unknown-linux-gnu\"],\n    \"riscv64gc-unknown-none-elf\": [\"@rules_rust//rust/platform:riscv64gc-unknown-none-elf\"],\n    \"s390x-unknown-linux-gnu\": [\"@rules_rust//rust/platform:s390x-unknown-linux-gnu\"],\n    \"thumbv7em-none-eabi\": [\"@rules_rust//rust/platform:thumbv7em-none-eabi\"],\n    \"thumbv8m.main-none-eabi\": [\"@rules_rust//rust/platform:thumbv8m.main-none-eabi\"],\n    \"wasm32-unknown-emscripten\": [\"@rules_rust//rust/platform:wasm32-unknown-emscripten\"],\n    \"wasm32-unknown-unknown\": [\"@rules_rust//rust/platform:wasm32-unknown-unknown\"],\n    \"wasm32-wasip1\": [\"@rules_rust//rust/platform:wasm32-wasip1\"],\n    \"wasm32-wasip1-threads\": [\"@rules_rust//rust/platform:wasm32-wasip1-threads\"],\n    \"wasm32-wasip2\": [\"@rules_rust//rust/platform:wasm32-wasip2\"],\n    \"x86_64-apple-darwin\": [\"@rules_rust//rust/platform:x86_64-apple-darwin\"],\n    \"x86_64-apple-ios\": [\"@rules_rust//rust/platform:x86_64-apple-ios\"],\n    \"x86_64-linux-android\": [\"@rules_rust//rust/platform:x86_64-linux-android\"],\n    \"x86_64-pc-windows-msvc\": [\"@rules_rust//rust/platform:x86_64-pc-windows-msvc\"],\n    \"x86_64-unknown-freebsd\": [\"@rules_rust//rust/platform:x86_64-unknown-freebsd\"],\n    \"x86_64-unknown-fuchsia\": [\"@rules_rust//rust/platform:x86_64-unknown-fuchsia\"],\n    \"x86_64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n    \"x86_64-unknown-nixos-gnu\": [\"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\"],\n    \"x86_64-unknown-none\": [\"@rules_rust//rust/platform:x86_64-unknown-none\"],\n    \"x86_64-unknown-uefi\": [\"@rules_rust//rust/platform:x86_64-unknown-uefi\"],\n}\n\n###############################################################################\n\ndef crate_repositories():\n    \"\"\"A macro for defining repositories for all generated crates.\n\n    Returns:\n      A list of repos visible to the module through the module extension.\n    \"\"\"\n    maybe(\n        http_archive,\n        name = \"vendor__anstyle-1.0.13\",\n        sha256 = \"5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/anstyle/1.0.13/download\"],\n        strip_prefix = \"anstyle-1.0.13\",\n        build_file = Label(\"//third-party/bazel:BUILD.anstyle-1.0.13.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__cc-1.2.53\",\n        sha256 = \"755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/cc/1.2.53/download\"],\n        strip_prefix = \"cc-1.2.53\",\n        build_file = Label(\"//third-party/bazel:BUILD.cc-1.2.53.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__clap-4.5.54\",\n        sha256 = \"c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/clap/4.5.54/download\"],\n        strip_prefix = \"clap-4.5.54\",\n        build_file = Label(\"//third-party/bazel:BUILD.clap-4.5.54.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__clap_builder-4.5.54\",\n        sha256 = \"fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/clap_builder/4.5.54/download\"],\n        strip_prefix = \"clap_builder-4.5.54\",\n        build_file = Label(\"//third-party/bazel:BUILD.clap_builder-4.5.54.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__clap_lex-0.7.7\",\n        sha256 = \"c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/clap_lex/0.7.7/download\"],\n        strip_prefix = \"clap_lex-0.7.7\",\n        build_file = Label(\"//third-party/bazel:BUILD.clap_lex-0.7.7.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__codespan-reporting-0.13.1\",\n        sha256 = \"af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/codespan-reporting/0.13.1/download\"],\n        strip_prefix = \"codespan-reporting-0.13.1\",\n        build_file = Label(\"//third-party/bazel:BUILD.codespan-reporting-0.13.1.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__equivalent-1.0.2\",\n        sha256 = \"877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/equivalent/1.0.2/download\"],\n        strip_prefix = \"equivalent-1.0.2\",\n        build_file = Label(\"//third-party/bazel:BUILD.equivalent-1.0.2.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__find-msvc-tools-0.1.8\",\n        sha256 = \"8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/find-msvc-tools/0.1.8/download\"],\n        strip_prefix = \"find-msvc-tools-0.1.8\",\n        build_file = Label(\"//third-party/bazel:BUILD.find-msvc-tools-0.1.8.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__foldhash-0.2.0\",\n        sha256 = \"77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/foldhash/0.2.0/download\"],\n        strip_prefix = \"foldhash-0.2.0\",\n        build_file = Label(\"//third-party/bazel:BUILD.foldhash-0.2.0.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__hashbrown-0.16.1\",\n        sha256 = \"841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/hashbrown/0.16.1/download\"],\n        strip_prefix = \"hashbrown-0.16.1\",\n        build_file = Label(\"//third-party/bazel:BUILD.hashbrown-0.16.1.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__indexmap-2.13.0\",\n        sha256 = \"7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/indexmap/2.13.0/download\"],\n        strip_prefix = \"indexmap-2.13.0\",\n        build_file = Label(\"//third-party/bazel:BUILD.indexmap-2.13.0.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__proc-macro2-1.0.105\",\n        sha256 = \"535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/proc-macro2/1.0.105/download\"],\n        strip_prefix = \"proc-macro2-1.0.105\",\n        build_file = Label(\"//third-party/bazel:BUILD.proc-macro2-1.0.105.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__quote-1.0.43\",\n        sha256 = \"dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/quote/1.0.43/download\"],\n        strip_prefix = \"quote-1.0.43\",\n        build_file = Label(\"//third-party/bazel:BUILD.quote-1.0.43.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__rustversion-1.0.22\",\n        sha256 = \"b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/rustversion/1.0.22/download\"],\n        strip_prefix = \"rustversion-1.0.22\",\n        build_file = Label(\"//third-party/bazel:BUILD.rustversion-1.0.22.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__scratch-1.0.9\",\n        sha256 = \"d68f2ec51b097e4c1a75b681a8bec621909b5e91f15bb7b840c4f2f7b01148b2\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/scratch/1.0.9/download\"],\n        strip_prefix = \"scratch-1.0.9\",\n        build_file = Label(\"//third-party/bazel:BUILD.scratch-1.0.9.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__serde-1.0.228\",\n        sha256 = \"9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/serde/1.0.228/download\"],\n        strip_prefix = \"serde-1.0.228\",\n        build_file = Label(\"//third-party/bazel:BUILD.serde-1.0.228.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__serde_core-1.0.228\",\n        sha256 = \"41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/serde_core/1.0.228/download\"],\n        strip_prefix = \"serde_core-1.0.228\",\n        build_file = Label(\"//third-party/bazel:BUILD.serde_core-1.0.228.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__serde_derive-1.0.228\",\n        sha256 = \"d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/serde_derive/1.0.228/download\"],\n        strip_prefix = \"serde_derive-1.0.228\",\n        build_file = Label(\"//third-party/bazel:BUILD.serde_derive-1.0.228.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__shlex-1.3.0\",\n        sha256 = \"0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/shlex/1.3.0/download\"],\n        strip_prefix = \"shlex-1.3.0\",\n        build_file = Label(\"//third-party/bazel:BUILD.shlex-1.3.0.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__syn-2.0.114\",\n        sha256 = \"d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/syn/2.0.114/download\"],\n        strip_prefix = \"syn-2.0.114\",\n        build_file = Label(\"//third-party/bazel:BUILD.syn-2.0.114.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__termcolor-1.4.1\",\n        sha256 = \"06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/termcolor/1.4.1/download\"],\n        strip_prefix = \"termcolor-1.4.1\",\n        build_file = Label(\"//third-party/bazel:BUILD.termcolor-1.4.1.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__unicode-ident-1.0.22\",\n        sha256 = \"9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/unicode-ident/1.0.22/download\"],\n        strip_prefix = \"unicode-ident-1.0.22\",\n        build_file = Label(\"//third-party/bazel:BUILD.unicode-ident-1.0.22.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__unicode-width-0.2.2\",\n        sha256 = \"b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/unicode-width/0.2.2/download\"],\n        strip_prefix = \"unicode-width-0.2.2\",\n        build_file = Label(\"//third-party/bazel:BUILD.unicode-width-0.2.2.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__winapi-util-0.1.11\",\n        sha256 = \"c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/winapi-util/0.1.11/download\"],\n        strip_prefix = \"winapi-util-0.1.11\",\n        build_file = Label(\"//third-party/bazel:BUILD.winapi-util-0.1.11.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__windows-link-0.2.1\",\n        sha256 = \"f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/windows-link/0.2.1/download\"],\n        strip_prefix = \"windows-link-0.2.1\",\n        build_file = Label(\"//third-party/bazel:BUILD.windows-link-0.2.1.bazel\"),\n    )\n\n    maybe(\n        http_archive,\n        name = \"vendor__windows-sys-0.61.2\",\n        sha256 = \"ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc\",\n        type = \"tar.gz\",\n        urls = [\"https://static.crates.io/crates/windows-sys/0.61.2/download\"],\n        strip_prefix = \"windows-sys-0.61.2\",\n        build_file = Label(\"//third-party/bazel:BUILD.windows-sys-0.61.2.bazel\"),\n    )\n\n    return [\n        struct(repo = \"vendor__cc-1.2.53\", is_dev_dep = False),\n        struct(repo = \"vendor__clap-4.5.54\", is_dev_dep = False),\n        struct(repo = \"vendor__codespan-reporting-0.13.1\", is_dev_dep = False),\n        struct(repo = \"vendor__foldhash-0.2.0\", is_dev_dep = False),\n        struct(repo = \"vendor__indexmap-2.13.0\", is_dev_dep = False),\n        struct(repo = \"vendor__proc-macro2-1.0.105\", is_dev_dep = False),\n        struct(repo = \"vendor__quote-1.0.43\", is_dev_dep = False),\n        struct(repo = \"vendor__rustversion-1.0.22\", is_dev_dep = False),\n        struct(repo = \"vendor__scratch-1.0.9\", is_dev_dep = False),\n        struct(repo = \"vendor__serde-1.0.228\", is_dev_dep = False),\n        struct(repo = \"vendor__syn-2.0.114\", is_dev_dep = False),\n    ]\n"
  },
  {
    "path": "third-party/fixups/proc-macro2/fixups.toml",
    "content": "buildscript.run = true\n"
  },
  {
    "path": "third-party/fixups/quote/fixups.toml",
    "content": "buildscript.run = true\n"
  },
  {
    "path": "third-party/fixups/rustversion/fixups.toml",
    "content": "buildscript.run = true\n"
  },
  {
    "path": "third-party/fixups/scratch/fixups.toml",
    "content": "buildscript.run = true\n"
  },
  {
    "path": "third-party/fixups/serde/fixups.toml",
    "content": "buildscript.run = true\ncargo_env = [\"CARGO_PKG_VERSION_PATCH\"]\n"
  },
  {
    "path": "third-party/fixups/serde_core/fixups.toml",
    "content": "buildscript.run = true\ncargo_env = [\"CARGO_PKG_VERSION_PATCH\"]\n"
  },
  {
    "path": "third-party/fixups/serde_derive/fixups.toml",
    "content": "cargo_env = [\"CARGO_PKG_VERSION_PATCH\"]\n"
  },
  {
    "path": "third-party/fixups/winapi-util/fixups.toml",
    "content": "target_compatible_with = [\"prelude//os:windows\"]\n"
  },
  {
    "path": "third-party/fixups/windows-sys/fixups.toml",
    "content": "target_compatible_with = [\"prelude//os:windows\"]\n"
  },
  {
    "path": "third-party/src/lib.rs",
    "content": "\n"
  },
  {
    "path": "tools/bazel/BUILD.bazel",
    "content": "load(\"@apple_support//xcode:xcode_config.bzl\", \"xcode_config\")\nload(\"@apple_support//xcode:xcode_version.bzl\", \"xcode_version\")\nload(\"@bazel_skylib//:bzl_library.bzl\", \"bzl_library\")\n\nbzl_library(\n    name = \"bzl_srcs\",\n    srcs = glob([\"**/*.bzl\"]),\n    visibility = [\"//visibility:public\"],\n)\n\nxcode_version(\n    name = \"github_actions_xcode_26_2_0\",\n    default_macos_sdk_version = \"26.2\",\n    version = \"26.2\",\n)\n\nxcode_config(\n    name = \"github_actions_xcodes\",\n    default = \":github_actions_xcode_26_2_0\",\n    versions = [\":github_actions_xcode_26_2_0\"],\n)\n"
  },
  {
    "path": "tools/bazel/extension.bzl",
    "content": "\"\"\"CXX bzlmod extensions\"\"\"\n\nload(\"@bazel_features//:features.bzl\", \"bazel_features\")\nload(\"//third-party/bazel:crates.bzl\", _crate_repositories = \"crate_repositories\")\n\ndef _crates_vendor_remote_repository_impl(repository_ctx):\n    repository_ctx.symlink(repository_ctx.attr.build_file, \"BUILD.bazel\")\n\n_crates_vendor_remote_repository = repository_rule(\n    implementation = _crates_vendor_remote_repository_impl,\n    attrs = {\n        \"build_file\": attr.label(mandatory = True),\n    },\n)\n\ndef _crate_repositories_impl(module_ctx):\n    _crate_repositories()\n    _crates_vendor_remote_repository(\n        name = \"crates.io\",\n        build_file = \"//third-party/bazel:BUILD.bazel\",\n    )\n\n    metadata_kwargs = {}\n    if bazel_features.external_deps.extension_metadata_has_reproducible:\n        metadata_kwargs[\"reproducible\"] = True\n    return module_ctx.extension_metadata(**metadata_kwargs)\n\ncrate_repositories = module_extension(\n    implementation = _crate_repositories_impl,\n)\n"
  },
  {
    "path": "tools/bazel/rust_cxx_bridge.bzl",
    "content": "\"\"\"CXX Bridge rules.\"\"\"\n\nload(\"@bazel_skylib//rules:run_binary.bzl\", \"run_binary\")\nload(\"@rules_cc//cc:defs.bzl\", \"cc_library\")\n\ndef rust_cxx_bridge(name, src, deps = [], linkstatic = True, **kwargs):\n    \"\"\"A macro defining a cxx bridge library\n\n    Args:\n        name (string): The name of the new target\n        src (string): The rust source file to generate a bridge for\n        deps (list, optional): A list of dependencies for the underlying cc_library. Defaults to [].\n        **kwargs: Common arguments to pass through to underlying rules.\n    \"\"\"\n    native.alias(\n        name = \"%s/header\" % name,\n        actual = src + \".h\",\n        **kwargs\n    )\n\n    native.alias(\n        name = \"%s/source\" % name,\n        actual = src + \".cc\",\n        **kwargs\n    )\n\n    run_binary(\n        name = \"%s/generated\" % name,\n        srcs = [src],\n        outs = [\n            src + \".h\",\n            src + \".cc\",\n        ],\n        args = [\n            \"$(execpath %s)\" % src,\n            \"-o\",\n            \"$(execpath %s.h)\" % src,\n            \"-o\",\n            \"$(execpath %s.cc)\" % src,\n        ],\n        tool = \"@cxx.rs//:codegen\",\n        **kwargs\n    )\n\n    cc_library(\n        name = name,\n        srcs = [src + \".cc\"],\n        deps = deps + [\":%s/include\" % name],\n        linkstatic = linkstatic,\n        **kwargs\n    )\n\n    cc_library(\n        name = \"%s/include\" % name,\n        hdrs = [src + \".h\"],\n        **kwargs\n    )\n"
  },
  {
    "path": "tools/buck/rust_cxx_bridge.bzl",
    "content": "def rust_cxx_bridge(\n        name: str,\n        src: str,\n        deps: list[str] = []):\n    native.export_file(\n        name = \"%s/header\" % name,\n        src = \":%s/generated[generated.h]\" % name,\n        out = src + \".h\",\n    )\n\n    native.export_file(\n        name = \"%s/source\" % name,\n        src = \":%s/generated[generated.cc]\" % name,\n        out = src + \".cc\",\n    )\n\n    native.genrule(\n        name = \"%s/generated\" % name,\n        srcs = [src],\n        outs = {\n            \"generated.cc\": [\"generated.cc\"],\n            \"generated.h\": [\"generated.h\"],\n        },\n        cmd = \"$(exe //:codegen) ${SRCS} -o ${OUT}/generated.h -o ${OUT}/generated.cc\",\n        type = \"cxxbridge\",\n    )\n\n    native.cxx_library(\n        name = name,\n        srcs = [\":%s/source\" % name],\n        preferred_linkage = \"static\",\n        exported_deps = deps + [\":%s/include\" % name],\n    )\n\n    native.cxx_library(\n        name = \"%s/include\" % name,\n        exported_headers = [\":%s/header\" % name],\n    )\n"
  },
  {
    "path": "tools/buck/toolchains/BUCK",
    "content": "load(\"@prelude//tests:test_toolchain.bzl\", \"noop_test_toolchain\")\nload(\"@prelude//toolchains:cxx.bzl\", \"system_cxx_toolchain\")\nload(\"@prelude//toolchains:genrule.bzl\", \"system_genrule_toolchain\")\nload(\"@prelude//toolchains:python.bzl\", \"system_python_bootstrap_toolchain\")\nload(\"@prelude//toolchains:remote_test_execution.bzl\", \"remote_test_execution_toolchain\")\nload(\"@prelude//toolchains:rust.bzl\", \"system_rust_toolchain\")\n\nsystem_cxx_toolchain(\n    name = \"cxx\",\n    cxx_flags = select({\n        \"config//os:linux\": [\"-std=c++17\"],\n        \"config//os:macos\": [\"-std=c++17\"],\n        \"config//os:windows\": [\"/EHsc\"],\n    }),\n    link_flags = select({\n        \"config//os:linux\": [\"-lstdc++\"],\n        \"config//os:macos\": [\"-lc++\"],\n        \"config//os:windows\": [],\n    }),\n    visibility = [\"PUBLIC\"],\n)\n\nsystem_genrule_toolchain(\n    name = \"genrule\",\n    visibility = [\"PUBLIC\"],\n)\n\nsystem_python_bootstrap_toolchain(\n    name = \"python_bootstrap\",\n    visibility = [\"PUBLIC\"],\n)\n\nsystem_rust_toolchain(\n    name = \"rust\",\n    default_edition = None,\n    doctests = True,\n    visibility = [\"PUBLIC\"],\n)\n\nnoop_test_toolchain(\n    name = \"test\",\n    visibility = [\"PUBLIC\"],\n)\n\nremote_test_execution_toolchain(\n    name = \"remote_test_execution\",\n    visibility = [\"PUBLIC\"],\n)\n"
  },
  {
    "path": "tools/cargo/build.rs",
    "content": "use std::io::{self, Write};\n#[cfg(windows)]\nuse std::os::windows::fs as windows;\nuse std::path::Path;\nuse std::process;\n#[cfg(windows)]\nuse std::{env, fs};\n\nconst MISSING: &str = \"\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nWhen building `cxx` from a git clone, git's symlink support needs\nto be enabled on platforms that have it off by default (Windows).\nEither use:\n\n   $ git config --global core.symlinks true\n\nprior to cloning, or else use:\n\n   $ git clone -c core.symlinks=true https://github.com/dtolnay/cxx\n\nfor the clone.\n\nSymlinks are only required when compiling locally from a clone of\nthe git repository---they are NOT required when building `cxx` as\na Cargo-managed (possibly transitive) build dependency downloaded\nthrough crates.io.\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\";\n\n#[cfg(windows)]\nconst DENIED: &str = \"\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nWhen building `cxx` from a git clone on Windows we need Developer\nMode enabled for symlink support.\n\nTo enable Developer Mode: go under Settings to Update & Security,\nthen 'For developers', and turn on the toggle for Developer Mode.\n\nFor more explanation of symlinks in Windows, see these resources:\n> https://blogs.windows.com/windowsdeveloper/2016/12/02/symlinks-windows-10/\n> https://docs.microsoft.com/windows/uwp/get-started/enable-your-device-for-development\n\nSymlinks are only required when compiling locally from a clone of\nthe git repository---they are NOT required when building `cxx` as\na Cargo-managed (possibly transitive) build dependency downloaded\nthrough crates.io.\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\";\n\nfn main() {\n    println!(\"cargo:rerun-if-changed=build.rs\");\n    println!(\"cargo:rustc-cfg=check_cfg\");\n    println!(\"cargo:rustc-check-cfg=cfg(check_cfg)\");\n\n    if Path::new(\"src/syntax/mod.rs\").exists() {\n        return;\n    }\n\n    #[cfg_attr(not(windows), expect(unused_mut))]\n    let mut message = MISSING;\n\n    #[cfg(windows)]\n    if let Some(out_dir) = env::var_os(\"OUT_DIR\") {\n        let parent_dir = Path::new(&out_dir).join(\"symlink\");\n        let original_dir = parent_dir.join(\"original\");\n        let link_dir = parent_dir.join(\"link\");\n        if fs::create_dir_all(&original_dir).is_ok()\n            && (!link_dir.exists() || fs::remove_dir(&link_dir).is_ok())\n            && windows::symlink_dir(&original_dir, &link_dir).is_err()\n        {\n            message = DENIED;\n        }\n    }\n\n    let _ = io::stderr().write_all(message.as_bytes());\n    process::exit(1);\n}\n"
  }
]