aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:00:59 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:00:59 +0000
commit515c8ddb2f65363a8a82b05d6f26436c89979616 (patch)
tree5c229c19807bc789990e1c77c40d790be20f6e2b
parent8bd8e0c76e06103c8868df239372b2ce172ffa61 (diff)
parent266d58b94dad5c2ce34051ad04ab8cd87293cd64 (diff)
downloadcxx-android14-mainline-mediaprovider-release.tar.gz
Change-Id: Ib1b7bc4a3d2f25b84d92f549dabc1f35ce9587fa
-rw-r--r--.bazelignore1
-rw-r--r--.bazelrc2
-rw-r--r--.buckconfig36
-rw-r--r--.buckversion1
-rw-r--r--.gitattributes1
-rw-r--r--.github/workflows/ci.yml85
-rw-r--r--.github/workflows/site.yml5
-rw-r--r--.gitmodules3
-rw-r--r--.watchmanconfig3
-rw-r--r--Android.bp15
-rw-r--r--BUCK30
-rw-r--r--BUILD18
-rw-r--r--Cargo.toml34
-rw-r--r--README.md4
-rw-r--r--WORKSPACE19
-rw-r--r--book/diagram/.gitignore9
-rw-r--r--book/diagram/Makefile16
-rw-r--r--book/diagram/overview.ascii13
-rw-r--r--book/diagram/overview.svg132
-rw-r--r--book/diagram/overview.tex45
-rw-r--r--book/src/binding/cxxstring.md1
-rw-r--r--book/src/binding/string.md13
-rw-r--r--book/src/binding/vec.md2
-rw-r--r--book/src/build/bazel.md2
-rw-r--r--book/src/build/cmake.md16
-rw-r--r--book/src/cxx.pngbin64483 -> 71692 bytes
-rw-r--r--book/src/index.md4
-rw-r--r--book/src/overview.svg541
-rw-r--r--book/src/tutorial.md7
-rw-r--r--book/theme/head.hbs7
-rw-r--r--demo/BUCK3
-rw-r--r--demo/BUILD3
-rw-r--r--demo/Cargo.toml4
-rw-r--r--flags/Cargo.toml6
-rw-r--r--gen/build/Cargo.toml27
-rw-r--r--gen/build/src/cargo.rs157
-rw-r--r--gen/build/src/cfg.rs112
-rw-r--r--gen/build/src/intern.rs12
-rw-r--r--gen/build/src/lib.rs7
-rw-r--r--gen/build/src/out.rs59
-rw-r--r--gen/cmd/Android.bp22
-rw-r--r--gen/cmd/Cargo.toml23
-rw-r--r--gen/cmd/src/app.rs166
-rw-r--r--gen/cmd/src/cfg.rs93
-rw-r--r--gen/cmd/src/main.rs6
-rw-r--r--gen/cmd/src/test.rs72
-rw-r--r--gen/lib/Cargo.toml19
-rw-r--r--gen/lib/src/error.rs1
-rw-r--r--gen/lib/src/lib.rs2
-rw-r--r--gen/src/builtin.rs91
-rw-r--r--gen/src/cfg.rs133
-rw-r--r--gen/src/fs.rs16
-rw-r--r--gen/src/mod.rs55
-rw-r--r--gen/src/names.rs14
-rw-r--r--gen/src/nested.rs2
-rw-r--r--gen/src/write.rs271
-rw-r--r--include/cxx.h17
-rw-r--r--macro/Android.bp9
-rw-r--r--macro/Cargo.toml23
-rw-r--r--macro/src/clang.rs2
-rw-r--r--macro/src/derive.rs78
-rw-r--r--macro/src/expand.rs395
-rw-r--r--macro/src/generics.rs32
-rw-r--r--macro/src/lib.rs6
-rw-r--r--macro/src/load.rs10
-rw-r--r--macro/src/tokens.rs75
-rw-r--r--macro/src/type_id.rs3
-rw-r--r--src/c_char.rs69
-rw-r--r--src/cxx.cc89
-rw-r--r--src/cxx_string.rs9
-rw-r--r--src/cxx_vector.rs10
-rw-r--r--src/exception.rs5
-rw-r--r--src/extern_type.rs8
-rw-r--r--src/fmt.rs2
-rw-r--r--src/hash.rs12
-rw-r--r--src/lib.rs55
-rw-r--r--src/lossy.rs67
-rw-r--r--src/result.rs7
-rw-r--r--src/rust_string.rs1
-rw-r--r--src/rust_vec.rs5
-rw-r--r--src/shared_ptr.rs10
-rw-r--r--src/sip.rs228
-rw-r--r--src/symbols/exception.rs14
-rw-r--r--src/symbols/rust_str.rs2
-rw-r--r--src/symbols/rust_string.rs26
-rw-r--r--src/symbols/rust_vec.rs10
-rw-r--r--src/unique_ptr.rs16
-rw-r--r--src/unwind.rs47
-rw-r--r--src/weak_ptr.rs6
-rw-r--r--syntax/attrs.rs73
-rw-r--r--syntax/cfg.rs77
-rw-r--r--syntax/check.rs7
-rw-r--r--syntax/derive.rs6
-rw-r--r--syntax/discriminant.rs1
-rw-r--r--syntax/doc.rs11
-rw-r--r--syntax/file.rs4
-rw-r--r--syntax/impls.rs12
-rw-r--r--syntax/map.rs1
-rw-r--r--syntax/mod.rs24
-rw-r--r--syntax/names.rs11
-rw-r--r--syntax/parse.rs153
-rw-r--r--syntax/qualified.rs52
-rw-r--r--syntax/symbol.rs6
-rw-r--r--syntax/tokens.rs89
-rw-r--r--syntax/types.rs1
-rw-r--r--tests/BUCK12
-rw-r--r--tests/BUILD4
-rw-r--r--tests/compiletest.rs2
-rw-r--r--tests/ffi/Cargo.toml3
-rw-r--r--tests/ffi/lib.rs23
-rw-r--r--tests/ffi/tests.cc31
-rw-r--r--tests/ffi/tests.h8
-rw-r--r--tests/test.rs13
-rw-r--r--tests/ui/array_len_expr.stderr6
-rw-r--r--tests/ui/array_len_suffix.stderr2
-rw-r--r--tests/ui/async_fn.rs4
-rw-r--r--tests/ui/async_fn.stderr10
-rw-r--r--tests/ui/bad_explicit_impl.stderr2
-rw-r--r--tests/ui/by_value_not_supported.stderr20
-rw-r--r--tests/ui/const_fn.stderr2
-rw-r--r--tests/ui/data_enums.stderr2
-rw-r--r--tests/ui/deny_elided_lifetimes.rs27
-rw-r--r--tests/ui/deny_elided_lifetimes.stderr15
-rw-r--r--tests/ui/deny_missing_docs.stderr20
-rw-r--r--tests/ui/derive_duplicate.stderr6
-rw-r--r--tests/ui/derive_noncopy.stderr5
-rw-r--r--tests/ui/drop_shared.stderr6
-rw-r--r--tests/ui/empty_enum.stderr2
-rw-r--r--tests/ui/empty_struct.stderr2
-rw-r--r--tests/ui/enum_inconsistent.stderr2
-rw-r--r--tests/ui/enum_match_without_wildcard.stderr20
-rw-r--r--tests/ui/enum_out_of_bounds.stderr4
-rw-r--r--tests/ui/enum_overflows.stderr2
-rw-r--r--tests/ui/enum_receiver.stderr2
-rw-r--r--tests/ui/enum_unsatisfiable.stderr2
-rw-r--r--tests/ui/expected_named.stderr4
-rw-r--r--tests/ui/extern_fn_abi.stderr2
-rw-r--r--tests/ui/extern_type_bound.stderr4
-rw-r--r--tests/ui/extern_type_generic.stderr2
-rw-r--r--tests/ui/extern_type_lifetime_bound.stderr2
-rw-r--r--tests/ui/fallible_fnptr.stderr2
-rw-r--r--tests/ui/function_with_body.stderr2
-rw-r--r--tests/ui/generic_enum.stderr6
-rw-r--r--tests/ui/impl_trait_for_type.stderr2
-rw-r--r--tests/ui/include.stderr12
-rw-r--r--tests/ui/lifetime_extern_cxx.stderr2
-rw-r--r--tests/ui/lifetime_extern_rust.stderr2
-rw-r--r--tests/ui/missing_unsafe.stderr6
-rw-r--r--tests/ui/multiple_parse_error.stderr4
-rw-r--r--tests/ui/mut_return.stderr4
-rw-r--r--tests/ui/non_integer_discriminant_enum.stderr2
-rw-r--r--tests/ui/nonempty_impl_block.stderr2
-rw-r--r--tests/ui/nonlocal_rust_type.stderr10
-rw-r--r--tests/ui/opaque_autotraits.stderr24
-rw-r--r--tests/ui/opaque_not_sized.stderr6
-rw-r--r--tests/ui/pin_mut_opaque.stderr12
-rw-r--r--tests/ui/ptr_in_fnptr.stderr2
-rw-r--r--tests/ui/ptr_missing_unsafe.stderr2
-rw-r--r--tests/ui/ptr_no_const_mut.stderr15
-rw-r--r--tests/ui/ptr_unsupported.stderr8
-rw-r--r--tests/ui/raw_ident_namespace.rs53
-rw-r--r--tests/ui/raw_ident_namespace.stderr11
-rw-r--r--tests/ui/reference_to_reference.stderr4
-rw-r--r--tests/ui/reserved_lifetime.stderr2
-rw-r--r--tests/ui/reserved_name.stderr6
-rw-r--r--tests/ui/result_no_display.stderr2
-rw-r--r--tests/ui/root_namespace.stderr2
-rw-r--r--tests/ui/rust_pinned.stderr6
-rw-r--r--tests/ui/slice_of_type_alias.stderr23
-rw-r--r--tests/ui/slice_unsupported.stderr4
-rw-r--r--tests/ui/struct_cycle.stderr8
-rw-r--r--tests/ui/type_alias_rust.stderr2
-rw-r--r--tests/ui/unique_ptr_as_mut.stderr4
-rw-r--r--tests/ui/unique_ptr_to_opaque.stderr21
-rw-r--r--tests/ui/unique_ptr_twice.stderr8
-rw-r--r--tests/ui/unnamed_receiver.stderr4
-rw-r--r--tests/ui/unpin_impl.stderr24
-rw-r--r--tests/ui/unrecognized_receiver.stderr2
-rw-r--r--tests/ui/unsupported_elided.stderr14
-rw-r--r--tests/ui/vec_opaque.stderr22
-rw-r--r--tests/ui/vector_autotraits.stderr8
-rw-r--r--tests/ui/wrong_type_id.stderr22
-rw-r--r--third-party/.gitignore1
-rw-r--r--third-party/BUCK516
-rw-r--r--third-party/BUILD121
-rw-r--r--third-party/Cargo.lock388
-rw-r--r--third-party/Cargo.toml18
-rw-r--r--third-party/fixups/cc/fixups.toml1
-rw-r--r--third-party/fixups/clap/fixups.toml2
-rw-r--r--third-party/fixups/proc-macro2/fixups.toml2
-rw-r--r--third-party/fixups/quote/fixups.toml2
-rw-r--r--third-party/fixups/scratch/fixups.toml4
-rw-r--r--third-party/fixups/syn/fixups.toml2
-rw-r--r--third-party/reindeer.toml13
-rw-r--r--tools/bazel/third_party.bzl2
-rw-r--r--tools/bazel/vendor.bzl25
-rw-r--r--tools/buck/buildscript.bzl13
-rw-r--r--tools/buck/genrule.bzl8
m---------tools/buck/prelude0
-rw-r--r--tools/buck/rust_cxx_bridge.bzl14
-rw-r--r--tools/buck/rust_library.bzl34
-rw-r--r--tools/buck/toolchains/BUCK21
202 files changed, 4306 insertions, 1848 deletions
diff --git a/.bazelignore b/.bazelignore
index 2f7896d1..c42dab31 100644
--- a/.bazelignore
+++ b/.bazelignore
@@ -1 +1,2 @@
target/
+tools/buck/buck2/
diff --git a/.bazelrc b/.bazelrc
new file mode 100644
index 00000000..5e3ff76a
--- /dev/null
+++ b/.bazelrc
@@ -0,0 +1,2 @@
+build --enable_platform_specific_config
+build:linux --@rules_rust//:extra_rustc_flags=-Clink-arg=-fuse-ld=lld
diff --git a/.buckconfig b/.buckconfig
index 5c6c995a..045974f7 100644
--- a/.buckconfig
+++ b/.buckconfig
@@ -1,23 +1,17 @@
-[project]
- # We use some symlinks in the source tree, but they get eliminated by `cargo
- # publish` and `cargo vendor` so this allow_symlinks setting should not be
- # required downstream.
- allow_symlinks = allow
-
- # Hide BUCK files under target/package/ from `buck build ...`. Otherwise:
- # $ buck build ...
- # //target/package/cxx-0.3.0/tests:ffi references non-existing file or directory 'target/package/cxx-0.3.0/tests/ffi/lib.rs'
- ignore = target
+[repositories]
+repo = .
+prelude = tools/buck/prelude
+toolchains = tools/buck/toolchains
+ovr_config = tools/buck/prelude
+buck = none
+fbcode = none
+fbsource = none
-[cxx]
- cxxflags = -std=c++11
-
-[rust]
- default_edition = 2018
- rustc_flags = \
- -Clink-arg=-fuse-ld=lld \
- -Crelocation-model=dynamic-no-pic \
- --cap-lints=allow
+[project]
+# Hide BUCK files under target/package/ from `buck build ...`. Otherwise:
+# $ buck build ...
+# //target/package/cxx-0.3.0/tests:ffi references non-existing file or directory 'target/package/cxx-0.3.0/tests/ffi/lib.rs'
+ignore = target
-[defaults.rust_library]
- type = check
+[parser]
+target_platform_detector_spec = target://...->ovr_config//platforms:default
diff --git a/.buckversion b/.buckversion
deleted file mode 100644
index b25fa3fc..00000000
--- a/.buckversion
+++ /dev/null
@@ -1 +0,0 @@
-last
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..f9f0dca7
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+third-party/BUCK linguist-generated
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0b82cd99..93feb348 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -5,6 +5,9 @@ on:
pull_request:
schedule: [cron: "40 1 * * *"]
+permissions:
+ contents: read
+
jobs:
test:
name: ${{matrix.name || format('Rust {0}', matrix.rust)}}
@@ -16,25 +19,23 @@ jobs:
- rust: nightly
- rust: beta
- rust: stable
- - rust: 1.48.0
+ - rust: 1.60.0
- name: macOS
rust: nightly
os: macos
- - name: Windows (gnu)
- rust: nightly-x86_64-pc-windows-gnu
- os: windows
- name: Windows (msvc)
rust: nightly-x86_64-pc-windows-msvc
os: windows
flags: /EHsc
env:
CXXFLAGS: ${{matrix.flags}}
- RUSTFLAGS: --cfg deny_warnings
+ RUSTFLAGS: --cfg deny_warnings -Dwarnings
+ timeout-minutes: 45
steps:
- name: Enable symlinks (windows)
if: matrix.os == 'windows'
run: git config --global core.symlinks true
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
@@ -45,51 +46,61 @@ jobs:
# build. The extra coverage is not particularly valuable and we can
# still ensure the test is kept passing on the basis of the scheduled
# builds.
- if: matrix.os && github.event_name != 'schedule'
- run: echo "RUSTFLAGS=--cfg skip_ui_tests $RUSTFLAGS" >> $GITHUB_ENV
+ run: |
+ echo RUSTFLAGS=$RUSTFLAGS >> $GITHUB_ENV
+ echo exclude=--exclude cxx-test-suite >> $GITHUB_OUTPUT
+ env:
+ RUSTFLAGS: ${{env.RUSTFLAGS}} ${{matrix.os && github.event_name != 'schedule' && '--cfg skip_ui_tests' || ''}}
+ id: testsuite
shell: bash
- run: cargo run --manifest-path demo/Cargo.toml
- - run: cargo test --workspace --exclude cxx-test-suite
+ - run: cargo test --workspace ${{steps.testsuite.outputs.exclude}}
+ - run: cargo check --no-default-features --features alloc
+ env:
+ RUSTFLAGS: --cfg compile_error_if_std ${{env.RUSTFLAGS}}
+ - run: cargo check --no-default-features
+ env:
+ RUSTFLAGS: --cfg compile_error_if_alloc --cfg cxx_experimental_no_alloc ${{env.RUSTFLAGS}}
buck:
name: Buck
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
- - uses: dtolnay/rust-toolchain@stable
- - uses: actions/setup-java@v1
+ - uses: actions/checkout@v3
with:
- java-version: 11
- java-package: jre
- - name: Install Buck
- run: |
- mkdir bin
- wget -q -O bin/buck https://jitpack.io/com/github/facebook/buck/a5f0342ae3/buck-a5f0342ae3-java11.pex # dev branch from 2020.10.11
- chmod +x bin/buck
- echo bin >> $GITHUB_PATH
+ submodules: true
+ - uses: dtolnay/rust-toolchain@stable
+ - uses: dtolnay/install@reindeer
+ - uses: dtolnay/install@buck2
- name: Install lld
run: sudo apt-get install lld
- - name: Vendor dependencies
- run: |
- cp third-party/Cargo.lock .
- cargo vendor --versioned-dirs --locked third-party/vendor
- - run: buck build :cxx#check --verbose=0
- - run: buck run demo --verbose=0
- - run: buck test ... --verbose=0
+ - run: cargo vendor --versioned-dirs --locked
+ working-directory: third-party
+ - run: reindeer vendor
+ working-directory: third-party
+ - name: Check reindeer-generated BUCK file up to date
+ run: git diff --exit-code
+ - run: buck2 run demo
+ - run: buck2 build ...
+ - run: buck2 run tests:test
bazel:
name: Bazel
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Install Bazel
run: |
- wget -q -O install.sh https://github.com/bazelbuild/bazel/releases/download/4.0.0/bazel-4.0.0-installer-linux-x86_64.sh
+ wget -q -O install.sh https://github.com/bazelbuild/bazel/releases/download/5.1.1/bazel-5.1.1-installer-linux-x86_64.sh
chmod +x install.sh
./install.sh --user
echo $HOME/bin >> $GITHUB_PATH
+ - name: Install lld
+ run: sudo apt-get install lld
- run: bazel run demo --verbose_failures --noshow_progress
- run: bazel test ... --verbose_failures --noshow_progress
@@ -97,8 +108,9 @@ jobs:
name: Clippy
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@clippy
- run: cargo clippy --workspace --tests -- -Dclippy::all
@@ -106,9 +118,20 @@ jobs:
name: Clang Tidy
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Install clang-tidy
run: sudo apt-get install clang-tidy-11
- name: Run clang-tidy
run: clang-tidy-11 src/cxx.cc --warnings-as-errors=*
+
+ outdated:
+ name: Outdated
+ runs-on: ubuntu-latest
+ if: github.event_name != 'pull_request'
+ timeout-minutes: 45
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/install@cargo-outdated
+ - run: cargo outdated --workspace --exit-code 1
diff --git a/.github/workflows/site.yml b/.github/workflows/site.yml
index d6b0ca6d..09382b79 100644
--- a/.github/workflows/site.yml
+++ b/.github/workflows/site.yml
@@ -12,8 +12,11 @@ jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ timeout-minutes: 30
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Get mdBook
run: |
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..208a58a9
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "tools/buck/prelude"]
+ path = tools/buck/prelude
+ url = https://github.com/facebookincubator/buck2-prelude
diff --git a/.watchmanconfig b/.watchmanconfig
new file mode 100644
index 00000000..d93f3088
--- /dev/null
+++ b/.watchmanconfig
@@ -0,0 +1,3 @@
+{
+ "ignore_dirs": ["buck-out"]
+}
diff --git a/Android.bp b/Android.bp
index 05ef3874..4c40b571 100644
--- a/Android.bp
+++ b/Android.bp
@@ -39,6 +39,10 @@ rust_library {
crate_name: "cxx",
srcs: ["src/lib.rs"],
edition: "2018",
+ features: [
+ "alloc",
+ "std",
+ ],
rustlibs: [
"libanyhow",
"libthiserror",
@@ -51,9 +55,11 @@ rust_library {
],
shared_libs: ["libc++"],
host_supported: true,
+ vendor_available: true,
+ product_available: true,
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.compos",
"com.android.virt",
],
@@ -61,13 +67,16 @@ rust_library {
}
cc_library_static {
- host_supported: true,
name: "libcxxbridge05",
+ defaults: ["rust_static_cc_lib_defaults"],
cflags: ["-DRUST_CXX_NO_EXCEPTIONS"],
srcs: ["src/cxx.cc"],
+ host_supported: true,
+ vendor_available: true,
+ product_available: true,
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
+ "com.android.btservices",
"com.android.compos",
"com.android.virt",
],
diff --git a/BUCK b/BUCK
index 86174e97..6fcf7fa8 100644
--- a/BUCK
+++ b/BUCK
@@ -1,6 +1,11 @@
rust_library(
name = "cxx",
- srcs = glob(["src/**"]),
+ srcs = glob(["src/**/*.rs"]),
+ edition = "2018",
+ features = [
+ "alloc",
+ "std",
+ ],
visibility = ["PUBLIC"],
deps = [
":core",
@@ -10,8 +15,12 @@ rust_library(
rust_binary(
name = "codegen",
- srcs = glob(["gen/cmd/src/**"]),
+ srcs = glob(["gen/cmd/src/**/*.rs"]) + [
+ "gen/cmd/src/gen",
+ "gen/cmd/src/syntax",
+ ],
crate = "cxxbridge",
+ edition = "2018",
visibility = ["PUBLIC"],
deps = [
"//third-party:clap",
@@ -35,8 +44,9 @@ cxx_library(
rust_library(
name = "macro",
- srcs = glob(["macro/src/**"]),
+ srcs = glob(["macro/src/**/*.rs"]) + ["macro/src/syntax"],
crate = "cxxbridge_macro",
+ edition = "2018",
proc_macro = True,
deps = [
"//third-party:proc-macro2",
@@ -47,12 +57,16 @@ rust_library(
rust_library(
name = "build",
- srcs = glob(["gen/build/src/**"]),
+ srcs = glob(["gen/build/src/**/*.rs"]) + [
+ "gen/build/src/gen",
+ "gen/build/src/syntax",
+ ],
+ edition = "2018",
visibility = ["PUBLIC"],
deps = [
"//third-party:cc",
"//third-party:codespan-reporting",
- "//third-party:lazy_static",
+ "//third-party:once_cell",
"//third-party:proc-macro2",
"//third-party:quote",
"//third-party:scratch",
@@ -62,7 +76,11 @@ rust_library(
rust_library(
name = "lib",
- srcs = glob(["gen/lib/src/**"]),
+ srcs = glob(["gen/lib/src/**/*.rs"]) + [
+ "gen/lib/src/gen",
+ "gen/lib/src/syntax",
+ ],
+ edition = "2018",
visibility = ["PUBLIC"],
deps = [
"//third-party:cc",
diff --git a/BUILD b/BUILD
index c2c2edfd..c88eb249 100644
--- a/BUILD
+++ b/BUILD
@@ -1,9 +1,14 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
-load("@rules_rust//rust:rust.bzl", "rust_binary", "rust_library")
+load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library", "rust_proc_macro")
rust_library(
name = "cxx",
srcs = glob(["src/**/*.rs"]),
+ crate_features = [
+ "alloc",
+ "std",
+ ],
+ edition = "2018",
proc_macro_deps = [
":cxxbridge-macro",
],
@@ -15,6 +20,7 @@ rust_binary(
name = "codegen",
srcs = glob(["gen/cmd/src/**/*.rs"]),
data = ["gen/cmd/src/gen/include/cxx.h"],
+ edition = "2018",
visibility = ["//visibility:public"],
deps = [
"//third-party:clap",
@@ -39,10 +45,10 @@ cc_library(
hdrs = ["include/cxx.h"],
)
-rust_library(
+rust_proc_macro(
name = "cxxbridge-macro",
- srcs = glob(["macro/src/**"]),
- crate_type = "proc-macro",
+ srcs = glob(["macro/src/**/*.rs"]),
+ edition = "2018",
deps = [
"//third-party:proc-macro2",
"//third-party:quote",
@@ -54,11 +60,12 @@ rust_library(
name = "build",
srcs = glob(["gen/build/src/**/*.rs"]),
data = ["gen/build/src/gen/include/cxx.h"],
+ edition = "2018",
visibility = ["//visibility:public"],
deps = [
"//third-party:cc",
"//third-party:codespan-reporting",
- "//third-party:lazy_static",
+ "//third-party:once_cell",
"//third-party:proc-macro2",
"//third-party:quote",
"//third-party:scratch",
@@ -70,6 +77,7 @@ rust_library(
name = "lib",
srcs = glob(["gen/lib/src/**/*.rs"]),
data = ["gen/lib/src/gen/include/cxx.h"],
+ edition = "2018",
visibility = ["//visibility:public"],
deps = [
"//third-party:cc",
diff --git a/Cargo.toml b/Cargo.toml
index 0414c727..9e80bda6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,45 +1,51 @@
[package]
name = "cxx"
-version = "1.0.54" # remember to update html_root_url
+version = "1.0.85" # remember to update html_root_url
authors = ["David Tolnay <dtolnay@gmail.com>"]
-edition = "2018"
-links = "cxxbridge1"
-license = "MIT OR Apache-2.0"
+categories = ["development-tools::ffi", "api-bindings", "no-std"]
description = "Safe interop between Rust and C++"
-repository = "https://github.com/dtolnay/cxx"
documentation = "https://docs.rs/cxx"
-homepage = "https://cxx.rs"
-readme = "README.md"
+edition = "2018"
exclude = ["/demo", "/gen", "/syntax", "/third-party"]
-keywords = ["ffi"]
-categories = ["development-tools::ffi", "api-bindings"]
+homepage = "https://cxx.rs"
+keywords = ["ffi", "c++"]
+license = "MIT OR Apache-2.0"
+links = "cxxbridge1"
+repository = "https://github.com/dtolnay/cxx"
+rust-version = "1.48"
[features]
-default = ["cxxbridge-flags/default"] # c++11
+default = ["std", "cxxbridge-flags/default"] # c++11
"c++14" = ["cxxbridge-flags/c++14"]
"c++17" = ["cxxbridge-flags/c++17"]
"c++20" = ["cxxbridge-flags/c++20"]
+alloc = []
+std = ["alloc"]
[dependencies]
-cxxbridge-macro = { version = "=1.0.54", path = "macro" }
+cxxbridge-macro = { version = "=1.0.85", path = "macro" }
link-cplusplus = "1.0"
[build-dependencies]
cc = "1.0.49"
-cxxbridge-flags = { version = "=1.0.54", path = "flags", default-features = false }
+cxxbridge-flags = { version = "=1.0.85", path = "flags", default-features = false }
[dev-dependencies]
-cxx-build = { version = "=1.0.54", path = "gen/build" }
+cxx-build = { version = "=1.0.85", path = "gen/build" }
cxx-gen = { version = "0.7", path = "gen/lib" }
cxx-test-suite = { version = "0", path = "tests/ffi" }
rustversion = "1.0"
-trybuild = { version = "1.0.33", features = ["diff"] }
+trybuild = { version = "1.0.66", features = ["diff"] }
+
+[lib]
+doc-scrape-examples = false
[workspace]
members = ["demo", "flags", "gen/build", "gen/cmd", "gen/lib", "macro", "tests/ffi"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
+rustdoc-args = ["--cfg", "doc_cfg"]
[patch.crates-io]
cxx = { path = "." }
diff --git a/README.md b/README.md
index 7dd4ded9..60a8a13f 100644
--- a/README.md
+++ b/README.md
@@ -3,8 +3,8 @@ CXX &mdash; safe FFI between Rust and C++
[<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)
[<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)
-[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-cxx-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/cxx)
-[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/cxx/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/cxx/actions?query=branch%3Amaster)
+[<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)
+[<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)
This library provides a **safe** mechanism for calling C++ code from Rust and
Rust code from C++, not subject to the many ways that things can go wrong when
diff --git a/WORKSPACE b/WORKSPACE
index 08aacf21..8f917810 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -4,20 +4,21 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_rust",
- sha256 = "697a6f4f2adbd1b00f792346d6eca4cd45f691be63069c7d7ebf4fcf82a377a8",
- strip_prefix = "rules_rust-8bad4c5e4e53d9f6f8d4d5228e26a44d92f37ab2",
+ sha256 = "617082067629939c0a22f587811a3e822a50a203119a90380e21f5aec3373da9",
+ strip_prefix = "rules_rust-e07881fa22a5f0d16230d8b23bbff2bf358823b8",
urls = [
- # Master branch as of 2021-04-11
- "https://github.com/bazelbuild/rules_rust/archive/8bad4c5e4e53d9f6f8d4d5228e26a44d92f37ab2.tar.gz",
+ # Main branch as of 2022-04-27
+ "https://github.com/bazelbuild/rules_rust/archive/e07881fa22a5f0d16230d8b23bbff2bf358823b8.tar.gz",
],
)
-load("@rules_rust//rust:repositories.bzl", "rust_repositories")
+load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains")
-RUST_VERSION = "1.54.0"
+RUST_VERSION = "1.65.0"
-rust_repositories(
- edition = "2018",
+rules_rust_dependencies()
+
+rust_register_toolchains(
version = RUST_VERSION,
)
@@ -25,6 +26,6 @@ load("//tools/bazel:vendor.bzl", "vendor")
vendor(
name = "third-party",
- lockfile = "//third-party:Cargo.lock",
cargo_version = RUST_VERSION,
+ lockfile = "//third-party:Cargo.lock",
)
diff --git a/book/diagram/.gitignore b/book/diagram/.gitignore
index 81631c69..27572bd3 100644
--- a/book/diagram/.gitignore
+++ b/book/diagram/.gitignore
@@ -1,2 +1,7 @@
-/bin
-/build
+*.aux
+*.fdb_latexmk
+*.fls
+*.log
+*.pdf
+*.png
+*.svg
diff --git a/book/diagram/Makefile b/book/diagram/Makefile
index 161da349..1723a9b9 100644
--- a/book/diagram/Makefile
+++ b/book/diagram/Makefile
@@ -1,12 +1,8 @@
-all: overview.svg
+overview.svg: overview.pdf
+ pdf2svg $< $@
-build/bin/svgbob:
- cargo install --git https://github.com/ivanceras/svgbob --rev df01674c47350665158ececa476e63f51c58a9c7 --root build
+overview.pdf: overview.tex
+ latexmk $<
-%.svg: %.ascii build/bin/svgbob
- build/bin/svgbob $< > $@
-
-clean:
- rm -f *.svg
-
-.PHONY: all clean
+overview.png: overview.svg
+ svgexport $< $@ 3x
diff --git a/book/diagram/overview.ascii b/book/diagram/overview.ascii
deleted file mode 100644
index dd1c4b93..00000000
--- a/book/diagram/overview.ascii
+++ /dev/null
@@ -1,13 +0,0 @@
- .-----------------------------.
- | #[cxx::bridge] mod |
- | description of boundary |
- '--------------+--------------'
- |
- |
- "Macro expansion" | "Code generation"
- +---------------+---------------+
- Safe | |
- straightforward v v Straightforward
- "Rust APIs".----------------. "Hidden C ABI".---------------. "C++ APIs"
-Rust <----------->| "Rust bindings"|<~~~~~~~~~~~~~>| "C++ bindings"|<-----------> "C++"
-code '----------------' '---------------' code
diff --git a/book/diagram/overview.svg b/book/diagram/overview.svg
deleted file mode 100644
index e5154668..00000000
--- a/book/diagram/overview.svg
+++ /dev/null
@@ -1,132 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="696" height="224">
- <style>line, path, circle,rect,polygon {
- stroke: black;
- stroke-width: 2;
- stroke-opacity: 1;
- fill-opacity: 1;
- stroke-linecap: round;
- stroke-linejoin: miter;
- }
-
- text {
- fill: black;
- }
- rect.backdrop{
- stroke: none;
- fill: white;
- }
- .broken{
- stroke-dasharray: 8;
- }
- .filled{
- fill: black;
- }
- .bg_filled{
- fill: white;
- }
- .nofill{
- fill: white;
- }
-
- text {
- font-family: monospace;
- font-size: 14px;
- }
-
- .end_marked_arrow{
- marker-end: url(#arrow);
- }
- .start_marked_arrow{
- marker-start: url(#arrow);
- }
-
- .end_marked_diamond{
- marker-end: url(#diamond);
- }
- .start_marked_diamond{
- marker-start: url(#diamond);
- }
-
- .end_marked_circle{
- marker-end: url(#circle);
- }
- .start_marked_circle{
- marker-start: url(#circle);
- }
-
- .end_marked_open_circle{
- marker-end: url(#open_circle);
- }
- .start_marked_open_circle{
- marker-start: url(#open_circle);
- }
-
- .end_marked_big_open_circle{
- marker-end: url(#big_open_circle);
- }
- .start_marked_big_open_circle{
- marker-start: url(#big_open_circle);
- }
-
-
- </style>
- <defs>
- <marker id="arrow" viewBox="-2 -2 8 8" refX="4" refY="2" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
- <polygon points="0,0 0,4 4,2 0,0"></polygon>
- </marker>
- <marker id="diamond" viewBox="-2 -2 8 8" refX="4" refY="2" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
- <polygon points="0,2 2,0 4,2 2,4 0,2"></polygon>
- </marker>
- <marker id="circle" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
- <circle cx="4" cy="4" r="2" class="filled"></circle>
- </marker>
- <marker id="open_circle" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
- <circle cx="4" cy="4" r="2" class="bg_filled"></circle>
- </marker>
- <marker id="big_open_circle" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
- <circle cx="4" cy="4" r="3" class="bg_filled"></circle>
- </marker>
- </defs>
- <rect class="backdrop" x="0" y="0" width="696" height="224"></rect>
- <rect x="148" y="168" width="136" height="32" class="solid nofill" rx="4"></rect>
- <text x="162" y="188" >Rust bindings</text>
- <rect x="412" y="168" width="128" height="32" class="solid nofill" rx="4"></rect>
- <text x="426" y="188" >C++ bindings</text>
- <text x="266" y="28" >#[cxx::bridge]</text>
- <text x="394" y="28" >mod</text>
- <text x="250" y="44" >description</text>
- <text x="346" y="44" >of</text>
- <text x="370" y="44" >boundary</text>
- <line x1="220" y1="120" x2="220" y2="160" class="solid end_marked_arrow"></line>
- <line x1="476" y1="120" x2="476" y2="160" class="solid end_marked_arrow"></line>
- <text x="74" y="140" >Safe</text>
- <text x="34" y="156" >straightforward</text>
- <text x="530" y="156" >Straightforward</text>
- <polygon points="48,180 40,184 48,188" class="filled"></polygon>
- <line x1="48" y1="184" x2="144" y2="184" class="solid end_marked_arrow"></line>
- <polygon points="296,180 288,184 296,188" class="filled"></polygon>
- <line x1="296" y1="184" x2="408" y2="184" class="broken end_marked_arrow"></line>
- <polygon points="552,180 544,184 552,188" class="filled"></polygon>
- <line x1="552" y1="184" x2="648" y2="184" class="solid end_marked_arrow"></line>
- <text x="2" y="188" >Rust</text>
- <text x="2" y="204" >code</text>
- <text x="658" y="204" >code</text>
- <text x="202" y="108" >Macro expansion</text>
- <text x="370" y="108" >Code generation</text>
- <text x="58" y="172" >Rust APIs</text>
- <text x="298" y="172" >Hidden C ABI</text>
- <text x="562" y="172" >C++ APIs</text>
- <text x="658" y="188" >C++</text>
- <g>
- <path d="M 228,8 A 8,8 0,0,0 220,16" class="nofill"></path>
- <line x1="228" y1="8" x2="468" y2="8" class="solid"></line>
- <path d="M 468,8 A 8,8 0,0,1 476,16" class="nofill"></path>
- <line x1="220" y1="16" x2="220" y2="48" class="solid"></line>
- <line x1="476" y1="16" x2="476" y2="48" class="solid"></line>
- <path d="M 220,48 A 8,8 0,0,0 228,56" class="nofill"></path>
- <line x1="228" y1="56" x2="468" y2="56" class="solid"></line>
- <line x1="348" y1="56" x2="348" y2="120" class="solid"></line>
- <path d="M 476,48 A 8,8 0,0,1 468,56" class="nofill"></path>
- <line x1="220" y1="120" x2="476" y2="120" class="solid"></line>
- </g>
-</svg>
diff --git a/book/diagram/overview.tex b/book/diagram/overview.tex
new file mode 100644
index 00000000..a613bb75
--- /dev/null
+++ b/book/diagram/overview.tex
@@ -0,0 +1,45 @@
+\documentclass{standalone}
+\usepackage{makecell}
+\usepackage{pgfplots}
+\usepackage{sansmath}
+\usetikzlibrary{arrows.meta}
+\pgfplotsset{compat=1.16}
+\begin{document}
+\pagecolor{white}
+\begin{tikzpicture}[
+ x=1cm,
+ y=-.6cm,
+ every node/.append style={
+ line width=1.5pt,
+ font=\Large\sansmath\sffamily,
+ },
+ every path/.append style={
+ >={Latex[length=10pt,width=8pt]},
+ line width=1.5pt,
+ },
+ execute at end node={\vphantom{bg}},
+]
+\node[draw, rounded corners=5, inner xsep=30pt, inner ysep=2pt]
+ (bridge) at (0, .25) {\makecell{\texttt{\#\hspace{-1pt}[}cxx::bridge\texttt{]} mod\\[-4pt]description of boundary}};
+\node[draw, rounded corners, inner xsep=10pt, inner ysep=6pt, text depth=1pt]
+ (rust-bindings) at (-3.5, 6.5) {Rust bindings};
+\node[draw, rounded corners, inner xsep=10pt, inner ysep=6pt, text depth=1pt]
+ (cpp-bindings) at (3.5, 6.5) {C\texttt{++} bindings};
+\node[inner xsep=4pt, inner ysep=-0pt]
+ (rust-code) at (-9, 6.5) {\makecell[r]{\\[-8pt]Rust\\[-4pt]code}};
+\node[inner xsep=4pt, inner ysep=-0pt]
+ (cpp-code) at (9, 6.5) {\makecell[l]{\\[-8pt]C\texttt{++}\\[-4pt]code}};
+\draw (bridge) -- (0, 4);
+\draw[<->] (rust-bindings) |- (0, 4) -| (cpp-bindings);
+\draw[<->] (rust-code) -- (rust-bindings);
+\draw[<->, dash pattern=on 8pt off 6pt] (rust-bindings) -- (cpp-bindings);
+\draw[<->] (cpp-bindings) -- (cpp-code);
+\draw (-.75, 4) node[anchor=south east] {Macro expansion};
+\draw (.75, 4) node[anchor=south west] {Code generation};
+\draw (0, 6.5) node[anchor=south, inner ysep=4pt] {Hidden C ABI};
+\draw (-6.75, 6.5) node[anchor=south, inner ysep=1pt] {\makecell{Safe\\[-4pt]straightforward\\[-4pt]Rust APIs}};
+\draw (6.75, 6.5) node[anchor=south, inner ysep=1pt] {\makecell{Straightforward\\[-4pt]C\texttt{++} APIs}};
+\pgfresetboundingbox\path
+ (-9.5, 0) -- (rust-bindings.south)+(0, .3) -- (9.5, 0) -- (bridge.north);
+\end{tikzpicture}
+\end{document}
diff --git a/book/src/binding/cxxstring.md b/book/src/binding/cxxstring.md
index 0b1d7bbd..cfe707f2 100644
--- a/book/src/binding/cxxstring.md
+++ b/book/src/binding/cxxstring.md
@@ -73,6 +73,7 @@ fn main() {
#pragma once
#include <map>
#include <memory>
+#include <string>
#include <variant>
#include <vector>
diff --git a/book/src/binding/string.md b/book/src/binding/string.md
index d564e00c..1e482781 100644
--- a/book/src/binding/string.md
+++ b/book/src/binding/string.md
@@ -18,15 +18,24 @@ public:
String(String &&) noexcept;
~String() noexcept;
- // Throws std::invalid_argument if not utf-8.
+ // Throws std::invalid_argument if not UTF-8.
String(const std::string &);
String(const char *);
String(const char *, size_t);
- // Throws std::invalid_argument if not utf-16.
+ // Replaces invalid UTF-8 data with the replacement character (U+FFFD).
+ static String lossy(const std::string &) noexcept;
+ static String lossy(const char *) noexcept;
+ static String lossy(const char *, size_t) noexcept;
+
+ // Throws std::invalid_argument if not UTF-16.
String(const char16_t *);
String(const char16_t *, size_t);
+ // Replaces invalid UTF-16 data with the replacement character (U+FFFD).
+ static String lossy(const char16_t *) noexcept;
+ static String lossy(const char16_t *, size_t) noexcept;
+
String &operator=(const String &) noexcept;
String &operator=(String &&) noexcept;
diff --git a/book/src/binding/vec.md b/book/src/binding/vec.md
index 948fa671..4d6587ab 100644
--- a/book/src/binding/vec.md
+++ b/book/src/binding/vec.md
@@ -47,6 +47,8 @@ public:
void push_back(T &&value);
template <typename... Args>
void emplace_back(Args &&...args);
+ void truncate(size_t len);
+ void clear();
class iterator;
iterator begin() noexcept;
diff --git a/book/src/build/bazel.md b/book/src/build/bazel.md
index 8f910550..6a2c82b0 100644
--- a/book/src/build/bazel.md
+++ b/book/src/build/bazel.md
@@ -70,7 +70,7 @@ def rust_cxx_bridge(name, src, deps = []):
# demo/BUILD
load("@rules_cc//cc:defs.bzl", "cc_library")
-load("@rules_rust//rust:rust.bzl", "rust_binary")
+load("@rules_rust//rust:defs.bzl", "rust_binary")
load("//tools/bazel:rust_cxx_bridge.bzl", "rust_cxx_bridge")
rust_binary(
diff --git a/book/src/build/cmake.md b/book/src/build/cmake.md
index 4b50746c..478552e7 100644
--- a/book/src/build/cmake.md
+++ b/book/src/build/cmake.md
@@ -29,3 +29,19 @@ what is available in these links, feel free to make a PR adding it to this list.
- Tested on Windows 10 with GNU target, and on Linux
---
+
+- **<https://github.com/geekbrother/cxx-corrosion-cmake>**
+
+ - Improved rusty_cmake CMake file to use modern C++
+ - Rich examples of using different primitive types and Rust's Result return to C++
+ - MacOS and Linux only
+
+---
+
+- **<https://github.com/paandahl/cpp-with-rust>**
+
+ - Same blobstore example as the official demo, but inverted languages
+ - Minimal CMake configuration
+ - Tested on Linux, macOS, and Windows
+
+---
diff --git a/book/src/cxx.png b/book/src/cxx.png
index aeb7ca9b..07118aaf 100644
--- a/book/src/cxx.png
+++ b/book/src/cxx.png
Binary files differ
diff --git a/book/src/index.md b/book/src/index.md
index 7b03e7e1..7add044c 100644
--- a/book/src/index.md
+++ b/book/src/index.md
@@ -1,5 +1,5 @@
<div class="badges">
-<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&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" alt="docs-rs" height="28" class="badge"></a>
+<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>
</div>
# CXX — safe interop between Rust and C++
@@ -11,7 +11,7 @@ boundary effectively within this regime. CXX fills in the low level stuff so
that you get a safe binding, preventing the pitfalls of doing a foreign function
interface over unsafe C-style signatures.
-<div style="height:226px;padding:34px 0 24px">
+<div style="height:190px;width=718px;padding:44px 0 44px">
<object type="image/svg+xml" data="overview.svg"></object>
</div>
diff --git a/book/src/overview.svg b/book/src/overview.svg
index 65905471..df4fcf49 100644
--- a/book/src/overview.svg
+++ b/book/src/overview.svg
@@ -1,99 +1,444 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="696" height="224">
- <style>line, path, circle,rect,polygon {
- stroke: black;
- stroke-width: 2;
- stroke-opacity: 1;
- fill-opacity: 1;
- stroke-linecap: round;
- stroke-linejoin: miter;
- }
-
- text {
- fill: black;
- }
- rect.backdrop{
- stroke: none;
- fill: white;
- fill-opacity: 0;
- }
- .broken{
- stroke-dasharray: 8;
- }
- .filled{
- fill: black;
- }
- .bg_filled{
- fill: white;
- }
- .nofill{
- fill: white;
- fill-opacity: 0;
- }
-
- text {
- font-family: monospace;
- font-size: 14px;
- }
- </style>
- <defs>
- <marker id="arrow" viewBox="-2 -2 8 8" refX="4" refY="2" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
- <polygon points="0,0 0,4 4,2 0,0"></polygon>
- </marker>
- <marker id="diamond" viewBox="-2 -2 8 8" refX="4" refY="2" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
- <polygon points="0,2 2,0 4,2 2,4 0,2"></polygon>
- </marker>
- <marker id="circle" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
- <circle cx="4" cy="4" r="2" class="filled"></circle>
- </marker>
- <marker id="open_circle" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
- <circle cx="4" cy="4" r="2" class="bg_filled"></circle>
- </marker>
- <marker id="big_open_circle" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
- <circle cx="4" cy="4" r="3" class="bg_filled"></circle>
- </marker>
- </defs>
- <rect class="backdrop" x="0" y="0" width="696" height="224"></rect>
- <rect x="148" y="168" width="136" height="32" class="solid nofill" rx="4"></rect>
- <text x="162" y="188" >Rust bindings</text>
- <rect x="412" y="168" width="128" height="32" class="solid nofill" rx="4"></rect>
- <text x="426" y="188" >C++ bindings</text>
- <text x="272" y="28" >#[cxx::bridge] mod</text>
- <text x="250" y="44" >description of boundary</text>
- <line x1="220" y1="120" x2="220" y2="160" class="solid"></line>
- <polygon points="216,156 224,156 220,164" class="filled"></polygon>
- <line x1="476" y1="120" x2="476" y2="160" class="solid"></line>
- <polygon points="472,156 480,156 476,164" class="filled"></polygon>
- <text x="74" y="140" >Safe</text>
- <text x="34" y="156" >straightforward</text>
- <text x="530" y="156" >Straightforward</text>
- <polygon points="48,180 40,184 48,188" class="filled"></polygon>
- <line x1="48" y1="184" x2="144" y2="184" class="solid"></line>
- <polygon points="136,180 144,184 136,188" class="filled"></polygon>
- <polygon points="296,180 288,184 296,188" class="filled"></polygon>
- <line x1="296" y1="184" x2="408" y2="184" class="broken"></line>
- <polygon points="400,180 408,184 400,188" class="filled"></polygon>
- <polygon points="552,180 544,184 552,188" class="filled"></polygon>
- <line x1="552" y1="184" x2="648" y2="184" class="solid"></line>
- <polygon points="644,180 652,184 644,188" class="filled"></polygon>
- <text x="2" y="188" >Rust</text>
- <text x="2" y="204" >code</text>
- <text x="658" y="204" >code</text>
- <text x="202" y="108" >Macro expansion</text>
- <text x="370" y="108" >Code generation</text>
- <text x="58" y="172" >Rust APIs</text>
- <text x="298" y="172" >Hidden C ABI</text>
- <text x="562" y="172" >C++ APIs</text>
- <text x="658" y="188" >C++</text>
- <g>
- <path d="M 228,8 A 8,8 0,0,0 220,16" class="nofill"></path>
- <line x1="228" y1="8" x2="468" y2="8" class="solid"></line>
- <path d="M 468,8 A 8,8 0,0,1 476,16" class="nofill"></path>
- <line x1="220" y1="16" x2="220" y2="48" class="solid"></line>
- <line x1="476" y1="16" x2="476" y2="48" class="solid"></line>
- <path d="M 220,48 A 8,8 0,0,0 228,56" class="nofill"></path>
- <line x1="228" y1="56" x2="468" y2="56" class="solid"></line>
- <line x1="348" y1="56" x2="348" y2="120" class="solid"></line>
- <path d="M 476,48 A 8,8 0,0,1 468,56" class="nofill"></path>
- <line x1="220" y1="120" x2="476" y2="120" class="solid"></line>
- </g>
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="541.903pt" height="142.287pt" viewBox="0 0 541.903 142.287" version="1.1">
+<defs>
+<g>
+<symbol overflow="visible" id="glyph0-0">
+<path style="stroke:none;" d=""/>
+</symbol>
+<symbol overflow="visible" id="glyph0-1">
+<path style="stroke:none;" d="M 5.140625 -2.359375 L 6.234375 -2.359375 C 6.421875 -2.359375 6.890625 -2.359375 6.890625 -2.828125 C 6.890625 -3.296875 6.4375 -3.296875 6.234375 -3.296875 L 5.265625 -3.296875 L 5.515625 -5.46875 L 6.234375 -5.46875 C 6.421875 -5.46875 6.890625 -5.46875 6.890625 -5.921875 C 6.890625 -6.390625 6.4375 -6.390625 6.234375 -6.390625 L 5.65625 -6.390625 L 5.875 -8.125 C 5.9375 -8.59375 5.6875 -8.765625 5.421875 -8.765625 C 5.015625 -8.765625 4.984375 -8.390625 4.953125 -8.203125 L 4.71875 -6.390625 L 3.171875 -6.390625 L 3.40625 -8.125 C 3.453125 -8.59375 3.203125 -8.765625 2.9375 -8.765625 C 2.53125 -8.765625 2.5 -8.390625 2.46875 -8.203125 L 2.234375 -6.390625 L 1.140625 -6.390625 C 0.953125 -6.390625 0.484375 -6.390625 0.484375 -5.9375 C 0.484375 -5.46875 0.9375 -5.46875 1.140625 -5.46875 L 2.109375 -5.46875 L 1.84375 -3.296875 L 1.140625 -3.296875 C 0.953125 -3.296875 0.484375 -3.296875 0.484375 -2.84375 C 0.484375 -2.359375 0.9375 -2.359375 1.140625 -2.359375 L 1.71875 -2.359375 L 1.484375 -0.640625 C 1.40625 0 1.90625 0 1.953125 0 C 2.359375 0 2.390625 -0.375 2.421875 -0.5625 L 2.65625 -2.359375 L 4.203125 -2.359375 L 3.96875 -0.640625 C 3.890625 0 4.390625 0 4.4375 0 C 4.828125 0 4.875 -0.375 4.90625 -0.5625 Z M 3.046875 -5.46875 L 4.59375 -5.46875 L 4.328125 -3.296875 L 2.78125 -3.296875 Z M 3.046875 -5.46875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-2">
+<path style="stroke:none;" d="M 6.21875 -9.125 C 6.421875 -9.125 6.796875 -9.125 6.796875 -9.53125 C 6.796875 -9.953125 6.421875 -9.953125 6.21875 -9.953125 L 3.734375 -9.953125 C 3.25 -9.953125 3.15625 -9.828125 3.15625 -9.359375 L 3.15625 0.609375 C 3.15625 1.046875 3.234375 1.1875 3.734375 1.1875 L 6.21875 1.1875 C 6.421875 1.1875 6.796875 1.1875 6.796875 0.78125 C 6.796875 0.359375 6.421875 0.359375 6.21875 0.359375 L 4.09375 0.359375 L 4.09375 -9.125 Z M 6.21875 -9.125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-3">
+<path style="stroke:none;" d="M 4.21875 -9.359375 C 4.21875 -9.8125 4.125 -9.953125 3.640625 -9.953125 L 1.140625 -9.953125 C 0.953125 -9.953125 0.578125 -9.953125 0.578125 -9.53125 C 0.578125 -9.125 0.953125 -9.125 1.140625 -9.125 L 3.28125 -9.125 L 3.28125 0.359375 L 1.140625 0.359375 C 0.953125 0.359375 0.578125 0.359375 0.578125 0.78125 C 0.578125 1.1875 0.953125 1.1875 1.140625 1.1875 L 3.640625 1.1875 C 4.109375 1.1875 4.21875 1.0625 4.21875 0.609375 Z M 4.21875 -9.359375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph0-4">
+<path style="stroke:none;" d="M 4.15625 -3.921875 L 6.203125 -3.921875 C 6.390625 -3.921875 6.84375 -3.921875 6.84375 -4.375 C 6.84375 -4.84375 6.390625 -4.84375 6.203125 -4.84375 L 4.15625 -4.84375 L 4.15625 -6.90625 C 4.15625 -7.078125 4.15625 -7.546875 3.703125 -7.546875 C 3.234375 -7.546875 3.234375 -7.09375 3.234375 -6.90625 L 3.234375 -4.84375 L 1.171875 -4.84375 C 0.984375 -4.84375 0.53125 -4.84375 0.53125 -4.390625 C 0.53125 -3.921875 0.96875 -3.921875 1.171875 -3.921875 L 3.234375 -3.921875 L 3.234375 -1.859375 C 3.234375 -1.671875 3.234375 -1.21875 3.6875 -1.21875 C 4.15625 -1.21875 4.15625 -1.65625 4.15625 -1.859375 Z M 4.15625 -3.921875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-0">
+<path style="stroke:none;" d=""/>
+</symbol>
+<symbol overflow="visible" id="glyph1-1">
+<path style="stroke:none;" d="M 5.75 -1.546875 C 5.09375 -1.015625 4.359375 -0.75 3.5625 -0.75 C 2.359375 -0.75 1.59375 -1.8125 1.59375 -3.203125 C 1.59375 -4.390625 2.171875 -5.6875 3.59375 -5.6875 C 4.5625 -5.6875 4.96875 -5.46875 5.578125 -5.046875 L 5.75 -5.984375 C 4.921875 -6.46875 4.453125 -6.578125 3.59375 -6.578125 C 1.625 -6.578125 0.5 -4.828125 0.5 -3.203125 C 0.5 -1.359375 1.828125 0.140625 3.546875 0.140625 C 4.25 0.140625 5.046875 -0.03125 5.84375 -0.609375 C 5.84375 -0.640625 5.796875 -1.09375 5.78125 -1.140625 Z M 5.75 -1.546875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-2">
+<path style="stroke:none;" d="M 3.640625 -3.28125 L 6.1875 -6.375 L 4.984375 -6.375 L 3.171875 -4.046875 L 1.296875 -6.375 L 0.078125 -6.375 L 2.6875 -3.28125 L 0 0 L 1.1875 0 L 3.171875 -2.671875 L 5.203125 0 L 6.40625 0 Z M 3.640625 -3.28125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-3">
+<path style="stroke:none;" d="M 2.53125 -6.375 L 1.359375 -6.375 L 1.359375 -5.203125 L 2.53125 -5.203125 Z M 1.359375 -1.15625 L 1.359375 0 L 2.53125 0 L 2.53125 -1.15625 Z M 1.359375 -1.15625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-4">
+<path style="stroke:none;" d="M 2.1875 -9.953125 L 1.125 -9.953125 L 1.125 0 L 2.203125 0 L 2.203125 -0.640625 C 2.875 -0.015625 3.578125 0.140625 4.078125 0.140625 C 5.4375 0.140625 6.6875 -1.25 6.6875 -3.203125 C 6.6875 -4.96875 5.734375 -6.515625 4.40625 -6.515625 C 3.984375 -6.515625 3.0625 -6.421875 2.1875 -5.703125 Z M 2.203125 -4.828125 C 2.46875 -5.234375 2.984375 -5.65625 3.6875 -5.65625 C 4.5625 -5.65625 5.59375 -4.984375 5.59375 -3.203125 C 5.59375 -1.328125 4.421875 -0.71875 3.546875 -0.71875 C 3.140625 -0.71875 2.875 -0.859375 2.609375 -1.0625 C 2.265625 -1.359375 2.203125 -1.625 2.203125 -1.859375 Z M 2.203125 -4.828125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-5">
+<path style="stroke:none;" d="M 2.1875 -3.140625 C 2.1875 -4.59375 3.265625 -5.53125 4.5625 -5.546875 L 4.5625 -6.515625 C 3.25 -6.5 2.5 -5.734375 2.109375 -5.171875 L 2.109375 -6.4375 L 1.125 -6.4375 L 1.125 0 L 2.1875 0 Z M 2.1875 -3.140625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-6">
+<path style="stroke:none;" d="M 2.265625 -9.734375 L 1.03125 -9.734375 L 1.03125 -8.5 L 2.265625 -8.5 Z M 2.1875 -6.375 L 1.125 -6.375 L 1.125 0 L 2.1875 0 Z M 2.1875 -6.375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-7">
+<path style="stroke:none;" d="M 6.0625 -9.953125 L 5 -9.953125 L 5 -5.765625 C 4.34375 -6.3125 3.59375 -6.515625 2.984375 -6.515625 C 1.625 -6.515625 0.5 -5.046875 0.5 -3.1875 C 0.5 -1.328125 1.5625 0.140625 2.921875 0.140625 C 3.453125 0.140625 4.265625 -0.03125 4.984375 -0.734375 L 4.984375 0 L 6.0625 0 Z M 4.984375 -1.6875 C 4.640625 -1.078125 4.125 -0.71875 3.5 -0.71875 C 2.625 -0.71875 1.59375 -1.390625 1.59375 -3.171875 C 1.59375 -5.078125 2.8125 -5.65625 3.640625 -5.65625 C 4.203125 -5.65625 4.65625 -5.359375 4.984375 -4.890625 Z M 4.984375 -1.6875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-8">
+<path style="stroke:none;" d="M 4.890625 -5.65625 C 4.890625 -5.65625 4.921875 -5.625 4.9375 -5.59375 C 5.234375 -5.625 5.546875 -5.671875 6.078125 -5.671875 C 6.125 -5.671875 6.453125 -5.671875 6.8125 -5.640625 L 6.65625 -6.515625 C 6.390625 -6.515625 5.40625 -6.5 4.453125 -6.03125 C 3.984375 -6.4375 3.40625 -6.515625 3.125 -6.515625 C 1.875 -6.515625 0.875 -5.46875 0.875 -4.203125 C 0.875 -3.6875 1.03125 -3.21875 1.34375 -2.78125 C 1.015625 -2.328125 0.9375 -1.890625 0.9375 -1.546875 C 0.9375 -1.015625 1.140625 -0.65625 1.296875 -0.46875 C 0.5625 0 0.390625 0.609375 0.390625 1.015625 C 0.390625 2.0625 1.75 2.9375 3.5 2.9375 C 5.25 2.9375 6.625 2.09375 6.625 1 C 6.625 -1 4.296875 -1 3.71875 -1 L 2.5 -1 C 2.296875 -1 1.671875 -1 1.671875 -1.765625 C 1.671875 -2.078125 1.734375 -2.171875 1.828125 -2.296875 C 2.0625 -2.125 2.53125 -1.875 3.109375 -1.875 C 4.34375 -1.875 5.359375 -2.890625 5.359375 -4.203125 C 5.359375 -4.71875 5.171875 -5.25 4.875 -5.640625 Z M 3.125 -2.671875 C 2.5 -2.671875 1.859375 -3.09375 1.859375 -4.1875 C 1.859375 -5.46875 2.671875 -5.71875 3.109375 -5.71875 C 3.75 -5.71875 4.375 -5.296875 4.375 -4.203125 C 4.375 -2.921875 3.578125 -2.671875 3.125 -2.671875 Z M 3.734375 0.03125 C 4.046875 0.03125 5.625 0.03125 5.625 1.015625 C 5.625 1.671875 4.640625 2.15625 3.515625 2.15625 C 2.390625 2.15625 1.390625 1.703125 1.390625 1 C 1.390625 0.96875 1.390625 0.03125 2.484375 0.03125 Z M 3.734375 0.03125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-9">
+<path style="stroke:none;" d="M 5.84375 -3.234375 C 5.84375 -3.84375 5.78125 -4.71875 5.328125 -5.484375 C 4.734375 -6.46875 3.734375 -6.578125 3.3125 -6.578125 C 1.765625 -6.578125 0.46875 -5.09375 0.46875 -3.234375 C 0.46875 -1.328125 1.84375 0.140625 3.515625 0.140625 C 4.171875 0.140625 4.96875 -0.046875 5.75 -0.609375 C 5.75 -0.671875 5.703125 -1.125 5.703125 -1.140625 C 5.6875 -1.15625 5.671875 -1.484375 5.671875 -1.53125 C 4.8125 -0.8125 3.96875 -0.71875 3.546875 -0.71875 C 2.4375 -0.71875 1.484375 -1.703125 1.46875 -3.234375 Z M 1.546875 -4 C 1.796875 -4.96875 2.46875 -5.71875 3.3125 -5.71875 C 3.765625 -5.71875 4.75 -5.515625 4.984375 -4 Z M 1.546875 -4 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-10">
+<path style="stroke:none;" d="M 10 -4.3125 C 10 -5.3125 9.734375 -6.515625 8.0625 -6.515625 C 6.84375 -6.515625 6.171875 -5.671875 5.953125 -5.34375 C 5.6875 -6.25 4.90625 -6.515625 4.15625 -6.515625 C 2.984375 -6.515625 2.359375 -5.75 2.125 -5.453125 L 2.125 -6.4375 L 1.109375 -6.4375 L 1.109375 0 L 2.1875 0 L 2.1875 -3.578125 C 2.1875 -4.515625 2.5625 -5.65625 3.609375 -5.65625 C 4.9375 -5.65625 5 -4.75 5 -4.21875 L 5 0 L 6.09375 0 L 6.09375 -3.578125 C 6.09375 -4.515625 6.46875 -5.65625 7.515625 -5.65625 C 8.828125 -5.65625 8.90625 -4.75 8.90625 -4.21875 L 8.90625 0 L 10 0 Z M 10 -4.3125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-11">
+<path style="stroke:none;" d="M 6.578125 -3.15625 C 6.578125 -5.09375 5.15625 -6.578125 3.515625 -6.578125 C 1.828125 -6.578125 0.4375 -5.0625 0.4375 -3.15625 C 0.4375 -1.28125 1.859375 0.140625 3.5 0.140625 C 5.1875 0.140625 6.578125 -1.3125 6.578125 -3.15625 Z M 3.515625 -0.75 C 2.484375 -0.75 1.515625 -1.609375 1.515625 -3.296875 C 1.515625 -5.03125 2.59375 -5.71875 3.5 -5.71875 C 4.484375 -5.71875 5.5 -4.984375 5.5 -3.296875 C 5.5 -1.53125 4.46875 -0.75 3.515625 -0.75 Z M 3.515625 -0.75 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-12">
+<path style="stroke:none;" d="M 4.8125 -6.140625 C 3.90625 -6.5625 3.125 -6.578125 2.796875 -6.578125 C 2.46875 -6.578125 0.46875 -6.578125 0.46875 -4.71875 C 0.46875 -4.09375 0.8125 -3.65625 1.03125 -3.453125 C 1.546875 -3.015625 1.90625 -2.9375 2.75 -2.765625 C 3.234375 -2.671875 4.0625 -2.5 4.0625 -1.734375 C 4.0625 -0.75 2.9375 -0.75 2.734375 -0.75 C 2.171875 -0.75 1.328125 -0.90625 0.5625 -1.46875 L 0.390625 -0.484375 C 0.453125 -0.4375 1.4375 0.140625 2.75 0.140625 C 4.609375 0.140625 5.046875 -0.96875 5.046875 -1.828125 C 5.046875 -2.546875 4.609375 -3.015625 4.546875 -3.078125 C 4.015625 -3.625 3.578125 -3.71875 2.71875 -3.890625 C 2.1875 -3.984375 1.46875 -4.125 1.46875 -4.84375 C 1.46875 -5.734375 2.46875 -5.734375 2.65625 -5.734375 C 3.40625 -5.734375 4.015625 -5.5625 4.640625 -5.203125 Z M 4.8125 -6.140625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-13">
+<path style="stroke:none;" d="M 2.203125 -0.640625 C 2.703125 -0.203125 3.296875 0.140625 4.078125 0.140625 C 5.453125 0.140625 6.6875 -1.25 6.6875 -3.203125 C 6.6875 -4.9375 5.765625 -6.515625 4.4375 -6.515625 C 3.84375 -6.515625 2.921875 -6.328125 2.1875 -5.6875 L 2.1875 -6.375 L 1.125 -6.375 L 1.125 2.78125 L 2.203125 2.78125 Z M 2.203125 -4.8125 C 2.53125 -5.3125 3.078125 -5.625 3.671875 -5.625 C 4.734375 -5.625 5.59375 -4.546875 5.59375 -3.1875 C 5.59375 -1.75 4.609375 -0.71875 3.546875 -0.71875 C 3.140625 -0.71875 2.875 -0.859375 2.609375 -1.0625 C 2.25 -1.375 2.203125 -1.640625 2.203125 -1.859375 Z M 2.203125 -4.8125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-14">
+<path style="stroke:none;" d="M 2.453125 -5.53125 L 4.4375 -5.53125 L 4.4375 -6.375 L 2.453125 -6.375 L 2.453125 -8.1875 L 1.46875 -8.1875 L 1.46875 -6.375 L 0.265625 -6.375 L 0.265625 -5.53125 L 1.4375 -5.53125 L 1.4375 -1.671875 C 1.4375 -0.84375 1.625 0.140625 2.609375 0.140625 C 3.578125 0.140625 4.234375 -0.1875 4.671875 -0.421875 L 4.453125 -1.25 C 3.953125 -0.796875 3.421875 -0.75 3.171875 -0.75 C 2.53125 -0.75 2.453125 -1.421875 2.453125 -1.921875 Z M 2.453125 -5.53125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-15">
+<path style="stroke:none;" d="M 6.078125 -4.3125 C 6.078125 -5.1875 5.890625 -6.515625 4.15625 -6.515625 C 3.359375 -6.515625 2.671875 -6.15625 2.125 -5.46875 L 2.125 -6.4375 L 1.109375 -6.4375 L 1.109375 0 L 2.1875 0 L 2.1875 -3.578125 C 2.1875 -4.453125 2.53125 -5.65625 3.609375 -5.65625 C 4.953125 -5.65625 4.984375 -4.71875 4.984375 -4.21875 L 4.984375 0 L 6.078125 0 Z M 6.078125 -4.3125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-16">
+<path style="stroke:none;" d="M 2.484375 -5.53125 L 4.015625 -5.53125 L 4.015625 -6.375 L 2.453125 -6.375 L 2.453125 -8.09375 C 2.453125 -9.0625 3.265625 -9.234375 3.75 -9.234375 C 4.25 -9.234375 4.6875 -9.078125 4.859375 -9.015625 L 4.859375 -9.953125 C 4.765625 -9.984375 4.28125 -10.09375 3.765625 -10.09375 C 2.390625 -10.09375 1.421875 -9.046875 1.421875 -7.65625 L 1.421875 -6.375 L 0.375 -6.375 L 0.375 -5.53125 L 1.421875 -5.53125 L 1.421875 0 L 2.484375 0 Z M 2.484375 -5.53125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-17">
+<path style="stroke:none;" d="M 6.078125 -6.375 L 4.984375 -6.375 L 4.984375 -2.265625 C 4.984375 -1.171875 4.234375 -0.640625 3.296875 -0.640625 C 2.296875 -0.640625 2.1875 -1.015625 2.1875 -1.65625 L 2.1875 -6.375 L 1.109375 -6.375 L 1.109375 -1.59375 C 1.109375 -0.5625 1.4375 0.140625 2.609375 0.140625 C 3.015625 0.140625 4.140625 0.078125 5.015625 -0.71875 L 5.015625 0 L 6.078125 0 Z M 6.078125 -6.375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-18">
+<path style="stroke:none;" d="M 5.609375 -4.203125 C 5.609375 -5.578125 4.625 -6.578125 3.28125 -6.578125 C 2.421875 -6.578125 1.78125 -6.390625 1.078125 -5.984375 L 1.15625 -5.03125 C 1.796875 -5.5 2.453125 -5.75 3.28125 -5.75 C 3.9375 -5.75 4.515625 -5.21875 4.515625 -4.171875 L 4.515625 -3.578125 C 3.875 -3.5625 3.015625 -3.515625 2.15625 -3.234375 C 1.1875 -2.890625 0.625 -2.359375 0.625 -1.65625 C 0.625 -1.015625 1 0.140625 2.21875 0.140625 C 3.015625 0.140625 4.015625 -0.09375 4.546875 -0.53125 L 4.546875 0 L 5.609375 0 Z M 4.515625 -1.921875 C 4.515625 -1.640625 4.515625 -1.296875 4.046875 -1 C 3.65625 -0.765625 3.171875 -0.71875 2.953125 -0.71875 C 2.1875 -0.71875 1.65625 -1.140625 1.65625 -1.65625 C 1.65625 -2.640625 3.640625 -2.859375 4.515625 -2.859375 Z M 4.515625 -1.921875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-19">
+<path style="stroke:none;" d="M 6.203125 -6.375 L 5.140625 -6.375 C 4.46875 -4.671875 3.375 -1.859375 3.3125 -0.828125 L 3.296875 -0.828125 C 3.234375 -1.671875 2.46875 -3.578125 2.359375 -3.859375 L 1.328125 -6.375 L 0.203125 -6.375 L 2.875 0 L 2.359375 1.3125 C 2.046875 2.015625 1.84375 2.09375 1.578125 2.09375 C 1.375 2.09375 0.921875 2.046875 0.46875 1.875 L 0.5625 2.8125 C 0.640625 2.828125 1.125 2.921875 1.578125 2.921875 C 1.921875 2.921875 2.59375 2.921875 3.21875 1.34375 Z M 6.203125 -6.375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-20">
+<path style="stroke:none;" d="M 5.84375 -4.671875 C 7.40625 -5.125 8.25 -6.203125 8.25 -7.265625 C 8.25 -8.703125 6.71875 -9.953125 4.6875 -9.953125 L 1.3125 -9.953125 L 1.3125 0 L 2.515625 0 L 2.515625 -4.546875 L 4.75 -4.546875 L 7.40625 0 L 8.640625 0 Z M 2.515625 -5.40625 L 2.515625 -9.15625 L 4.53125 -9.15625 C 6.265625 -9.15625 7.109375 -8.234375 7.109375 -7.265625 C 7.109375 -6.390625 6.34375 -5.40625 4.53125 -5.40625 Z M 2.515625 -5.40625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-21">
+<path style="stroke:none;" d="M 8.171875 -1.65625 C 7.296875 -1 6.703125 -0.765625 5.453125 -0.765625 C 3.578125 -0.765625 2.171875 -2.703125 2.171875 -5 C 2.171875 -6.9375 3.328125 -9.21875 5.515625 -9.21875 C 6.453125 -9.21875 7.171875 -8.9375 7.890625 -8.453125 L 8.109375 -9.625 C 7.171875 -9.984375 6.46875 -10.109375 5.484375 -10.109375 C 3.046875 -10.109375 0.953125 -7.953125 0.953125 -4.984375 C 0.953125 -1.84375 3.25 0.125 5.34375 0.125 C 6.78125 0.125 7.09375 0.046875 8.265625 -0.65625 Z M 8.171875 -1.65625 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-22">
+<path style="stroke:none;" d="M 3 -9.953125 L 1.359375 -9.953125 L 1.359375 0 L 2.46875 0 L 2.46875 -8.84375 L 2.484375 -8.84375 C 2.6875 -7.875 5 -1.734375 5.546875 -0.296875 L 6.59375 -0.296875 C 7.078125 -1.53125 9.4375 -7.78125 9.703125 -8.859375 L 9.703125 0 L 10.8125 0 L 10.8125 -9.953125 L 9.1875 -9.953125 L 7.546875 -5.53125 C 6.796875 -3.53125 6.234375 -2.015625 6.09375 -1.359375 L 6.078125 -1.359375 C 6.03125 -1.609375 5.859375 -2.140625 5.671875 -2.703125 C 5.40625 -3.46875 5.40625 -3.5 5.171875 -4.09375 Z M 3 -9.953125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-23">
+<path style="stroke:none;" d="M 8.53125 -9.953125 L 7.296875 -9.953125 L 7.296875 -5.609375 L 2.53125 -5.609375 L 2.53125 -9.953125 L 1.296875 -9.953125 L 1.296875 0 L 2.53125 0 L 2.53125 -4.75 L 7.296875 -4.75 L 7.296875 0 L 8.53125 0 Z M 8.53125 -9.953125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-24">
+<path style="stroke:none;" d="M 5.265625 -9.953125 L 4 -9.953125 L 0.390625 0 L 1.453125 0 L 2.5 -2.90625 L 6.546875 -2.90625 L 7.609375 0 L 8.875 0 Z M 4.515625 -8.921875 L 6.234375 -3.71875 L 2.8125 -3.71875 Z M 4.515625 -8.921875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-25">
+<path style="stroke:none;" d="M 1.328125 -9.953125 L 1.328125 0 L 5.03125 0 C 7.0625 0 8.53125 -1.296875 8.53125 -2.703125 C 8.53125 -3.953125 7.28125 -4.984375 5.8125 -5.203125 C 7.484375 -5.671875 8.140625 -6.625 8.140625 -7.453125 C 8.140625 -8.75 6.671875 -9.953125 4.640625 -9.953125 Z M 2.5 -5.609375 L 2.5 -9.15625 L 4.265625 -9.15625 C 5.796875 -9.15625 7.03125 -8.390625 7.03125 -7.4375 C 7.03125 -6.4375 5.796875 -5.609375 4.28125 -5.609375 Z M 2.5 -0.796875 L 2.5 -4.75 L 4.40625 -4.75 C 6.25 -4.75 7.40625 -3.71875 7.40625 -2.71875 C 7.40625 -1.703125 6.234375 -0.796875 4.640625 -0.796875 Z M 2.5 -0.796875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-26">
+<path style="stroke:none;" d="M 2.53125 -9.953125 L 1.296875 -9.953125 L 1.296875 0 L 2.53125 0 Z M 2.53125 -9.953125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-27">
+<path style="stroke:none;" d="M 6.53125 -9.546875 C 5.9375 -9.875 5.21875 -10.25 3.9375 -10.25 C 2.015625 -10.25 0.78125 -8.875 0.78125 -7.4375 C 0.78125 -6.421875 1.390625 -5.765625 1.46875 -5.6875 C 2.171875 -4.984375 2.65625 -4.84375 3.578125 -4.625 C 4.796875 -4.3125 4.984375 -4.265625 5.453125 -3.78125 C 5.6875 -3.53125 5.90625 -3.0625 5.90625 -2.5625 C 5.90625 -1.578125 5.09375 -0.65625 3.859375 -0.65625 C 2.8125 -0.65625 1.6875 -1.078125 0.84375 -1.84375 L 0.625 -0.6875 C 1.9375 0.171875 3.203125 0.296875 3.859375 0.296875 C 5.703125 0.296875 7.015625 -1.125 7.015625 -2.71875 C 7.015625 -3.625 6.5625 -4.3125 6.25 -4.671875 C 5.59375 -5.375 5.0625 -5.515625 4.109375 -5.765625 C 3.125 -6.015625 2.765625 -6.09375 2.453125 -6.390625 C 2.265625 -6.59375 1.875 -6.953125 1.875 -7.609375 C 1.875 -8.484375 2.671875 -9.328125 3.9375 -9.328125 C 5.15625 -9.328125 5.796875 -8.84375 6.3125 -8.390625 Z M 6.53125 -9.546875 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-28">
+<path style="stroke:none;" d="M 6.078125 -4.3125 C 6.078125 -5.1875 5.890625 -6.515625 4.15625 -6.515625 C 3.171875 -6.515625 2.515625 -5.953125 2.171875 -5.515625 L 2.171875 -9.953125 L 1.109375 -9.953125 L 1.109375 0 L 2.1875 0 L 2.1875 -3.578125 C 2.1875 -4.453125 2.53125 -5.65625 3.609375 -5.65625 C 4.953125 -5.65625 4.984375 -4.71875 4.984375 -4.21875 L 4.984375 0 L 6.078125 0 Z M 6.078125 -4.3125 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-29">
+<path style="stroke:none;" d="M 9.328125 -6.375 L 8.28125 -6.375 L 7.421875 -3.453125 C 7.21875 -2.765625 6.8125 -1.421875 6.75 -0.796875 L 6.734375 -0.796875 C 6.703125 -1.140625 6.46875 -2.109375 6.171875 -3.125 L 5.21875 -6.375 L 4.234375 -6.375 L 3.40625 -3.5625 C 3.15625 -2.671875 2.8125 -1.4375 2.765625 -0.828125 L 2.75 -0.828125 C 2.734375 -1.109375 2.578125 -1.859375 2.3125 -2.828125 L 1.296875 -6.375 L 0.203125 -6.375 L 2.125 0 L 3.234375 0 C 3.765625 -1.8125 4.609375 -4.53125 4.6875 -5.53125 L 4.703125 -5.53125 C 4.734375 -4.953125 5.015625 -3.921875 5.125 -3.578125 L 6.140625 0 L 7.40625 0 Z M 9.328125 -6.375 "/>
+</symbol>
+<symbol overflow="visible" id="glyph1-30">
+<path style="stroke:none;" d="M 4.8125 -4.140625 C 6.78125 -4.140625 8.140625 -5.5625 8.140625 -7.0625 C 8.140625 -8.578125 6.75 -9.953125 4.8125 -9.953125 L 1.3125 -9.953125 L 1.3125 0 L 2.53125 0 L 2.53125 -4.140625 Z M 4.5 -9.15625 C 6.1875 -9.15625 7.015625 -8.140625 7.015625 -7.078125 C 7.015625 -5.9375 6.140625 -4.984375 4.5 -4.984375 L 2.515625 -4.984375 L 2.515625 -9.15625 Z M 4.5 -9.15625 "/>
+</symbol>
+</g>
+<clipPath id="clip1">
+ <path d="M 0 0 L 541.902344 0 L 541.902344 142.285156 L 0 142.285156 Z M 0 0 "/>
+</clipPath>
+<clipPath id="clip2">
+ <path d="M 102 92 L 245 92 L 245 142.285156 L 102 142.285156 Z M 102 92 "/>
+</clipPath>
+<clipPath id="clip3">
+ <path d="M 302 92 L 442 92 L 442 142.285156 L 302 142.285156 Z M 302 92 "/>
+</clipPath>
+<clipPath id="clip4">
+ <path d="M 17 101 L 67 101 L 67 142.285156 L 17 142.285156 Z M 17 101 "/>
+</clipPath>
+<clipPath id="clip5">
+ <path d="M 92 101 L 142 101 L 142 142.285156 L 92 142.285156 Z M 92 101 "/>
+</clipPath>
+<clipPath id="clip6">
+ <path d="M 205 101 L 255 101 L 255 142.285156 L 205 142.285156 Z M 205 101 "/>
+</clipPath>
+<clipPath id="clip7">
+ <path d="M 292 101 L 342 101 L 342 142.285156 L 292 142.285156 Z M 292 101 "/>
+</clipPath>
+<clipPath id="clip8">
+ <path d="M 402 101 L 452 101 L 452 142.285156 L 402 142.285156 Z M 402 101 "/>
+</clipPath>
+<clipPath id="clip9">
+ <path d="M 479 101 L 528 101 L 528 142.285156 L 479 142.285156 Z M 479 101 "/>
+</clipPath>
+</defs>
+<g id="surface1">
+<g clip-path="url(#clip1)" clip-rule="nonzero">
+<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 0 142.285156 L 543.933594 142.285156 L 543.933594 -0.535156 L 0 -0.535156 Z M 0 142.285156 "/>
+</g>
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 93.618469 13.681906 L -93.619813 13.681906 C -96.369813 13.681906 -98.600281 11.451438 -98.600281 8.701438 L -98.600281 -17.204812 C -98.600281 -19.954812 -96.369813 -22.185281 -93.619813 -22.185281 L 93.618469 -22.185281 C 96.368469 -22.185281 98.598937 -19.954812 98.598937 -17.204812 L 98.598937 8.701438 C 98.598937 11.451438 96.368469 13.681906 93.618469 13.681906 Z M 93.618469 13.681906 " transform="matrix(1,0,0,-1,272.612,14.428)"/>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph0-1" x="215.699" y="15.293"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph0-2" x="222.091667" y="15.293"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-1" x="229.467" y="15.293"/>
+ <use xlink:href="#glyph1-2" x="235.710466" y="15.293"/>
+ <use xlink:href="#glyph1-2" x="242.136129" y="15.293"/>
+ <use xlink:href="#glyph1-3" x="248.561792" y="15.293"/>
+ <use xlink:href="#glyph1-3" x="252.463959" y="15.293"/>
+ <use xlink:href="#glyph1-4" x="256.366125" y="15.293"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-5" x="263.184874" y="15.293"/>
+ <use xlink:href="#glyph1-6" x="267.959289" y="15.293"/>
+ <use xlink:href="#glyph1-7" x="271.263219" y="15.293"/>
+ <use xlink:href="#glyph1-8" x="278.469315" y="15.293"/>
+ <use xlink:href="#glyph1-9" x="285.493215" y="15.293"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph0-3" x="291.733" y="15.293"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-10" x="303.797" y="15.293"/>
+ <use xlink:href="#glyph1-11" x="314.905263" y="15.293"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-7" x="322.31651" y="15.293"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-7" x="203.901" y="29.24"/>
+ <use xlink:href="#glyph1-9" x="211.107096" y="29.24"/>
+ <use xlink:href="#glyph1-12" x="217.350563" y="29.24"/>
+ <use xlink:href="#glyph1-1" x="222.734691" y="29.24"/>
+ <use xlink:href="#glyph1-5" x="228.978158" y="29.24"/>
+ <use xlink:href="#glyph1-6" x="233.752573" y="29.24"/>
+ <use xlink:href="#glyph1-13" x="237.056503" y="29.24"/>
+ <use xlink:href="#glyph1-14" x="244.262599" y="29.24"/>
+ <use xlink:href="#glyph1-6" x="249.335415" y="29.24"/>
+ <use xlink:href="#glyph1-11" x="252.639345" y="29.24"/>
+ <use xlink:href="#glyph1-15" x="259.663245" y="29.24"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-11" x="271.546202" y="29.24"/>
+ <use xlink:href="#glyph1-16" x="278.570102" y="29.24"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-4" x="287.553692" y="29.24"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-11" x="295.147136" y="29.24"/>
+ <use xlink:href="#glyph1-17" x="302.171035" y="29.24"/>
+ <use xlink:href="#glyph1-15" x="309.377132" y="29.24"/>
+ <use xlink:href="#glyph1-7" x="316.583228" y="29.24"/>
+ <use xlink:href="#glyph1-18" x="323.789324" y="29.24"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-5" x="330.126041" y="29.24"/>
+ <use xlink:href="#glyph1-19" x="334.900456" y="29.24"/>
+</g>
+<g clip-path="url(#clip2)" clip-rule="nonzero">
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M -53.619813 -99.095437 L -144.807313 -99.095437 C -147.006531 -99.095437 -148.791688 -100.880594 -148.791688 -103.079812 L -148.791688 -118.025125 C -148.791688 -120.22825 -147.006531 -122.0095 -144.807313 -122.0095 L -53.619813 -122.0095 C -51.420594 -122.0095 -49.635438 -120.22825 -49.635438 -118.025125 L -49.635438 -103.079812 C -49.635438 -100.880594 -51.420594 -99.095437 -53.619813 -99.095437 Z M -53.619813 -99.095437 " transform="matrix(1,0,0,-1,272.612,14.428)"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-20" x="133.785" y="129.463"/>
+ <use xlink:href="#glyph1-17" x="142.825975" y="129.463"/>
+ <use xlink:href="#glyph1-12" x="150.032072" y="129.463"/>
+ <use xlink:href="#glyph1-14" x="155.4162" y="129.463"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-4" x="165.165878" y="129.463"/>
+ <use xlink:href="#glyph1-6" x="172.371974" y="129.463"/>
+ <use xlink:href="#glyph1-15" x="175.675904" y="129.463"/>
+ <use xlink:href="#glyph1-7" x="182.882" y="129.463"/>
+ <use xlink:href="#glyph1-6" x="190.088097" y="129.463"/>
+ <use xlink:href="#glyph1-15" x="193.392026" y="129.463"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-8" x="200.612469" y="129.463"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-12" x="207.622022" y="129.463"/>
+</g>
+<g clip-path="url(#clip3)" clip-rule="nonzero">
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 143.3255 -99.095437 L 55.102844 -99.095437 C 52.903625 -99.095437 51.118469 -100.880594 51.118469 -103.079812 L 51.118469 -118.025125 C 51.118469 -120.22825 52.903625 -122.0095 55.102844 -122.0095 L 143.3255 -122.0095 C 145.524719 -122.0095 147.309875 -120.22825 147.309875 -118.025125 L 147.309875 -103.079812 C 147.309875 -100.880594 145.524719 -99.095437 143.3255 -99.095437 Z M 143.3255 -99.095437 " transform="matrix(1,0,0,-1,272.612,14.428)"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-21" x="333.693" y="129.463"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph0-4" x="342.668" y="129.463"/>
+ <use xlink:href="#glyph0-4" x="350.050555" y="129.463"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-4" x="362.115" y="129.463"/>
+ <use xlink:href="#glyph1-6" x="369.321096" y="129.463"/>
+ <use xlink:href="#glyph1-15" x="372.625026" y="129.463"/>
+ <use xlink:href="#glyph1-7" x="379.831122" y="129.463"/>
+ <use xlink:href="#glyph1-6" x="387.037219" y="129.463"/>
+ <use xlink:href="#glyph1-15" x="390.341148" y="129.463"/>
+ <use xlink:href="#glyph1-8" x="397.547245" y="129.463"/>
+ <use xlink:href="#glyph1-12" x="404.571144" y="129.463"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-20" x="4.343" y="126.574"/>
+ <use xlink:href="#glyph1-17" x="13.383975" y="126.574"/>
+ <use xlink:href="#glyph1-12" x="20.590072" y="126.574"/>
+ <use xlink:href="#glyph1-14" x="25.9742" y="126.574"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-1" x="3.941" y="140.522"/>
+ <use xlink:href="#glyph1-11" x="10.184466" y="140.522"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-7" x="17.595713" y="140.522"/>
+ <use xlink:href="#glyph1-9" x="24.801809" y="140.522"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-21" x="514.177" y="126.574"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph0-4" x="523.151" y="126.574"/>
+ <use xlink:href="#glyph0-4" x="530.533555" y="126.574"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-1" x="514.177" y="140.522"/>
+ <use xlink:href="#glyph1-11" x="520.420466" y="140.522"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-7" x="527.831713" y="140.522"/>
+ <use xlink:href="#glyph1-9" x="535.037809" y="140.522"/>
+</g>
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 0.00128125 -22.931375 L 0.00128125 -68.032937 " transform="matrix(1,0,0,-1,272.612,14.428)"/>
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M -99.213563 -89.1345 L -99.213563 -68.032937 L 99.212219 -68.032937 L 99.212219 -89.1345 " transform="matrix(1,0,0,-1,272.612,14.428)"/>
+<path style="fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6.317146 0.0002575 C 5.539802 0.207289 2.129646 1.371351 0.00074 2.640882 L 0.00074 -2.640368 C 2.129646 -1.370836 5.539802 -0.206774 6.317146 0.0002575 Z M 6.317146 0.0002575 " transform="matrix(0,1,1,0,173.39818,103.56176)"/>
+<path style="fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6.317146 -0.00160125 C 5.539802 0.20543 2.129646 1.373399 0.00074 2.639024 L 0.00074 -2.63832 C 2.129646 -1.372695 5.539802 -0.204726 6.317146 -0.00160125 Z M 6.317146 -0.00160125 " transform="matrix(0,1,1,0,371.82582,103.56176)"/>
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M -227.619813 -110.552469 L -158.752625 -110.552469 " transform="matrix(1,0,0,-1,272.612,14.428)"/>
+<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 38.675781 124.980469 C 39.453125 125.1875 42.859375 126.351562 44.992188 127.621094 L 44.992188 122.339844 C 42.859375 123.609375 39.453125 124.777344 38.675781 124.980469 Z M 38.675781 124.980469 "/>
+<g clip-path="url(#clip4)" clip-rule="nonzero">
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6.316149 -0.00123125 C 5.538805 0.2058 2.132555 1.369862 -0.0002575 2.639394 L -0.0002575 -2.641856 C 2.132555 -1.372325 5.538805 -0.204356 6.316149 -0.00123125 Z M 6.316149 -0.00123125 " transform="matrix(-1,0,0,1,44.99193,124.9817)"/>
+</g>
+<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 120.171875 124.980469 C 119.398438 124.777344 115.988281 123.609375 113.859375 122.339844 L 113.859375 127.621094 C 115.988281 126.351562 119.398438 125.1875 120.171875 124.980469 Z M 120.171875 124.980469 "/>
+<g clip-path="url(#clip5)" clip-rule="nonzero">
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6.313975 0.00123125 C 5.540537 0.204356 2.130381 1.372325 0.001475 2.641856 L 0.001475 -2.639394 C 2.130381 -1.369862 5.540537 -0.2058 6.313975 0.00123125 Z M 6.313975 0.00123125 " transform="matrix(1,0,0,-1,113.8579,124.9817)"/>
+</g>
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:7.97021,5.97766;stroke-miterlimit:10;" d="M -39.6745 -110.552469 L 41.157531 -110.552469 " transform="matrix(1,0,0,-1,272.612,14.428)"/>
+<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 226.621094 124.980469 C 227.398438 125.1875 230.808594 126.351562 232.9375 127.621094 L 232.9375 122.339844 C 230.808594 123.609375 227.398438 124.777344 226.621094 124.980469 Z M 226.621094 124.980469 "/>
+<g clip-path="url(#clip6)" clip-rule="nonzero">
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6.317366 -0.00123125 C 5.540023 0.2058 2.129866 1.369862 0.00096 2.639394 L 0.00096 -2.641856 C 2.129866 -1.372325 5.540023 -0.204356 6.317366 -0.00123125 Z M 6.317366 -0.00123125 " transform="matrix(-1,0,0,1,232.93846,124.9817)"/>
+</g>
+<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 320.082031 124.980469 C 319.308594 124.777344 315.898438 123.609375 313.769531 122.339844 L 313.769531 127.621094 C 315.898438 126.351562 319.308594 125.1875 320.082031 124.980469 Z M 320.082031 124.980469 "/>
+<g clip-path="url(#clip7)" clip-rule="nonzero">
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6.313811 0.00123125 C 5.540374 0.204356 2.130217 1.372325 0.00131125 2.641856 L 0.00131125 -2.639394 C 2.130217 -1.369862 5.540374 -0.2058 6.313811 0.00123125 Z M 6.313811 0.00123125 " transform="matrix(1,0,0,-1,313.76822,124.9817)"/>
+</g>
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 157.270812 -110.552469 L 227.618469 -110.552469 " transform="matrix(1,0,0,-1,272.612,14.428)"/>
+<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 423.566406 124.980469 C 424.34375 125.1875 427.753906 126.351562 429.882812 127.621094 L 429.882812 122.339844 C 427.753906 123.609375 424.34375 124.777344 423.566406 124.980469 Z M 423.566406 124.980469 "/>
+<g clip-path="url(#clip8)" clip-rule="nonzero">
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6.317014 -0.00123125 C 5.53967 0.2058 2.129514 1.369862 0.0006075 2.639394 L 0.0006075 -2.641856 C 2.129514 -1.372325 5.53967 -0.204356 6.317014 -0.00123125 Z M 6.317014 -0.00123125 " transform="matrix(-1,0,0,1,429.88342,124.9817)"/>
+</g>
+<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 506.546875 124.980469 C 505.773438 124.777344 502.363281 123.609375 500.230469 122.339844 L 500.230469 127.621094 C 502.363281 126.351562 505.773438 125.1875 506.546875 124.980469 Z M 506.546875 124.980469 "/>
+<g clip-path="url(#clip9)" clip-rule="nonzero">
+<path style="fill:none;stroke-width:1.49442;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6.314805 0.00123125 C 5.541367 0.204356 2.131211 1.372325 -0.00160125 2.641856 L -0.00160125 -2.639394 C 2.131211 -1.369862 5.541367 -0.2058 6.314805 0.00123125 Z M 6.314805 0.00123125 " transform="matrix(1,0,0,-1,500.23207,124.9817)"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-22" x="148.925" y="75.603"/>
+ <use xlink:href="#glyph1-18" x="161.112097" y="75.603"/>
+ <use xlink:href="#glyph1-1" x="167.836161" y="75.603"/>
+ <use xlink:href="#glyph1-5" x="174.079627" y="75.603"/>
+ <use xlink:href="#glyph1-11" x="178.854042" y="75.603"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-9" x="190.554803" y="75.603"/>
+ <use xlink:href="#glyph1-2" x="196.798269" y="75.603"/>
+ <use xlink:href="#glyph1-13" x="203.223932" y="75.603"/>
+ <use xlink:href="#glyph1-18" x="210.430029" y="75.603"/>
+ <use xlink:href="#glyph1-15" x="217.154093" y="75.603"/>
+ <use xlink:href="#glyph1-12" x="224.360189" y="75.603"/>
+ <use xlink:href="#glyph1-6" x="229.744318" y="75.603"/>
+ <use xlink:href="#glyph1-11" x="233.048248" y="75.603"/>
+ <use xlink:href="#glyph1-15" x="240.072147" y="75.603"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-21" x="297.94" y="75.603"/>
+ <use xlink:href="#glyph1-11" x="306.914983" y="75.603"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-7" x="314.32623" y="75.603"/>
+ <use xlink:href="#glyph1-9" x="321.532326" y="75.603"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-8" x="332.452653" y="75.603"/>
+ <use xlink:href="#glyph1-9" x="339.476553" y="75.603"/>
+ <use xlink:href="#glyph1-15" x="345.720019" y="75.603"/>
+ <use xlink:href="#glyph1-9" x="352.926115" y="75.603"/>
+ <use xlink:href="#glyph1-5" x="359.169582" y="75.603"/>
+ <use xlink:href="#glyph1-18" x="363.943997" y="75.603"/>
+ <use xlink:href="#glyph1-14" x="370.668061" y="75.603"/>
+ <use xlink:href="#glyph1-6" x="375.740877" y="75.603"/>
+ <use xlink:href="#glyph1-11" x="379.044807" y="75.603"/>
+ <use xlink:href="#glyph1-15" x="386.068707" y="75.603"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-23" x="231.724" y="117.459"/>
+ <use xlink:href="#glyph1-6" x="241.569797" y="117.459"/>
+ <use xlink:href="#glyph1-7" x="244.873727" y="117.459"/>
+ <use xlink:href="#glyph1-7" x="252.079823" y="117.459"/>
+ <use xlink:href="#glyph1-9" x="259.285919" y="117.459"/>
+ <use xlink:href="#glyph1-15" x="265.529386" y="117.459"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-21" x="277.412343" y="117.459"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-24" x="291.078533" y="117.459"/>
+ <use xlink:href="#glyph1-25" x="300.360525" y="117.459"/>
+ <use xlink:href="#glyph1-26" x="309.68412" y="117.459"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-27" x="68.742" y="89.962"/>
+ <use xlink:href="#glyph1-18" x="76.546333" y="89.962"/>
+ <use xlink:href="#glyph1-16" x="83.270397" y="89.962"/>
+ <use xlink:href="#glyph1-9" x="87.56278" y="89.962"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-12" x="37.407" y="103.909"/>
+ <use xlink:href="#glyph1-14" x="42.791129" y="103.909"/>
+ <use xlink:href="#glyph1-5" x="47.863945" y="103.909"/>
+ <use xlink:href="#glyph1-18" x="52.638361" y="103.909"/>
+ <use xlink:href="#glyph1-6" x="59.362424" y="103.909"/>
+ <use xlink:href="#glyph1-8" x="62.666354" y="103.909"/>
+ <use xlink:href="#glyph1-28" x="69.690254" y="103.909"/>
+ <use xlink:href="#glyph1-14" x="76.89635" y="103.909"/>
+ <use xlink:href="#glyph1-16" x="81.969166" y="103.909"/>
+ <use xlink:href="#glyph1-11" x="86.261549" y="103.909"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-5" x="92.898102" y="103.909"/>
+ <use xlink:href="#glyph1-29" x="97.672517" y="103.909"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-18" x="106.832566" y="103.909"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-5" x="113.154936" y="103.909"/>
+ <use xlink:href="#glyph1-7" x="117.929351" y="103.909"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-20" x="51.871" y="117.857"/>
+ <use xlink:href="#glyph1-17" x="60.911975" y="117.857"/>
+ <use xlink:href="#glyph1-12" x="68.118072" y="117.857"/>
+ <use xlink:href="#glyph1-14" x="73.5022" y="117.857"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-24" x="83.251878" y="117.857"/>
+ <use xlink:href="#glyph1-30" x="92.533869" y="117.857"/>
+ <use xlink:href="#glyph1-26" x="101.467248" y="117.857"/>
+ <use xlink:href="#glyph1-12" x="105.286206" y="117.857"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-27" x="418.874" y="103.909"/>
+ <use xlink:href="#glyph1-14" x="426.678333" y="103.909"/>
+ <use xlink:href="#glyph1-5" x="431.751149" y="103.909"/>
+ <use xlink:href="#glyph1-18" x="436.525564" y="103.909"/>
+ <use xlink:href="#glyph1-6" x="443.249628" y="103.909"/>
+ <use xlink:href="#glyph1-8" x="446.553558" y="103.909"/>
+ <use xlink:href="#glyph1-28" x="453.577458" y="103.909"/>
+ <use xlink:href="#glyph1-14" x="460.783554" y="103.909"/>
+ <use xlink:href="#glyph1-16" x="465.85637" y="103.909"/>
+ <use xlink:href="#glyph1-11" x="470.148753" y="103.909"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-5" x="476.785306" y="103.909"/>
+ <use xlink:href="#glyph1-29" x="481.559721" y="103.909"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-18" x="490.705423" y="103.909"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-5" x="497.04214" y="103.909"/>
+ <use xlink:href="#glyph1-7" x="501.816555" y="103.909"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-21" x="436.031" y="117.857"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph0-4" x="445.005" y="117.857"/>
+ <use xlink:href="#glyph0-4" x="452.387555" y="117.857"/>
+</g>
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
+ <use xlink:href="#glyph1-24" x="464.452" y="117.857"/>
+ <use xlink:href="#glyph1-30" x="473.733991" y="117.857"/>
+ <use xlink:href="#glyph1-26" x="482.66737" y="117.857"/>
+ <use xlink:href="#glyph1-12" x="486.486329" y="117.857"/>
+</g>
+</g>
</svg>
diff --git a/book/src/tutorial.md b/book/src/tutorial.md
index c9fa00cb..2467282f 100644
--- a/book/src/tutorial.md
+++ b/book/src/tutorial.md
@@ -356,6 +356,7 @@ relative path of the Rust source file within the crate, and a `.rs.h` extension.
##include "cxx-demo/include/blobstore.h"
##include "cxx-demo/src/main.rs.h"
##include <functional>
+##include <string>
#
# BlobstoreClient::BlobstoreClient() {}
#
@@ -560,9 +561,9 @@ fn main() {
```cpp,hidelines
// include/blobstore.h
-#
-# #pragma once
-# #include "rust/cxx.h"
+
+##pragma once
+##include "rust/cxx.h"
# #include <memory>
struct MultiBuf;
diff --git a/book/theme/head.hbs b/book/theme/head.hbs
new file mode 100644
index 00000000..4210276b
--- /dev/null
+++ b/book/theme/head.hbs
@@ -0,0 +1,7 @@
+ <script async src="https://www.googletagmanager.com/gtag/js?id=G-DG41MK6DDN"></script>
+ <script>
+ window.dataLayer = window.dataLayer || [];
+ function gtag(){dataLayer.push(arguments);}
+ gtag('js', new Date());
+ gtag('config', 'G-DG41MK6DDN', {'anonymize_ip': true});
+ </script>
diff --git a/demo/BUCK b/demo/BUCK
index 43b83aad..8b3990ce 100644
--- a/demo/BUCK
+++ b/demo/BUCK
@@ -3,6 +3,7 @@ load("//tools/buck:rust_cxx_bridge.bzl", "rust_cxx_bridge")
rust_binary(
name = "demo",
srcs = glob(["src/**/*.rs"]),
+ edition = "2018",
deps = [
":blobstore-sys",
":bridge",
@@ -28,6 +29,6 @@ cxx_library(
cxx_library(
name = "blobstore-include",
+ exported_deps = ["//:core"],
exported_headers = ["include/blobstore.h"],
- deps = ["//:core"],
)
diff --git a/demo/BUILD b/demo/BUILD
index 4ab5ecb7..3f598fe2 100644
--- a/demo/BUILD
+++ b/demo/BUILD
@@ -1,10 +1,11 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
-load("@rules_rust//rust:rust.bzl", "rust_binary")
+load("@rules_rust//rust:defs.bzl", "rust_binary")
load("//tools/bazel:rust_cxx_bridge.bzl", "rust_cxx_bridge")
rust_binary(
name = "demo",
srcs = glob(["src/**/*.rs"]),
+ edition = "2018",
deps = [
":blobstore-sys",
":bridge",
diff --git a/demo/Cargo.toml b/demo/Cargo.toml
index 8115b1e4..cee0bc2c 100644
--- a/demo/Cargo.toml
+++ b/demo/Cargo.toml
@@ -2,11 +2,11 @@
name = "demo"
version = "0.0.0"
authors = ["David Tolnay <dtolnay@gmail.com>"]
-license = "MIT OR Apache-2.0"
description = "Toy project from https://github.com/dtolnay/cxx"
-repository = "https://github.com/dtolnay/cxx"
edition = "2018"
+license = "MIT OR Apache-2.0"
publish = false
+repository = "https://github.com/dtolnay/cxx"
[dependencies]
cxx = "1.0"
diff --git a/flags/Cargo.toml b/flags/Cargo.toml
index baf1157a..8958481c 100644
--- a/flags/Cargo.toml
+++ b/flags/Cargo.toml
@@ -1,11 +1,13 @@
[package]
name = "cxxbridge-flags"
-version = "1.0.54"
+version = "1.0.85"
authors = ["David Tolnay <dtolnay@gmail.com>"]
+categories = ["development-tools::ffi", "compilers"]
+description = "Compiler configuration of the `cxx` crate (implementation detail)"
edition = "2018"
license = "MIT OR Apache-2.0"
-description = "Compiler configuration of the `cxx` crate (implementation detail)"
repository = "https://github.com/dtolnay/cxx"
+rust-version = "1.48"
[features]
default = [] # c++11
diff --git a/gen/build/Cargo.toml b/gen/build/Cargo.toml
index 393fc1ce..ea19af89 100644
--- a/gen/build/Cargo.toml
+++ b/gen/build/Cargo.toml
@@ -1,31 +1,38 @@
[package]
name = "cxx-build"
-version = "1.0.54"
+version = "1.0.85"
authors = ["David Tolnay <dtolnay@gmail.com>"]
+categories = ["development-tools::build-utils", "development-tools::ffi"]
+description = "C++ code generator for integrating `cxx` crate into a Cargo build."
edition = "2018"
+exclude = ["build.rs"]
+homepage = "https://cxx.rs"
+keywords = ["ffi", "build-dependencies"]
license = "MIT OR Apache-2.0"
-description = "C++ code generator for integrating `cxx` crate into a Cargo build."
repository = "https://github.com/dtolnay/cxx"
-homepage = "https://cxx.rs"
-exclude = ["build.rs"]
-keywords = ["ffi"]
-categories = ["development-tools::ffi"]
+rust-version = "1.48"
[features]
parallel = ["cc/parallel"]
+# incomplete features that are not covered by a compatibility guarantee:
+experimental-async-fn = []
[dependencies]
cc = "1.0.49"
-codespan-reporting = "0.11"
-lazy_static = "1.4"
-proc-macro2 = { version = "1.0.26", default-features = false, features = ["span-locations"] }
+codespan-reporting = "0.11.1"
+once_cell = "1.9"
+proc-macro2 = { version = "1.0.39", default-features = false, features = ["span-locations"] }
quote = { version = "1.0", default-features = false }
scratch = "1.0"
-syn = { version = "1.0.70", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] }
+syn = { version = "1.0.95", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] }
[dev-dependencies]
+cxx = { version = "1.0", path = "../.." }
cxx-gen = { version = "0.7", path = "../lib" }
pkg-config = "0.3"
+[lib]
+doc-scrape-examples = false
+
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
diff --git a/gen/build/src/cargo.rs b/gen/build/src/cargo.rs
new file mode 100644
index 00000000..cbaa58a4
--- /dev/null
+++ b/gen/build/src/cargo.rs
@@ -0,0 +1,157 @@
+use crate::gen::{CfgEvaluator, CfgResult};
+use once_cell::sync::OnceCell;
+use std::borrow::Borrow;
+use std::cmp::Ordering;
+use std::collections::{BTreeMap as Map, BTreeSet as Set};
+use std::env;
+
+static ENV: OnceCell<CargoEnv> = OnceCell::new();
+
+struct CargoEnv {
+ features: Set<Name>,
+ cfgs: Map<Name, String>,
+}
+
+pub(super) struct CargoEnvCfgEvaluator;
+
+impl CfgEvaluator for CargoEnvCfgEvaluator {
+ fn eval(&self, name: &str, query_value: Option<&str>) -> CfgResult {
+ let env = ENV.get_or_init(CargoEnv::load);
+ if name == "feature" {
+ return if let Some(query_value) = query_value {
+ CfgResult::from(env.features.contains(Lookup::new(query_value)))
+ } else {
+ let msg = "expected `feature = \"...\"`".to_owned();
+ CfgResult::Undetermined { msg }
+ };
+ }
+ if name == "test" && query_value.is_none() {
+ 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();
+ return CfgResult::Undetermined { msg };
+ }
+ if let Some(cargo_value) = env.cfgs.get(Lookup::new(name)) {
+ return if let Some(query_value) = query_value {
+ CfgResult::from(cargo_value.split(',').any(|value| value == query_value))
+ } else {
+ CfgResult::True
+ };
+ }
+ if name == "debug_assertions" && query_value.is_none() {
+ return CfgResult::from(cfg!(debug_assertions));
+ }
+ CfgResult::False
+ }
+}
+
+impl CargoEnv {
+ fn load() -> Self {
+ const CARGO_FEATURE_PREFIX: &str = "CARGO_FEATURE_";
+ const CARGO_CFG_PREFIX: &str = "CARGO_CFG_";
+
+ let mut features = Set::new();
+ let mut cfgs = Map::new();
+ for (k, v) in env::vars_os() {
+ let k = match k.to_str() {
+ Some(k) => k,
+ None => continue,
+ };
+ let v = match v.into_string() {
+ Ok(v) => v,
+ Err(_) => continue,
+ };
+ if let Some(feature_name) = k.strip_prefix(CARGO_FEATURE_PREFIX) {
+ let feature_name = Name(feature_name.to_owned());
+ features.insert(feature_name);
+ } else if let Some(cfg_name) = k.strip_prefix(CARGO_CFG_PREFIX) {
+ let cfg_name = Name(cfg_name.to_owned());
+ cfgs.insert(cfg_name, v);
+ }
+ }
+ CargoEnv { features, cfgs }
+ }
+}
+
+struct Name(String);
+
+impl Ord for Name {
+ fn cmp(&self, rhs: &Self) -> Ordering {
+ Lookup::new(&self.0).cmp(Lookup::new(&rhs.0))
+ }
+}
+
+impl PartialOrd for Name {
+ fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
+ Some(self.cmp(rhs))
+ }
+}
+
+impl Eq for Name {}
+
+impl PartialEq for Name {
+ fn eq(&self, rhs: &Self) -> bool {
+ Lookup::new(&self.0).eq(Lookup::new(&rhs.0))
+ }
+}
+
+#[repr(transparent)]
+struct Lookup(str);
+
+impl Lookup {
+ fn new(name: &str) -> &Self {
+ unsafe { &*(name as *const str as *const Self) }
+ }
+}
+
+impl Borrow<Lookup> for Name {
+ fn borrow(&self) -> &Lookup {
+ Lookup::new(&self.0)
+ }
+}
+
+impl Ord for Lookup {
+ fn cmp(&self, rhs: &Self) -> Ordering {
+ self.0
+ .bytes()
+ .map(CaseAgnosticByte)
+ .cmp(rhs.0.bytes().map(CaseAgnosticByte))
+ }
+}
+
+impl PartialOrd for Lookup {
+ fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
+ Some(self.cmp(rhs))
+ }
+}
+
+impl Eq for Lookup {}
+
+impl PartialEq for Lookup {
+ fn eq(&self, rhs: &Self) -> bool {
+ self.0
+ .bytes()
+ .map(CaseAgnosticByte)
+ .eq(rhs.0.bytes().map(CaseAgnosticByte))
+ }
+}
+
+struct CaseAgnosticByte(u8);
+
+impl Ord for CaseAgnosticByte {
+ fn cmp(&self, rhs: &Self) -> Ordering {
+ self.0.to_ascii_lowercase().cmp(&rhs.0.to_ascii_lowercase())
+ }
+}
+
+impl PartialOrd for CaseAgnosticByte {
+ fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
+ Some(self.cmp(rhs))
+ }
+}
+
+impl Eq for CaseAgnosticByte {}
+
+impl PartialEq for CaseAgnosticByte {
+ fn eq(&self, rhs: &Self) -> bool {
+ self.cmp(rhs) == Ordering::Equal
+ }
+}
diff --git a/gen/build/src/cfg.rs b/gen/build/src/cfg.rs
index 6818bdaa..69eb6945 100644
--- a/gen/build/src/cfg.rs
+++ b/gen/build/src/cfg.rs
@@ -12,6 +12,8 @@ pub struct Cfg<'a> {
pub exported_header_prefixes: Vec<&'a str>,
/// See [`CFG.exported_header_links`][CFG#cfgexported_header_links].
pub exported_header_links: Vec<&'a str>,
+ /// See [`CFG.doxygen`][CFG#cfgdoxygen].
+ pub doxygen: bool,
marker: PhantomData<*const ()>, // !Send + !Sync
}
@@ -19,7 +21,7 @@ pub struct Cfg<'a> {
///
/// <br>
///
-/// <div style="float:right;margin:22px 50px 0;font-size:1.15em;color:#444"><strong>&amp;str</strong></div>
+/// <div style="float:right;margin:22px 50px 0;font-size:1.15em;opacity:.73"><strong>&amp;str</strong></div>
///
/// ## **`CFG.include_prefix`**
///
@@ -71,7 +73,7 @@ pub struct Cfg<'a> {
///
/// <br>
///
-/// <div style="float:right;margin:22px 50px 0;font-size:1.15em;color:#444"><strong>Vec&lt;&amp;Path&gt;</strong></div>
+/// <div style="float:right;margin:22px 50px 0;font-size:1.15em;opacity:.73"><strong>Vec&lt;&amp;Path&gt;</strong></div>
///
/// ## **`CFG.exported_header_dirs`**
///
@@ -146,7 +148,7 @@ pub struct Cfg<'a> {
///
/// <p style="margin:0"><br><br></p>
///
-/// <div style="float:right;margin:22px 50px 0;font-size:1.15em;color:#444"><strong>Vec&lt;&amp;str&gt;</strong></div>
+/// <div style="float:right;margin:22px 50px 0;font-size:1.15em;opacity:.73"><strong>Vec&lt;&amp;str&gt;</strong></div>
///
/// ## **`CFG.exported_header_prefixes`**
///
@@ -203,7 +205,7 @@ pub struct Cfg<'a> {
///
/// <p style="margin:0"><br><br></p>
///
-/// <div style="float:right;margin:22px 50px 0;font-size:1.15em;color:#444"><strong>Vec&lt;&amp;str&gt;</strong></div>
+/// <div style="float:right;margin:22px 50px 0;font-size:1.15em;opacity:.73"><strong>Vec&lt;&amp;str&gt;</strong></div>
///
/// ## **`CFG.exported_header_links`**
///
@@ -232,12 +234,84 @@ pub struct Cfg<'a> {
/// cxx_build::bridge("src/bridge.rs").compile("demo");
/// }
/// ```
+///
+/// <p style="margin:0"><br><br></p>
+///
+/// <div style="float:right;margin:22px 50px 0;font-size:1.15em;opacity:.73"><strong>bool</strong></div>
+///
+/// ## **`CFG.doxygen`**
+///
+/// Boolean. Whether to propagate Rust documentation from inside the cxx::bridge
+/// module as Doxygen-style comments in the generated C++ header.
+///
+/// Documentation on the following are supported:
+///
+/// - shared structs, and fields of shared structs
+/// - shared enums, and their variants
+/// - extern "Rust" opaque types
+/// - extern "Rust" functions, including methods/member functions
+///
+/// ### Example
+///
+/// ```no_run
+/// // build.rs
+///
+/// use cxx_build::CFG;
+///
+/// fn main() {
+/// CFG.doxygen = true;
+///
+/// cxx_build::bridge("src/bridge.rs").compile("demo");
+/// }
+/// ```
+///
+/// ```rust
+/// // src/bridge.rs
+///
+/// #[cxx::bridge]
+/// mod ffi {
+/// /// documentation of MyStruct
+/// pub struct MyStruct {
+/// /// documentation of the struct field
+/// lol: String,
+/// }
+///
+/// extern "Rust" {
+/// /// documentation of MyType
+/// type MyType;
+///
+/// /// function documentation
+/// fn asdf() -> bool;
+/// }
+/// }
+/// #
+/// # pub struct MyType;
+/// # fn asdf() -> bool { true }
+/// # fn main() {}
+/// ```
+///
+/// With `CFG.doxygen` enabled, the generated C++ header through which
+/// downstream C++ code will be able to access these shared structs and extern
+/// "Rust" signatures will have the Rust documentation comments propagated as
+/// Doxygen-style comments:
+///
+/// ```cpp
+/// /// documentation of MyStruct
+/// struct MyStruct final {
+/// /// documentation of the struct field
+/// ::rust::String lol;
+/// …
+/// };
+/// ```
+///
+/// Otherwise by default (without `CFG.doxygen`) they'll just be `//` comments.
#[cfg(doc)]
pub static mut CFG: Cfg = Cfg {
include_prefix: "",
exported_header_dirs: Vec::new(),
exported_header_prefixes: Vec::new(),
exported_header_links: Vec::new(),
+ doxygen: false,
marker: PhantomData,
};
@@ -248,6 +322,7 @@ impl<'a> Debug for Cfg<'a> {
exported_header_dirs,
exported_header_prefixes,
exported_header_links,
+ doxygen,
marker: _,
} = self;
formatter
@@ -256,6 +331,7 @@ impl<'a> Debug for Cfg<'a> {
.field("exported_header_dirs", exported_header_dirs)
.field("exported_header_prefixes", exported_header_prefixes)
.field("exported_header_links", exported_header_links)
+ .field("doxygen", doxygen)
.finish()
}
}
@@ -268,7 +344,7 @@ mod r#impl {
use crate::intern::{intern, InternedString};
use crate::syntax::map::UnorderedMap as Map;
use crate::vec::{self, InternedVec as _};
- use lazy_static::lazy_static;
+ use once_cell::sync::Lazy;
use std::cell::RefCell;
use std::fmt::{self, Debug};
use std::marker::PhantomData;
@@ -280,6 +356,7 @@ mod r#impl {
exported_header_dirs: Vec<InternedString>,
exported_header_prefixes: Vec<InternedString>,
exported_header_links: Vec<InternedString>,
+ doxygen: bool,
}
impl CurrentCfg {
@@ -290,18 +367,18 @@ mod r#impl {
let exported_header_dirs = Vec::new();
let exported_header_prefixes = Vec::new();
let exported_header_links = Vec::new();
+ let doxygen = false;
CurrentCfg {
include_prefix,
exported_header_dirs,
exported_header_prefixes,
exported_header_links,
+ doxygen,
}
}
}
- lazy_static! {
- static ref CURRENT: RwLock<CurrentCfg> = RwLock::new(CurrentCfg::default());
- }
+ static CURRENT: Lazy<RwLock<CurrentCfg>> = Lazy::new(|| RwLock::new(CurrentCfg::default()));
thread_local! {
// FIXME: If https://github.com/rust-lang/rust/issues/77425 is resolved,
@@ -329,11 +406,13 @@ mod r#impl {
let exported_header_dirs = current.exported_header_dirs.vec();
let exported_header_prefixes = current.exported_header_prefixes.vec();
let exported_header_links = current.exported_header_links.vec();
+ let doxygen = current.doxygen;
super::Cfg {
include_prefix,
exported_header_dirs,
exported_header_prefixes,
exported_header_links,
+ doxygen,
marker: PhantomData,
}
}
@@ -394,11 +473,20 @@ mod r#impl {
impl<'a> Drop for Cfg<'a> {
fn drop(&mut self) {
if let Cfg::Mut(cfg) = self {
+ let super::Cfg {
+ include_prefix,
+ exported_header_dirs,
+ exported_header_prefixes,
+ exported_header_links,
+ doxygen,
+ marker: _,
+ } = cfg;
let mut current = CURRENT.write().unwrap_or_else(PoisonError::into_inner);
- current.include_prefix = intern(cfg.include_prefix);
- current.exported_header_dirs = vec::intern(&cfg.exported_header_dirs);
- current.exported_header_prefixes = vec::intern(&cfg.exported_header_prefixes);
- current.exported_header_links = vec::intern(&cfg.exported_header_links);
+ current.include_prefix = intern(include_prefix);
+ current.exported_header_dirs = vec::intern(exported_header_dirs);
+ current.exported_header_prefixes = vec::intern(exported_header_prefixes);
+ current.exported_header_links = vec::intern(exported_header_links);
+ current.doxygen = *doxygen;
} else {
CONST_DEREFS.with(|derefs| derefs.borrow_mut().remove(&self.handle()));
}
diff --git a/gen/build/src/intern.rs b/gen/build/src/intern.rs
index 25b87061..c8b57d89 100644
--- a/gen/build/src/intern.rs
+++ b/gen/build/src/intern.rs
@@ -1,5 +1,5 @@
use crate::syntax::set::UnorderedSet as Set;
-use lazy_static::lazy_static;
+use once_cell::sync::OnceCell;
use std::sync::{Mutex, PoisonError};
#[derive(Copy, Clone, Default)]
@@ -12,11 +12,13 @@ impl InternedString {
}
pub fn intern(s: &str) -> InternedString {
- lazy_static! {
- static ref INTERN: Mutex<Set<&'static str>> = Mutex::new(Set::new());
- }
+ static INTERN: OnceCell<Mutex<Set<&'static str>>> = OnceCell::new();
+
+ let mut set = INTERN
+ .get_or_init(|| Mutex::new(Set::new()))
+ .lock()
+ .unwrap_or_else(PoisonError::into_inner);
- let mut set = INTERN.lock().unwrap_or_else(PoisonError::into_inner);
InternedString(match set.get(s) {
Some(interned) => *interned,
None => {
diff --git a/gen/build/src/lib.rs b/gen/build/src/lib.rs
index b8a463c3..225042c2 100644
--- a/gen/build/src/lib.rs
+++ b/gen/build/src/lib.rs
@@ -48,9 +48,11 @@
#![allow(
clippy::cast_sign_loss,
clippy::default_trait_access,
+ clippy::derive_partial_eq_without_eq,
clippy::doc_markdown,
clippy::drop_copy,
clippy::enum_glob_use,
+ clippy::explicit_auto_deref,
clippy::if_same_then_else,
clippy::inherent_to_string,
clippy::items_after_statements,
@@ -67,6 +69,7 @@
clippy::or_fun_call,
clippy::redundant_else,
clippy::shadow_unrelated,
+ clippy::significant_drop_in_scrutinee,
clippy::similar_names,
clippy::single_match_else,
clippy::struct_excessive_bools,
@@ -78,6 +81,7 @@
clippy::wrong_self_convention
)]
+mod cargo;
mod cfg;
mod deps;
mod error;
@@ -89,6 +93,7 @@ mod syntax;
mod target;
mod vec;
+use crate::cargo::CargoEnvCfgEvaluator;
use crate::deps::{Crate, HeaderDir};
use crate::error::{Error, Result};
use crate::gen::error::report;
@@ -393,6 +398,8 @@ fn make_include_dir(prj: &Project) -> Result<PathBuf> {
fn generate_bridge(prj: &Project, build: &mut Build, rust_source_file: &Path) -> Result<()> {
let opt = Opt {
allow_dot_includes: false,
+ cfg_evaluator: Box::new(CargoEnvCfgEvaluator),
+ doxygen: CFG.doxygen,
..Opt::default()
};
let generated = gen::generate_from_path(rust_source_file, &opt);
diff --git a/gen/build/src/out.rs b/gen/build/src/out.rs
index e275049c..a52aab25 100644
--- a/gen/build/src/out.rs
+++ b/gen/build/src/out.rs
@@ -1,13 +1,14 @@
use crate::error::{Error, Result};
use crate::gen::fs;
use crate::paths;
+use std::io;
use std::path::Path;
pub(crate) fn write(path: impl AsRef<Path>, content: &[u8]) -> Result<()> {
let path = path.as_ref();
let mut create_dir_error = None;
- if path.exists() {
+ if fs::exists(path) {
if let Ok(existing) = fs::read(path) {
if existing == content {
// Avoid bumping modified time with unchanged contents.
@@ -33,7 +34,7 @@ pub(crate) fn symlink_file(original: impl AsRef<Path>, link: impl AsRef<Path>) -
let link = link.as_ref();
let mut create_dir_error = None;
- if link.exists() {
+ if fs::exists(link) {
best_effort_remove(link);
} else {
let parent = link.parent().unwrap();
@@ -43,8 +44,22 @@ pub(crate) fn symlink_file(original: impl AsRef<Path>, link: impl AsRef<Path>) -
match paths::symlink_or_copy(original, link) {
// As long as symlink_or_copy succeeded, ignore any create_dir_all error.
Ok(()) => Ok(()),
- // If create_dir_all and symlink_or_copy both failed, prefer the first error.
- Err(err) => Err(Error::Fs(create_dir_error.unwrap_or(err))),
+ Err(err) => {
+ if err.kind() == io::ErrorKind::AlreadyExists {
+ // This is fine, a different simultaneous build script already
+ // created the same link or copy. The cxx_build target directory
+ // is laid out such that the same path never refers to two
+ // different targets during the same multi-crate build, so if
+ // some other build script already created the same path then we
+ // know it refers to the identical target that the current build
+ // script was trying to create.
+ Ok(())
+ } else {
+ // If create_dir_all and symlink_or_copy both failed, prefer the
+ // first error.
+ Err(Error::Fs(create_dir_error.unwrap_or(err)))
+ }
+ }
}
}
@@ -53,7 +68,7 @@ pub(crate) fn symlink_dir(original: impl AsRef<Path>, link: impl AsRef<Path>) ->
let link = link.as_ref();
let mut create_dir_error = None;
- if link.exists() {
+ if fs::exists(link) {
best_effort_remove(link);
} else {
let parent = link.parent().unwrap();
@@ -71,24 +86,34 @@ pub(crate) fn symlink_dir(original: impl AsRef<Path>, link: impl AsRef<Path>) ->
fn best_effort_remove(path: &Path) {
use std::fs;
- let file_type = match if cfg!(windows) {
+ if cfg!(windows) {
// On Windows, the correct choice of remove_file vs remove_dir needs to
// be used according to what the symlink *points to*. Trying to use
// remove_file to remove a symlink which points to a directory fails
// with "Access is denied".
- fs::metadata(path)
+ if let Ok(metadata) = fs::metadata(path) {
+ if metadata.is_dir() {
+ let _ = fs::remove_dir_all(path);
+ } else {
+ let _ = fs::remove_file(path);
+ }
+ } else if fs::symlink_metadata(path).is_ok() {
+ // The symlink might exist but be dangling, in which case there is
+ // no standard way to determine what "kind" of symlink it is. Try
+ // deleting both ways.
+ if fs::remove_dir_all(path).is_err() {
+ let _ = fs::remove_file(path);
+ }
+ }
} else {
// On non-Windows, we check metadata not following symlinks. All
// symlinks are removed using remove_file.
- fs::symlink_metadata(path)
- } {
- Ok(metadata) => metadata.file_type(),
- Err(_) => return,
- };
-
- if file_type.is_dir() {
- let _ = fs::remove_dir_all(path);
- } else {
- let _ = fs::remove_file(path);
+ if let Ok(metadata) = fs::symlink_metadata(path) {
+ if metadata.is_dir() {
+ let _ = fs::remove_dir_all(path);
+ } else {
+ let _ = fs::remove_file(path);
+ }
+ }
}
}
diff --git a/gen/cmd/Android.bp b/gen/cmd/Android.bp
index bff1cb4b..ffda7dbc 100644
--- a/gen/cmd/Android.bp
+++ b/gen/cmd/Android.bp
@@ -1,4 +1,5 @@
-// This file is generated by cargo2android.py --run --dependencies --add_workspace --host-first-multilib.
+// This file is generated by cargo2android.py --run --dependencies --add_workspace --host-first-multilib --no-pkg-vers.
+// Do not modify this file as changes will be overridden on upgrade.
package {
// See: http://go/android-license-faq
@@ -13,6 +14,7 @@ package {
rust_binary_host {
name: "cxxbridge",
crate_name: "cxxbridge",
+ cargo_env_compat: true,
srcs: ["src/main.rs"],
edition: "2018",
rustlibs: [
@@ -29,6 +31,7 @@ rust_binary_host {
rust_library_host {
name: "libcxxbridge_cmd",
crate_name: "cxxbridge_cmd",
+ cargo_env_compat: true,
srcs: ["src/lib.rs"],
edition: "2018",
rustlibs: [
@@ -40,20 +43,3 @@ rust_library_host {
],
compile_multilib: "first",
}
-
-// dependent_library ["feature_list"]
-// ansi_term-0.11.0
-// atty-0.2.14
-// bitflags-1.2.1 "default"
-// clap-2.33.3 "ansi_term,atty,color,default,strsim,suggestions,vec_map"
-// codespan-reporting-0.9.5
-// libc-0.2.80
-// proc-macro2-1.0.24 "span-locations"
-// quote-1.0.7
-// strsim-0.8.0
-// syn-1.0.50 "clone-impls,full,parsing,printing,quote"
-// termcolor-1.1.2
-// textwrap-0.11.0
-// unicode-width-0.1.8 "default"
-// unicode-xid-0.2.1 "default"
-// vec_map-0.8.2
diff --git a/gen/cmd/Cargo.toml b/gen/cmd/Cargo.toml
index 4b3a299f..39d9a617 100644
--- a/gen/cmd/Cargo.toml
+++ b/gen/cmd/Cargo.toml
@@ -1,26 +1,31 @@
[package]
name = "cxxbridge-cmd"
-version = "1.0.54"
+version = "1.0.85"
authors = ["David Tolnay <dtolnay@gmail.com>"]
-edition = "2018"
-license = "MIT OR Apache-2.0"
+categories = ["development-tools::build-utils", "development-tools::ffi"]
description = "C++ code generator for integrating `cxx` crate into a non-Cargo build."
-repository = "https://github.com/dtolnay/cxx"
-homepage = "https://cxx.rs"
+edition = "2018"
exclude = ["build.rs"]
+homepage = "https://cxx.rs"
keywords = ["ffi"]
-categories = ["development-tools::ffi"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/dtolnay/cxx"
+rust-version = "1.56"
[[bin]]
name = "cxxbridge"
path = "src/main.rs"
+[features]
+# incomplete features that are not covered by a compatibility guarantee:
+experimental-async-fn = []
+
[dependencies]
-clap = "2.33"
+clap = { version = "4", default-features = false, features = ["error-context", "help", "std", "suggestions", "usage"] }
codespan-reporting = "0.11"
-proc-macro2 = { version = "1.0.26", default-features = false, features = ["span-locations"] }
+proc-macro2 = { version = "1.0.39", default-features = false, features = ["span-locations"] }
quote = { version = "1.0", default-features = false }
-syn = { version = "1.0.70", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] }
+syn = { version = "1.0.95", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
diff --git a/gen/cmd/src/app.rs b/gen/cmd/src/app.rs
index c233ad77..bfad8562 100644
--- a/gen/cmd/src/app.rs
+++ b/gen/cmd/src/app.rs
@@ -3,14 +3,16 @@
mod test;
use super::{Opt, Output};
+use crate::cfg::{self, CfgValue};
use crate::gen::include::Include;
use crate::syntax::IncludeKind;
-use clap::AppSettings;
-use std::ffi::{OsStr, OsString};
+use clap::builder::{ArgAction, ValueParser};
+use clap::{Arg, Command};
+use std::collections::{BTreeMap as Map, BTreeSet as Set};
use std::path::PathBuf;
-
-type App = clap::App<'static, 'static>;
-type Arg = clap::Arg<'static, 'static>;
+use std::process;
+use std::sync::{Arc, Mutex, PoisonError};
+use syn::parse::Parser;
const USAGE: &str = "\
cxxbridge <input>.rs Emit .cc file for bridge to stdout
@@ -23,47 +25,56 @@ const TEMPLATE: &str = "\
David Tolnay <dtolnay@gmail.com>
https://github.com/dtolnay/cxx
-USAGE:
+{usage-heading}
{usage}
-ARGS:
-{positionals}
-OPTIONS:
-{unified}\
+{all-args}\
";
-fn app() -> App {
- let mut app = App::new("cxxbridge")
- .usage(USAGE)
- .template(TEMPLATE)
- .setting(AppSettings::NextLineHelp)
+fn app() -> Command {
+ let mut app = Command::new("cxxbridge")
+ .override_usage(USAGE)
+ .help_template(TEMPLATE)
+ .next_line_help(true)
+ .disable_help_flag(true)
+ .disable_version_flag(true)
.arg(arg_input())
+ .arg(arg_cfg())
.arg(arg_cxx_impl_annotations())
.arg(arg_header())
+ .arg(arg_help())
.arg(arg_include())
- .arg(arg_output())
- .help_message("Print help information.")
- .version_message("Print version information.");
+ .arg(arg_output());
if let Some(version) = option_env!("CARGO_PKG_VERSION") {
- app = app.version(version);
+ app = app.arg(arg_version()).version(version);
}
app
}
const INPUT: &str = "input";
+const CFG: &str = "cfg";
const CXX_IMPL_ANNOTATIONS: &str = "cxx-impl-annotations";
+const HELP: &str = "help";
const HEADER: &str = "header";
const INCLUDE: &str = "include";
const OUTPUT: &str = "output";
+const VERSION: &str = "version";
pub(super) fn from_args() -> Opt {
let matches = app().get_matches();
- let input = matches.value_of_os(INPUT).map(PathBuf::from);
- let cxx_impl_annotations = matches.value_of(CXX_IMPL_ANNOTATIONS).map(str::to_owned);
- let header = matches.is_present(HEADER);
+ if matches.get_flag(HELP) {
+ let _ = app().print_long_help();
+ process::exit(0);
+ }
+
+ let input = matches.get_one::<PathBuf>(INPUT).cloned();
+ let cxx_impl_annotations = matches
+ .get_one::<String>(CXX_IMPL_ANNOTATIONS)
+ .map(String::clone);
+ let header = matches.get_flag(HEADER);
let include = matches
- .values_of(INCLUDE)
+ .get_many::<String>(INCLUDE)
.unwrap_or_default()
.map(|include| {
if include.starts_with('<') && include.ends_with('>') {
@@ -81,38 +92,65 @@ pub(super) fn from_args() -> Opt {
.collect();
let mut outputs = Vec::new();
- for path in matches.values_of_os(OUTPUT).unwrap_or_default() {
- outputs.push(if path == "-" {
+ for path in matches.get_many::<PathBuf>(OUTPUT).unwrap_or_default() {
+ outputs.push(if path.as_os_str() == "-" {
Output::Stdout
} else {
- Output::File(PathBuf::from(path))
+ Output::File(path.clone())
});
}
if outputs.is_empty() {
outputs.push(Output::Stdout);
}
+ let mut cfg = Map::new();
+ for arg in matches.get_many::<String>(CFG).unwrap_or_default() {
+ let (name, value) = cfg::parse.parse_str(arg).unwrap();
+ cfg.entry(name).or_insert_with(Set::new).insert(value);
+ }
+
Opt {
input,
header,
cxx_impl_annotations,
include,
outputs,
- }
-}
-
-fn validate_utf8(arg: &OsStr) -> Result<(), OsString> {
- if arg.to_str().is_some() {
- Ok(())
- } else {
- Err(OsString::from("invalid utf-8 sequence"))
+ cfg,
}
}
fn arg_input() -> Arg {
- Arg::with_name(INPUT)
+ Arg::new(INPUT)
.help("Input Rust source file containing #[cxx::bridge].")
- .required_unless(HEADER)
+ .required_unless_present_any(&[HEADER, HELP])
+ .value_parser(ValueParser::path_buf())
+}
+
+fn arg_cfg() -> Arg {
+ const HELP: &str = "\
+Compilation configuration matching what will be used to build
+the Rust side of the bridge.";
+ let bool_cfgs = Arc::new(Mutex::new(Map::<String, bool>::new()));
+ Arg::new(CFG)
+ .long(CFG)
+ .num_args(1)
+ .value_name("name=\"value\" | name[=true] | name=false")
+ .action(ArgAction::Append)
+ .value_parser(move |arg: &str| match cfg::parse.parse_str(arg) {
+ Ok((_, CfgValue::Str(_))) => Ok(arg.to_owned()),
+ Ok((name, CfgValue::Bool(value))) => {
+ let mut bool_cfgs = bool_cfgs.lock().unwrap_or_else(PoisonError::into_inner);
+ if let Some(&prev) = bool_cfgs.get(&name) {
+ if prev != value {
+ return Err(format!("cannot have both {0}=false and {0}=true", name));
+ }
+ }
+ bool_cfgs.insert(name, value);
+ Ok(arg.to_owned())
+ }
+ Err(_) => Err("expected name=\"value\", name=true, or name=false".to_owned()),
+ })
+ .help(HELP)
}
fn arg_cxx_impl_annotations() -> Arg {
@@ -121,51 +159,59 @@ Optional annotation for implementations of C++ function wrappers
that may be exposed to Rust. You may for example need to provide
__declspec(dllexport) or __attribute__((visibility(\"default\")))
if Rust code from one shared object or executable depends on
-these C++ functions in another.
- ";
- Arg::with_name(CXX_IMPL_ANNOTATIONS)
+these C++ functions in another.";
+ Arg::new(CXX_IMPL_ANNOTATIONS)
.long(CXX_IMPL_ANNOTATIONS)
- .takes_value(true)
+ .num_args(1)
.value_name("annotation")
- .validator_os(validate_utf8)
+ .value_parser(ValueParser::string())
.help(HELP)
}
fn arg_header() -> Arg {
const HELP: &str = "\
Emit header with declarations only. Optional if using `-o` with
-a path ending in `.h`.
- ";
- Arg::with_name(HEADER).long(HEADER).help(HELP)
+a path ending in `.h`.";
+ Arg::new(HEADER).long(HEADER).num_args(0).help(HELP)
+}
+
+fn arg_help() -> Arg {
+ Arg::new(HELP)
+ .long(HELP)
+ .help("Print help information.")
+ .num_args(0)
}
fn arg_include() -> Arg {
const HELP: &str = "\
Any additional headers to #include. The cxxbridge tool does not
parse or even require the given paths to exist; they simply go
-into the generated C++ code as #include lines.
- ";
- Arg::with_name(INCLUDE)
+into the generated C++ code as #include lines.";
+ Arg::new(INCLUDE)
.long(INCLUDE)
- .short("i")
- .takes_value(true)
- .multiple(true)
- .number_of_values(1)
- .validator_os(validate_utf8)
+ .short('i')
+ .num_args(1)
+ .action(ArgAction::Append)
+ .value_parser(ValueParser::string())
.help(HELP)
}
fn arg_output() -> Arg {
const HELP: &str = "\
Path of file to write as output. Output goes to stdout if -o is
-not specified.
- ";
- Arg::with_name(OUTPUT)
+not specified.";
+ Arg::new(OUTPUT)
.long(OUTPUT)
- .short("o")
- .takes_value(true)
- .multiple(true)
- .number_of_values(1)
- .validator_os(validate_utf8)
+ .short('o')
+ .num_args(1)
+ .action(ArgAction::Append)
+ .value_parser(ValueParser::path_buf())
.help(HELP)
}
+
+fn arg_version() -> Arg {
+ Arg::new(VERSION)
+ .long(VERSION)
+ .help("Print version information.")
+ .action(ArgAction::Version)
+}
diff --git a/gen/cmd/src/cfg.rs b/gen/cmd/src/cfg.rs
new file mode 100644
index 00000000..29f0b9bc
--- /dev/null
+++ b/gen/cmd/src/cfg.rs
@@ -0,0 +1,93 @@
+use crate::gen::{CfgEvaluator, CfgResult};
+use std::collections::{BTreeMap as Map, BTreeSet as Set};
+use std::fmt::{self, Debug};
+use syn::parse::ParseStream;
+use syn::{Ident, LitBool, LitStr, Token};
+
+#[derive(Ord, PartialOrd, Eq, PartialEq)]
+pub enum CfgValue {
+ Bool(bool),
+ Str(String),
+}
+
+impl CfgValue {
+ const FALSE: Self = CfgValue::Bool(false);
+ const TRUE: Self = CfgValue::Bool(true);
+}
+
+pub struct FlagsCfgEvaluator {
+ map: Map<String, Set<CfgValue>>,
+}
+
+impl FlagsCfgEvaluator {
+ pub fn new(map: Map<String, Set<CfgValue>>) -> Self {
+ FlagsCfgEvaluator { map }
+ }
+}
+
+impl CfgEvaluator for FlagsCfgEvaluator {
+ fn eval(&self, name: &str, value: Option<&str>) -> CfgResult {
+ let set = self.map.get(name);
+ if let Some(value) = value {
+ if let Some(set) = set {
+ CfgResult::from(set.contains(&CfgValue::Str(value.to_owned())))
+ } else if name == "feature" {
+ CfgResult::False
+ } else {
+ let msg = format!(
+ "pass `--cfg {}=\"...\"` to be able to use this attribute",
+ name,
+ );
+ CfgResult::Undetermined { msg }
+ }
+ } else {
+ let (mut is_false, mut is_true) = (false, false);
+ if let Some(set) = set {
+ is_false = set.contains(&CfgValue::FALSE);
+ is_true = set.contains(&CfgValue::TRUE);
+ }
+ if is_false && is_true {
+ let msg = format!("the cxxbridge flags say both {0}=false and {0}=true", name);
+ CfgResult::Undetermined { msg }
+ } else if is_false {
+ CfgResult::False
+ } else if is_true {
+ CfgResult::True
+ } else {
+ let msg = format!(
+ "pass either `--cfg {0}=true` or `--cfg {0}=false` to be able to use this cfg attribute",
+ name,
+ );
+ CfgResult::Undetermined { msg }
+ }
+ }
+ }
+}
+
+impl Debug for CfgValue {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ CfgValue::Bool(value) => Debug::fmt(value, formatter),
+ CfgValue::Str(value) => Debug::fmt(value, formatter),
+ }
+ }
+}
+
+pub fn parse(input: ParseStream) -> syn::Result<(String, CfgValue)> {
+ let ident: Ident = input.parse()?;
+ let name = ident.to_string();
+ if input.is_empty() {
+ return Ok((name, CfgValue::TRUE));
+ }
+ input.parse::<Token![=]>()?;
+ let lookahead = input.lookahead1();
+ if lookahead.peek(LitBool) {
+ let lit: LitBool = input.parse()?;
+ Ok((name, CfgValue::Bool(lit.value)))
+ } else if lookahead.peek(LitStr) {
+ let lit: LitStr = input.parse()?;
+ Ok((name, CfgValue::Str(lit.value())))
+ } else {
+ Err(lookahead.error())
+ }
+}
diff --git a/gen/cmd/src/main.rs b/gen/cmd/src/main.rs
index 1c15db63..4d5edfd1 100644
--- a/gen/cmd/src/main.rs
+++ b/gen/cmd/src/main.rs
@@ -2,6 +2,7 @@
clippy::cast_sign_loss,
clippy::cognitive_complexity,
clippy::default_trait_access,
+ clippy::derive_partial_eq_without_eq,
clippy::enum_glob_use,
clippy::if_same_then_else,
clippy::inherent_to_string,
@@ -29,14 +30,17 @@
)]
mod app;
+mod cfg;
mod gen;
mod output;
mod syntax;
+use crate::cfg::{CfgValue, FlagsCfgEvaluator};
use crate::gen::error::{report, Result};
use crate::gen::fs;
use crate::gen::include::{self, Include};
use crate::output::Output;
+use std::collections::{BTreeMap as Map, BTreeSet as Set};
use std::io::{self, Write};
use std::path::PathBuf;
use std::process;
@@ -48,6 +52,7 @@ struct Opt {
cxx_impl_annotations: Option<String>,
include: Vec<Include>,
outputs: Vec<Output>,
+ cfg: Map<String, Set<CfgValue>>,
}
fn main() {
@@ -91,6 +96,7 @@ fn try_main() -> Result<()> {
cxx_impl_annotations: opt.cxx_impl_annotations,
gen_header,
gen_implementation,
+ cfg_evaluator: Box::new(FlagsCfgEvaluator::new(opt.cfg)),
..Default::default()
};
diff --git a/gen/cmd/src/test.rs b/gen/cmd/src/test.rs
index 17023e4d..c04c28e8 100644
--- a/gen/cmd/src/test.rs
+++ b/gen/cmd/src/test.rs
@@ -3,41 +3,45 @@ cxxbridge $VERSION
David Tolnay <dtolnay@gmail.com>
https://github.com/dtolnay/cxx
-USAGE:
+Usage:
cxxbridge <input>.rs Emit .cc file for bridge to stdout
cxxbridge <input>.rs --header Emit .h file for bridge to stdout
cxxbridge --header Emit \"rust/cxx.h\" header to stdout
-ARGS:
- <input>
- Input Rust source file containing #[cxx::bridge].
-
-OPTIONS:
- --cxx-impl-annotations <annotation>
- Optional annotation for implementations of C++ function wrappers
- that may be exposed to Rust. You may for example need to provide
- __declspec(dllexport) or __attribute__((visibility(\"default\")))
- if Rust code from one shared object or executable depends on
- these C++ functions in another.
- \x20
- -h, --help
- Print help information.
-
- --header
- Emit header with declarations only. Optional if using `-o` with
- a path ending in `.h`.
- \x20
- -i, --include <include>...
- Any additional headers to #include. The cxxbridge tool does not
- parse or even require the given paths to exist; they simply go
- into the generated C++ code as #include lines.
- \x20
- -o, --output <output>...
- Path of file to write as output. Output goes to stdout if -o is
- not specified.
- \x20
- -V, --version
- Print version information.
+Arguments:
+ [input]
+ Input Rust source file containing #[cxx::bridge].
+
+Options:
+ --cfg <name=\"value\" | name[=true] | name=false>
+ Compilation configuration matching what will be used to build
+ the Rust side of the bridge.
+
+ --cxx-impl-annotations <annotation>
+ Optional annotation for implementations of C++ function wrappers
+ that may be exposed to Rust. You may for example need to provide
+ __declspec(dllexport) or __attribute__((visibility(\"default\")))
+ if Rust code from one shared object or executable depends on
+ these C++ functions in another.
+
+ --header
+ Emit header with declarations only. Optional if using `-o` with
+ a path ending in `.h`.
+
+ --help
+ Print help information.
+
+ -i, --include <include>
+ Any additional headers to #include. The cxxbridge tool does not
+ parse or even require the given paths to exist; they simply go
+ into the generated C++ code as #include lines.
+
+ -o, --output <output>
+ Path of file to write as output. Output goes to stdout if -o is
+ not specified.
+
+ --version
+ Print version information.
";
#[test]
@@ -50,3 +54,9 @@ fn test_help() {
let expected = EXPECTED.replace("$VERSION", version);
assert_eq!(help, expected);
}
+
+#[test]
+fn test_cli() {
+ let app = super::app();
+ app.debug_assert();
+}
diff --git a/gen/lib/Cargo.toml b/gen/lib/Cargo.toml
index 37d81687..df8c8558 100644
--- a/gen/lib/Cargo.toml
+++ b/gen/lib/Cargo.toml
@@ -1,21 +1,24 @@
[package]
name = "cxx-gen"
-version = "0.7.54"
+version = "0.7.85"
authors = ["Adrian Taylor <adetaylor@chromium.org>"]
-edition = "2018"
-license = "MIT OR Apache-2.0"
+categories = ["development-tools::ffi"]
description = "C++ code generator for integrating `cxx` crate into higher level tools."
-repository = "https://github.com/dtolnay/cxx"
+edition = "2018"
exclude = ["build.rs"]
keywords = ["ffi"]
-categories = ["development-tools::ffi"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/dtolnay/cxx"
+rust-version = "1.48"
[dependencies]
-cc = "1.0.49"
codespan-reporting = "0.11"
-proc-macro2 = { version = "1.0.26", default-features = false, features = ["span-locations"] }
+proc-macro2 = { version = "1.0.39", default-features = false, features = ["span-locations"] }
quote = { version = "1.0", default-features = false }
-syn = { version = "1.0.70", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] }
+syn = { version = "1.0.95", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] }
+
+[lib]
+doc-scrape-examples = false
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
diff --git a/gen/lib/src/error.rs b/gen/lib/src/error.rs
index 26249be3..bb53a7fc 100644
--- a/gen/lib/src/error.rs
+++ b/gen/lib/src/error.rs
@@ -4,6 +4,7 @@
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display};
+#[allow(missing_docs)]
pub struct Error {
pub(crate) err: crate::gen::Error,
}
diff --git a/gen/lib/src/lib.rs b/gen/lib/src/lib.rs
index 411953b2..47cfa18d 100644
--- a/gen/lib/src/lib.rs
+++ b/gen/lib/src/lib.rs
@@ -7,10 +7,12 @@
//! [dtolnay/cxx#235]: https://github.com/dtolnay/cxx/issues/235
//! [https://github.com/google/autocxx]: https://github.com/google/autocxx
+#![deny(missing_docs)]
#![allow(dead_code)]
#![allow(
clippy::cast_sign_loss,
clippy::default_trait_access,
+ clippy::derive_partial_eq_without_eq,
clippy::enum_glob_use,
clippy::if_same_then_else,
clippy::inherent_to_string,
diff --git a/gen/src/builtin.rs b/gen/src/builtin.rs
index 7ac9209c..277c64f8 100644
--- a/gen/src/builtin.rs
+++ b/gen/src/builtin.rs
@@ -26,8 +26,8 @@ pub struct Builtins<'a> {
pub rust_str_repr: bool,
pub rust_slice_new: bool,
pub rust_slice_repr: bool,
- pub exception: bool,
pub relocatable: bool,
+ pub relocatable_or_array: bool,
pub friend_impl: bool,
pub is_complete: bool,
pub destroy: bool,
@@ -113,6 +113,11 @@ pub(super) fn write(out: &mut OutFile) {
include.sys_types = true;
}
+ if builtin.relocatable_or_array {
+ include.cstddef = true;
+ builtin.relocatable = true;
+ }
+
if builtin.relocatable {
include.type_traits = true;
}
@@ -132,6 +137,10 @@ pub(super) fn write(out: &mut OutFile) {
builtin.unsafe_bitcopy_t = true;
}
+ if builtin.trycatch {
+ builtin.ptr_len = true;
+ }
+
out.begin_block(Block::Namespace("rust"));
out.begin_block(Block::InlineNamespace("cxxbridge1"));
@@ -199,6 +208,26 @@ pub(super) fn write(out: &mut OutFile) {
writeln!(out, "inline Slice<T>::Slice(uninit) noexcept {{}}");
}
+ out.begin_block(Block::Namespace("repr"));
+
+ if builtin.repr_fat {
+ include.array = true;
+ include.cstdint = true;
+ out.next_section();
+ writeln!(out, "using Fat = ::std::array<::std::uintptr_t, 2>;");
+ }
+
+ if builtin.ptr_len {
+ include.cstddef = true;
+ out.next_section();
+ writeln!(out, "struct PtrLen final {{");
+ writeln!(out, " void *ptr;");
+ writeln!(out, " ::std::size_t len;");
+ writeln!(out, "}};");
+ }
+
+ out.end_block(Block::Namespace("repr"));
+
out.begin_block(Block::Namespace("detail"));
if builtin.maybe_uninit {
@@ -225,6 +254,21 @@ pub(super) fn write(out: &mut OutFile) {
writeln!(out, "}};");
}
+ if builtin.trycatch {
+ include.string = true;
+ out.next_section();
+ writeln!(out, "class Fail final {{");
+ writeln!(out, " ::rust::repr::PtrLen &throw$;");
+ writeln!(out, "public:");
+ writeln!(
+ out,
+ " Fail(::rust::repr::PtrLen &throw$) noexcept : throw$(throw$) {{}}",
+ );
+ writeln!(out, " void operator()(char const *) noexcept;");
+ writeln!(out, " void operator()(std::string const &) noexcept;");
+ writeln!(out, "}};");
+ }
+
out.end_block(Block::Namespace("detail"));
if builtin.manually_drop {
@@ -258,26 +302,6 @@ pub(super) fn write(out: &mut OutFile) {
out.begin_block(Block::AnonymousNamespace);
- if builtin.repr_fat {
- include.array = true;
- include.cstdint = true;
- out.next_section();
- out.begin_block(Block::Namespace("repr"));
- writeln!(out, "using Fat = ::std::array<::std::uintptr_t, 2>;");
- out.end_block(Block::Namespace("repr"));
- }
-
- if builtin.ptr_len {
- include.cstddef = true;
- out.next_section();
- out.begin_block(Block::Namespace("repr"));
- writeln!(out, "struct PtrLen final {{");
- writeln!(out, " void *ptr;");
- writeln!(out, " ::std::size_t len;");
- writeln!(out, "}};");
- out.end_block(Block::Namespace("repr"));
- }
-
if builtin.rust_str_new_unchecked || builtin.rust_str_repr {
out.next_section();
writeln!(out, "template <>");
@@ -328,7 +352,7 @@ pub(super) fn write(out: &mut OutFile) {
writeln!(out, "public:");
writeln!(out, " static Error error(repr::PtrLen repr) noexcept {{");
writeln!(out, " Error error;");
- writeln!(out, " error.msg = static_cast<const char *>(repr.ptr);");
+ writeln!(out, " error.msg = static_cast<char const *>(repr.ptr);");
writeln!(out, " error.len = repr.len;");
writeln!(out, " return error;");
writeln!(out, " }}");
@@ -357,6 +381,17 @@ pub(super) fn write(out: &mut OutFile) {
writeln!(out, "}};");
}
+ if builtin.relocatable_or_array {
+ out.next_section();
+ writeln!(out, "template <typename T>");
+ writeln!(out, "struct IsRelocatableOrArray : IsRelocatable<T> {{}};");
+ writeln!(out, "template <typename T, ::std::size_t N>");
+ writeln!(
+ out,
+ "struct IsRelocatableOrArray<T[N]> : IsRelocatableOrArray<T> {{}};",
+ );
+ }
+
out.end_block(Block::AnonymousNamespace);
out.end_block(Block::InlineNamespace("cxxbridge1"));
@@ -377,21 +412,11 @@ pub(super) fn write(out: &mut OutFile) {
writeln!(out, " missing>::value>::type");
writeln!(out, "trycatch(Try &&func, Fail &&fail) noexcept try {{");
writeln!(out, " func();");
- writeln!(out, "}} catch (const ::std::exception &e) {{");
+ writeln!(out, "}} catch (::std::exception const &e) {{");
writeln!(out, " fail(e.what());");
writeln!(out, "}}");
out.end_block(Block::Namespace("behavior"));
}
out.end_block(Block::Namespace("rust"));
-
- if builtin.exception {
- include.cstddef = true;
- out.begin_block(Block::ExternC);
- writeln!(
- out,
- "const char *cxxbridge1$exception(const char *, ::std::size_t);",
- );
- out.end_block(Block::ExternC);
- }
}
diff --git a/gen/src/cfg.rs b/gen/src/cfg.rs
new file mode 100644
index 00000000..da589085
--- /dev/null
+++ b/gen/src/cfg.rs
@@ -0,0 +1,133 @@
+use crate::gen::{CfgEvaluator, CfgResult};
+use crate::syntax::cfg::CfgExpr;
+use crate::syntax::report::Errors;
+use crate::syntax::Api;
+use quote::quote;
+use std::collections::BTreeSet as Set;
+use syn::Error;
+
+pub(super) struct UnsupportedCfgEvaluator;
+
+impl CfgEvaluator for UnsupportedCfgEvaluator {
+ fn eval(&self, name: &str, value: Option<&str>) -> CfgResult {
+ let _ = name;
+ let _ = value;
+ let msg = "cfg attribute is not supported".to_owned();
+ CfgResult::Undetermined { msg }
+ }
+}
+
+pub(super) fn strip(
+ cx: &mut Errors,
+ cfg_errors: &mut Set<String>,
+ cfg_evaluator: &dyn CfgEvaluator,
+ apis: &mut Vec<Api>,
+) {
+ apis.retain(|api| eval(cx, cfg_errors, cfg_evaluator, api.cfg()));
+ for api in apis {
+ match api {
+ Api::Struct(strct) => strct
+ .fields
+ .retain(|field| eval(cx, cfg_errors, cfg_evaluator, &field.cfg)),
+ Api::Enum(enm) => enm
+ .variants
+ .retain(|variant| eval(cx, cfg_errors, cfg_evaluator, &variant.cfg)),
+ _ => {}
+ }
+ }
+}
+
+pub(super) fn eval(
+ cx: &mut Errors,
+ cfg_errors: &mut Set<String>,
+ cfg_evaluator: &dyn CfgEvaluator,
+ expr: &CfgExpr,
+) -> bool {
+ match try_eval(cfg_evaluator, expr) {
+ Ok(value) => value,
+ Err(errors) => {
+ for error in errors {
+ if cfg_errors.insert(error.to_string()) {
+ cx.push(error);
+ }
+ }
+ false
+ }
+ }
+}
+
+fn try_eval(cfg_evaluator: &dyn CfgEvaluator, expr: &CfgExpr) -> Result<bool, Vec<Error>> {
+ match expr {
+ CfgExpr::Unconditional => Ok(true),
+ CfgExpr::Eq(ident, string) => {
+ let key = ident.to_string();
+ let value = string.as_ref().map(|string| string.value());
+ match cfg_evaluator.eval(&key, value.as_deref()) {
+ CfgResult::True => Ok(true),
+ CfgResult::False => Ok(false),
+ CfgResult::Undetermined { msg } => {
+ let span = quote!(#ident #string);
+ Err(vec![Error::new_spanned(span, msg)])
+ }
+ }
+ }
+ CfgExpr::All(list) => {
+ let mut all_errors = Vec::new();
+ for subexpr in list {
+ match try_eval(cfg_evaluator, subexpr) {
+ Ok(true) => {}
+ Ok(false) => return Ok(false),
+ Err(errors) => all_errors.extend(errors),
+ }
+ }
+ if all_errors.is_empty() {
+ Ok(true)
+ } else {
+ Err(all_errors)
+ }
+ }
+ CfgExpr::Any(list) => {
+ let mut all_errors = Vec::new();
+ for subexpr in list {
+ match try_eval(cfg_evaluator, subexpr) {
+ Ok(true) => return Ok(true),
+ Ok(false) => {}
+ Err(errors) => all_errors.extend(errors),
+ }
+ }
+ if all_errors.is_empty() {
+ Ok(false)
+ } else {
+ Err(all_errors)
+ }
+ }
+ CfgExpr::Not(subexpr) => match try_eval(cfg_evaluator, subexpr) {
+ Ok(value) => Ok(!value),
+ Err(errors) => Err(errors),
+ },
+ }
+}
+
+impl Api {
+ fn cfg(&self) -> &CfgExpr {
+ match self {
+ Api::Include(include) => &include.cfg,
+ Api::Struct(strct) => &strct.cfg,
+ Api::Enum(enm) => &enm.cfg,
+ Api::CxxType(ety) | Api::RustType(ety) => &ety.cfg,
+ Api::CxxFunction(efn) | Api::RustFunction(efn) => &efn.cfg,
+ Api::TypeAlias(alias) => &alias.cfg,
+ Api::Impl(imp) => &imp.cfg,
+ }
+ }
+}
+
+impl From<bool> for CfgResult {
+ fn from(value: bool) -> Self {
+ if value {
+ CfgResult::True
+ } else {
+ CfgResult::False
+ }
+ }
+}
diff --git a/gen/src/fs.rs b/gen/src/fs.rs
index 7053cc44..7bc3bbcb 100644
--- a/gen/src/fs.rs
+++ b/gen/src/fs.rs
@@ -13,6 +13,15 @@ pub(crate) struct Error {
message: String,
}
+impl Error {
+ pub fn kind(&self) -> io::ErrorKind {
+ match &self.source {
+ Some(io_error) => io_error.kind(),
+ None => io::ErrorKind::Other,
+ }
+ }
+}
+
impl Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(&self.message)
@@ -59,6 +68,13 @@ pub(crate) fn current_dir() -> Result<PathBuf> {
}
}
+pub(crate) fn exists(path: impl AsRef<Path>) -> bool {
+ let path = path.as_ref();
+ // If path is a symlink, this returns true, regardless of whether the
+ // symlink points to a path that exists.
+ std::fs::symlink_metadata(path).is_ok()
+}
+
pub(crate) fn read(path: impl AsRef<Path>) -> Result<Vec<u8>> {
let path = path.as_ref();
match std::fs::read(path) {
diff --git a/gen/src/mod.rs b/gen/src/mod.rs
index d8b90d0d..f24846a7 100644
--- a/gen/src/mod.rs
+++ b/gen/src/mod.rs
@@ -3,25 +3,31 @@
mod block;
mod builtin;
+mod cfg;
mod check;
pub(super) mod error;
mod file;
pub(super) mod fs;
mod ifndef;
pub(super) mod include;
+mod names;
mod namespace;
mod nested;
pub(super) mod out;
mod write;
-pub(super) use self::error::Error;
+use self::cfg::UnsupportedCfgEvaluator;
use self::error::{format_err, Result};
use self::file::File;
use self::include::Include;
+use crate::syntax::cfg::CfgExpr;
use crate::syntax::report::Errors;
-use crate::syntax::{self, Types};
+use crate::syntax::{self, attrs, Types};
+use std::collections::BTreeSet as Set;
use std::path::Path;
+pub(super) use self::error::Error;
+
/// Options for C++ code generation.
///
/// We expect options to be added over time, so this is a non-exhaustive struct.
@@ -52,6 +58,18 @@ pub struct Opt {
pub(super) gen_header: bool,
pub(super) gen_implementation: bool,
pub(super) allow_dot_includes: bool,
+ pub(super) cfg_evaluator: Box<dyn CfgEvaluator>,
+ pub(super) doxygen: bool,
+}
+
+pub(super) trait CfgEvaluator {
+ fn eval(&self, name: &str, value: Option<&str>) -> CfgResult;
+}
+
+pub(super) enum CfgResult {
+ True,
+ False,
+ Undetermined { msg: String },
}
/// Results of code generation.
@@ -71,6 +89,8 @@ impl Default for Opt {
gen_header: true,
gen_implementation: true,
allow_dot_includes: true,
+ cfg_evaluator: Box::new(UnsupportedCfgEvaluator),
+ doxygen: false,
}
}
}
@@ -116,20 +136,37 @@ pub(super) fn generate(syntax: File, opt: &Opt) -> Result<GeneratedCode> {
let ref mut apis = Vec::new();
let ref mut errors = Errors::new();
+ let ref mut cfg_errors = Set::new();
for bridge in syntax.modules {
- let ref namespace = bridge.namespace;
- let trusted = bridge.unsafety.is_some();
- apis.extend(syntax::parse_items(
+ let mut cfg = CfgExpr::Unconditional;
+ attrs::parse(
errors,
- bridge.content,
- trusted,
- namespace,
- ));
+ bridge.attrs,
+ attrs::Parser {
+ cfg: Some(&mut cfg),
+ ignore_unrecognized: true,
+ ..Default::default()
+ },
+ );
+ if cfg::eval(errors, cfg_errors, opt.cfg_evaluator.as_ref(), &cfg) {
+ let ref namespace = bridge.namespace;
+ let trusted = bridge.unsafety.is_some();
+ apis.extend(syntax::parse_items(
+ errors,
+ bridge.content,
+ trusted,
+ namespace,
+ ));
+ }
}
+ cfg::strip(errors, cfg_errors, opt.cfg_evaluator.as_ref(), apis);
+ errors.propagate()?;
+
let ref types = Types::collect(errors, apis);
check::precheck(errors, apis, opt);
errors.propagate()?;
+
let generator = check::Generator::Build;
check::typecheck(errors, apis, types, generator);
errors.propagate()?;
diff --git a/gen/src/names.rs b/gen/src/names.rs
new file mode 100644
index 00000000..834424bb
--- /dev/null
+++ b/gen/src/names.rs
@@ -0,0 +1,14 @@
+use crate::syntax::Pair;
+
+impl Pair {
+ pub fn to_fully_qualified(&self) -> String {
+ let mut fully_qualified = String::new();
+ for segment in &self.namespace {
+ fully_qualified += "::";
+ fully_qualified += &segment.to_string();
+ }
+ fully_qualified += "::";
+ fully_qualified += &self.cxx.to_string();
+ fully_qualified
+ }
+}
diff --git a/gen/src/nested.rs b/gen/src/nested.rs
index 2129d10f..32cc5f15 100644
--- a/gen/src/nested.rs
+++ b/gen/src/nested.rs
@@ -52,6 +52,7 @@ fn sort_by_inner_namespace(apis: Vec<&Api>, depth: usize) -> NamespaceEntries {
mod tests {
use super::NamespaceEntries;
use crate::syntax::attrs::OtherAttrs;
+ use crate::syntax::cfg::CfgExpr;
use crate::syntax::namespace::Namespace;
use crate::syntax::{Api, Doc, ExternType, ForeignName, Lang, Lifetimes, Pair};
use proc_macro2::{Ident, Span};
@@ -128,6 +129,7 @@ mod tests {
fn make_api(ns: Option<&str>, ident: &str) -> Api {
let ns = ns.map_or(Namespace::ROOT, |ns| syn::parse_str(ns).unwrap());
Api::CxxType(ExternType {
+ cfg: CfgExpr::Unconditional,
lang: Lang::Rust,
doc: Doc::new(),
derives: Vec::new(),
diff --git a/gen/src/write.rs b/gen/src/write.rs
index a3b9c9fa..6f535ccb 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -6,7 +6,7 @@ use crate::syntax::atom::Atom::{self, *};
use crate::syntax::instantiate::{ImplKey, NamedImplKey};
use crate::syntax::map::UnorderedMap as Map;
use crate::syntax::set::UnorderedSet;
-use crate::syntax::symbol::Symbol;
+use crate::syntax::symbol::{self, Symbol};
use crate::syntax::trivial::{self, TrivialReason};
use crate::syntax::{
derive, mangle, Api, Doc, Enum, EnumRepr, ExternFn, ExternType, Pair, Signature, Struct, Trait,
@@ -177,7 +177,7 @@ fn write_std_specializations(out: &mut OutFile, apis: &[Api]) {
writeln!(out, "template <> struct hash<{}> {{", qualified);
writeln!(
out,
- " ::std::size_t operator()(const {} &self) const noexcept {{",
+ " ::std::size_t operator()({} const &self) const noexcept {{",
qualified,
);
let link_name = mangle::operator(&strct.name, "hash");
@@ -227,6 +227,25 @@ fn pick_includes_and_builtins(out: &mut OutFile, apis: &[Api]) {
}
}
+fn write_doc(out: &mut OutFile, indent: &str, doc: &Doc) {
+ let mut lines = 0;
+ for line in doc.to_string().lines() {
+ if out.opt.doxygen {
+ writeln!(out, "{}///{}", indent, line);
+ } else {
+ writeln!(out, "{}//{}", indent, line);
+ }
+ lines += 1;
+ }
+ // According to https://www.doxygen.nl/manual/docblocks.html, Doxygen only
+ // interprets `///` as a Doxygen comment block if there are at least 2 of
+ // them. In Rust, a single `///` is definitely still documentation so we
+ // make sure to propagate that as a Doxygen comment.
+ if out.opt.doxygen && lines == 1 {
+ writeln!(out, "{}///", indent);
+ }
+}
+
fn write_struct<'a>(out: &mut OutFile<'a>, strct: &'a Struct, methods: &[&ExternFn]) {
let operator_eq = derive::contains(&strct.derives, Trait::PartialEq);
let operator_ord = derive::contains(&strct.derives, Trait::PartialOrd);
@@ -235,15 +254,11 @@ fn write_struct<'a>(out: &mut OutFile<'a>, strct: &'a Struct, methods: &[&Extern
let guard = format!("CXXBRIDGE1_STRUCT_{}", strct.name.to_symbol());
writeln!(out, "#ifndef {}", guard);
writeln!(out, "#define {}", guard);
- for line in strct.doc.to_string().lines() {
- writeln!(out, "//{}", line);
- }
+ write_doc(out, "", &strct.doc);
writeln!(out, "struct {} final {{", strct.name.cxx);
for field in &strct.fields {
- for line in field.doc.to_string().lines() {
- writeln!(out, " //{}", line);
- }
+ write_doc(out, " ", &field.doc);
write!(out, " ");
write_type_space(out, &field.ty);
writeln!(out, "{};", field.name.cxx);
@@ -255,9 +270,7 @@ fn write_struct<'a>(out: &mut OutFile<'a>, strct: &'a Struct, methods: &[&Extern
if !method.doc.is_empty() {
out.next_section();
}
- for line in method.doc.to_string().lines() {
- writeln!(out, " //{}", line);
- }
+ write_doc(out, " ", &method.doc);
write!(out, " ");
let sig = &method.sig;
let local_name = method.name.cxx.to_string();
@@ -272,12 +285,12 @@ fn write_struct<'a>(out: &mut OutFile<'a>, strct: &'a Struct, methods: &[&Extern
if operator_eq {
writeln!(
out,
- " bool operator==(const {} &) const noexcept;",
+ " bool operator==({} const &) const noexcept;",
strct.name.cxx,
);
writeln!(
out,
- " bool operator!=(const {} &) const noexcept;",
+ " bool operator!=({} const &) const noexcept;",
strct.name.cxx,
);
}
@@ -285,22 +298,22 @@ fn write_struct<'a>(out: &mut OutFile<'a>, strct: &'a Struct, methods: &[&Extern
if operator_ord {
writeln!(
out,
- " bool operator<(const {} &) const noexcept;",
+ " bool operator<({} const &) const noexcept;",
strct.name.cxx,
);
writeln!(
out,
- " bool operator<=(const {} &) const noexcept;",
+ " bool operator<=({} const &) const noexcept;",
strct.name.cxx,
);
writeln!(
out,
- " bool operator>(const {} &) const noexcept;",
+ " bool operator>({} const &) const noexcept;",
strct.name.cxx,
);
writeln!(
out,
- " bool operator>=(const {} &) const noexcept;",
+ " bool operator>=({} const &) const noexcept;",
strct.name.cxx,
);
}
@@ -318,6 +331,7 @@ fn write_struct_decl(out: &mut OutFile, ident: &Pair) {
fn write_enum_decl(out: &mut OutFile, enm: &Enum) {
let repr = match &enm.repr {
+ #[cfg(feature = "experimental-enum-variants-from-header")]
EnumRepr::Foreign { .. } => return,
EnumRepr::Native { atom, .. } => *atom,
};
@@ -335,9 +349,7 @@ fn write_opaque_type<'a>(out: &mut OutFile<'a>, ety: &'a ExternType, methods: &[
let guard = format!("CXXBRIDGE1_STRUCT_{}", ety.name.to_symbol());
writeln!(out, "#ifndef {}", guard);
writeln!(out, "#define {}", guard);
- for line in ety.doc.to_string().lines() {
- writeln!(out, "//{}", line);
- }
+ write_doc(out, "", &ety.doc);
out.builtin.opaque = true;
writeln!(
@@ -350,9 +362,7 @@ fn write_opaque_type<'a>(out: &mut OutFile<'a>, ety: &'a ExternType, methods: &[
if i > 0 && !method.doc.is_empty() {
out.next_section();
}
- for line in method.doc.to_string().lines() {
- writeln!(out, " //{}", line);
- }
+ write_doc(out, " ", &method.doc);
write!(out, " ");
let sig = &method.sig;
let local_name = method.name.cxx.to_string();
@@ -381,6 +391,7 @@ fn write_opaque_type<'a>(out: &mut OutFile<'a>, ety: &'a ExternType, methods: &[
fn write_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {
let repr = match &enm.repr {
+ #[cfg(feature = "experimental-enum-variants-from-header")]
EnumRepr::Foreign { .. } => return,
EnumRepr::Native { atom, .. } => *atom,
};
@@ -388,16 +399,12 @@ fn write_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {
let guard = format!("CXXBRIDGE1_ENUM_{}", enm.name.to_symbol());
writeln!(out, "#ifndef {}", guard);
writeln!(out, "#define {}", guard);
- for line in enm.doc.to_string().lines() {
- writeln!(out, "//{}", line);
- }
+ write_doc(out, "", &enm.doc);
write!(out, "enum class {} : ", enm.name.cxx);
write_atom(out, repr);
writeln!(out, " {{");
for variant in &enm.variants {
- for line in variant.doc.to_string().lines() {
- writeln!(out, " //{}", line);
- }
+ write_doc(out, " ", &variant.doc);
writeln!(out, " {} = {},", variant.name.cxx, variant.discriminant);
}
writeln!(out, "}};");
@@ -406,6 +413,7 @@ fn write_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {
fn check_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {
let repr = match &enm.repr {
+ #[cfg(feature = "experimental-enum-variants-from-header")]
EnumRepr::Foreign { .. } => return,
EnumRepr::Native { atom, .. } => *atom,
};
@@ -467,7 +475,25 @@ fn check_trivial_extern_type(out: &mut OutFile, alias: &TypeAlias, reasons: &[Tr
let id = alias.name.to_fully_qualified();
out.builtin.relocatable = true;
writeln!(out, "static_assert(");
- writeln!(out, " ::rust::IsRelocatable<{}>::value,", id);
+ if reasons
+ .iter()
+ .all(|r| matches!(r, TrivialReason::StructField(_) | TrivialReason::VecElement))
+ {
+ // If the type is only used as a struct field or Vec element, not as
+ // by-value function argument or return value, then C array of trivially
+ // relocatable type is also permissible.
+ //
+ // --- means something sane:
+ // struct T { char buf[N]; };
+ //
+ // --- means something totally different:
+ // void f(char buf[N]);
+ //
+ out.builtin.relocatable_or_array = true;
+ writeln!(out, " ::rust::IsRelocatableOrArray<{}>::value,", id);
+ } else {
+ writeln!(out, " ::rust::IsRelocatable<{}>::value,", id);
+ }
writeln!(
out,
" \"type {} should be trivially move constructible and trivially destructible in C++ to be used as {} in Rust\");",
@@ -484,7 +510,7 @@ fn write_struct_operator_decls<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
let link_name = mangle::operator(&strct.name, "eq");
writeln!(
out,
- "bool {}(const {1} &, const {1} &) noexcept;",
+ "bool {}({1} const &, {1} const &) noexcept;",
link_name, strct.name.cxx,
);
@@ -492,7 +518,7 @@ fn write_struct_operator_decls<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
let link_name = mangle::operator(&strct.name, "ne");
writeln!(
out,
- "bool {}(const {1} &, const {1} &) noexcept;",
+ "bool {}({1} const &, {1} const &) noexcept;",
link_name, strct.name.cxx,
);
}
@@ -502,14 +528,14 @@ fn write_struct_operator_decls<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
let link_name = mangle::operator(&strct.name, "lt");
writeln!(
out,
- "bool {}(const {1} &, const {1} &) noexcept;",
+ "bool {}({1} const &, {1} const &) noexcept;",
link_name, strct.name.cxx,
);
let link_name = mangle::operator(&strct.name, "le");
writeln!(
out,
- "bool {}(const {1} &, const {1} &) noexcept;",
+ "bool {}({1} const &, {1} const &) noexcept;",
link_name, strct.name.cxx,
);
@@ -517,14 +543,14 @@ fn write_struct_operator_decls<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
let link_name = mangle::operator(&strct.name, "gt");
writeln!(
out,
- "bool {}(const {1} &, const {1} &) noexcept;",
+ "bool {}({1} const &, {1} const &) noexcept;",
link_name, strct.name.cxx,
);
let link_name = mangle::operator(&strct.name, "ge");
writeln!(
out,
- "bool {}(const {1} &, const {1} &) noexcept;",
+ "bool {}({1} const &, {1} const &) noexcept;",
link_name, strct.name.cxx,
);
}
@@ -535,7 +561,7 @@ fn write_struct_operator_decls<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
let link_name = mangle::operator(&strct.name, "hash");
writeln!(
out,
- "::std::size_t {}(const {} &) noexcept;",
+ "::std::size_t {}({} const &) noexcept;",
link_name, strct.name.cxx,
);
}
@@ -554,7 +580,7 @@ fn write_struct_operators<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
out.next_section();
writeln!(
out,
- "bool {0}::operator==(const {0} &rhs) const noexcept {{",
+ "bool {0}::operator==({0} const &rhs) const noexcept {{",
strct.name.cxx,
);
let link_name = mangle::operator(&strct.name, "eq");
@@ -564,7 +590,7 @@ fn write_struct_operators<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
out.next_section();
writeln!(
out,
- "bool {0}::operator!=(const {0} &rhs) const noexcept {{",
+ "bool {0}::operator!=({0} const &rhs) const noexcept {{",
strct.name.cxx,
);
if derive::contains(&strct.derives, Trait::Eq) {
@@ -580,7 +606,7 @@ fn write_struct_operators<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
out.next_section();
writeln!(
out,
- "bool {0}::operator<(const {0} &rhs) const noexcept {{",
+ "bool {0}::operator<({0} const &rhs) const noexcept {{",
strct.name.cxx,
);
let link_name = mangle::operator(&strct.name, "lt");
@@ -590,7 +616,7 @@ fn write_struct_operators<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
out.next_section();
writeln!(
out,
- "bool {0}::operator<=(const {0} &rhs) const noexcept {{",
+ "bool {0}::operator<=({0} const &rhs) const noexcept {{",
strct.name.cxx,
);
let link_name = mangle::operator(&strct.name, "le");
@@ -600,7 +626,7 @@ fn write_struct_operators<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
out.next_section();
writeln!(
out,
- "bool {0}::operator>(const {0} &rhs) const noexcept {{",
+ "bool {0}::operator>({0} const &rhs) const noexcept {{",
strct.name.cxx,
);
if derive::contains(&strct.derives, Trait::Ord) {
@@ -614,7 +640,7 @@ fn write_struct_operators<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
out.next_section();
writeln!(
out,
- "bool {0}::operator>=(const {0} &rhs) const noexcept {{",
+ "bool {0}::operator>=({0} const &rhs) const noexcept {{",
strct.name.cxx,
);
if derive::contains(&strct.derives, Trait::Ord) {
@@ -688,25 +714,29 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
let mangled = mangle::extern_fn(efn, out.types);
write!(out, "{}(", mangled);
if let Some(receiver) = &efn.receiver {
- if !receiver.mutable {
- write!(out, "const ");
- }
write!(
out,
- "{} &self",
+ "{}",
out.types.resolve(&receiver.ty).name.to_fully_qualified(),
);
+ if !receiver.mutable {
+ write!(out, " const");
+ }
+ write!(out, " &self");
}
for (i, arg) in efn.args.iter().enumerate() {
if i > 0 || efn.receiver.is_some() {
write!(out, ", ");
}
if arg.ty == RustString {
- write!(out, "const ");
+ write_type_space(out, &arg.ty);
+ write!(out, "const *{}", arg.name.cxx);
} else if let Type::RustVec(_) = arg.ty {
- write!(out, "const ");
+ write_type_space(out, &arg.ty);
+ write!(out, "const *{}", arg.name.cxx);
+ } else {
+ write_extern_arg(out, arg);
}
- write_extern_arg(out, arg);
}
let indirect_return = indirect_return(efn, out.types);
if indirect_return {
@@ -826,17 +856,9 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
}
writeln!(out, ";");
if efn.throws {
- out.include.cstring = true;
- out.builtin.exception = true;
writeln!(out, " throw$.ptr = nullptr;");
writeln!(out, " }},");
- writeln!(out, " [&](const char *catch$) noexcept {{");
- writeln!(out, " throw$.len = ::std::strlen(catch$);");
- writeln!(
- out,
- " throw$.ptr = const_cast<char *>(::cxxbridge1$exception(catch$, throw$.len));",
- );
- writeln!(out, " }});");
+ writeln!(out, " ::rust::detail::Fail(throw$));");
writeln!(out, " return throw$;");
}
writeln!(out, "}}");
@@ -885,14 +907,15 @@ fn write_rust_function_decl_impl(
write!(out, "{}(", link_name);
let mut needs_comma = false;
if let Some(receiver) = &sig.receiver {
- if !receiver.mutable {
- write!(out, "const ");
- }
write!(
out,
- "{} &self",
+ "{}",
out.types.resolve(&receiver.ty).name.to_fully_qualified(),
);
+ if !receiver.mutable {
+ write!(out, " const");
+ }
+ write!(out, " &self");
needs_comma = true;
}
for arg in &sig.args {
@@ -908,8 +931,11 @@ fn write_rust_function_decl_impl(
}
match sig.ret.as_ref().unwrap() {
Type::Ref(ret) => {
- write_pointee_type(out, &ret.inner, ret.mutable);
- write!(out, " *");
+ write_type_space(out, &ret.inner);
+ if !ret.mutable {
+ write!(out, "const ");
+ }
+ write!(out, "*");
}
ret => write_type_space(out, ret),
}
@@ -988,9 +1014,7 @@ fn write_rust_function_shim_impl(
}
if sig.receiver.is_none() {
// Member functions already documented at their declaration.
- for line in doc.to_string().lines() {
- writeln!(out, "//{}", line);
- }
+ write_doc(out, "", doc);
}
write_rust_function_shim_decl(out, local_name, sig, indirect_call);
if out.header {
@@ -1014,8 +1038,11 @@ fn write_rust_function_shim_impl(
write!(out, "::rust::MaybeUninit<");
match sig.ret.as_ref().unwrap() {
Type::Ref(ret) => {
- write_pointee_type(out, &ret.inner, ret.mutable);
- write!(out, " *");
+ write_type_space(out, &ret.inner);
+ if !ret.mutable {
+ write!(out, "const ");
+ }
+ write!(out, "*");
}
ret => write_type(out, ret),
}
@@ -1134,11 +1161,11 @@ fn write_indirect_return_type(out: &mut OutFile, ty: &Type) {
write!(out, "*");
}
Type::Ref(ty) => {
+ write_type_space(out, &ty.inner);
if !ty.mutable {
write!(out, "const ");
}
- write_type(out, &ty.inner);
- write!(out, " *");
+ write!(out, "*");
}
_ => write_type(out, ty),
}
@@ -1160,11 +1187,11 @@ fn write_extern_return_type_space(out: &mut OutFile, ty: &Option<Type>) {
write!(out, "*");
}
Some(Type::Ref(ty)) => {
+ write_type_space(out, &ty.inner);
if !ty.mutable {
write!(out, "const ");
}
- write_type(out, &ty.inner);
- write!(out, " *");
+ write!(out, "*");
}
Some(Type::Str(_)) | Some(Type::SliceRef(_)) => {
out.builtin.repr_fat = true;
@@ -1230,22 +1257,28 @@ fn write_type(out: &mut OutFile, ty: &Type) {
write!(out, ">");
}
Type::Ref(r) => {
- write_pointee_type(out, &r.inner, r.mutable);
- write!(out, " &");
+ write_type_space(out, &r.inner);
+ if !r.mutable {
+ write!(out, "const ");
+ }
+ write!(out, "&");
}
Type::Ptr(p) => {
- write_pointee_type(out, &p.inner, p.mutable);
- write!(out, " *");
+ write_type_space(out, &p.inner);
+ if !p.mutable {
+ write!(out, "const ");
+ }
+ write!(out, "*");
}
Type::Str(_) => {
write!(out, "::rust::Str");
}
Type::SliceRef(slice) => {
write!(out, "::rust::Slice<");
+ write_type_space(out, &slice.inner);
if slice.mutability.is_none() {
- write!(out, "const ");
+ write!(out, "const");
}
- write_type(out, &slice.inner);
write!(out, ">");
}
Type::Fn(f) => {
@@ -1272,21 +1305,6 @@ fn write_type(out: &mut OutFile, ty: &Type) {
}
}
-// Write just the T type behind a &T or &mut T or *const T or *mut T.
-fn write_pointee_type(out: &mut OutFile, inner: &Type, mutable: bool) {
- if let Type::Ptr(_) = inner {
- write_type_space(out, inner);
- if !mutable {
- write!(out, "const");
- }
- } else {
- if !mutable {
- write!(out, "const ");
- }
- write_type(out, inner);
- }
-}
-
fn write_atom(out: &mut OutFile, atom: Atom) {
match atom {
Bool => write!(out, "bool"),
@@ -1372,7 +1390,9 @@ impl<'a> ToMangled for UniquePtr<'a> {
fn to_mangled(&self, types: &Types) -> Symbol {
match self {
UniquePtr::Ident(ident) => ident.to_mangled(types),
- UniquePtr::CxxVector(element) => element.to_mangled(types).prefix_with("std$vector$"),
+ UniquePtr::CxxVector(element) => {
+ symbol::join(&[&"std", &"vector", &element.to_mangled(types)])
+ }
}
}
}
@@ -1442,7 +1462,7 @@ fn write_rust_vec_extern(out: &mut OutFile, key: NamedImplKey) {
writeln!(
out,
- "void cxxbridge1$rust_vec${}$new(const ::rust::Vec<{}> *ptr) noexcept;",
+ "void cxxbridge1$rust_vec${}$new(::rust::Vec<{}> const *ptr) noexcept;",
instance, inner,
);
writeln!(
@@ -1452,17 +1472,17 @@ fn write_rust_vec_extern(out: &mut OutFile, key: NamedImplKey) {
);
writeln!(
out,
- "::std::size_t cxxbridge1$rust_vec${}$len(const ::rust::Vec<{}> *ptr) noexcept;",
+ "::std::size_t cxxbridge1$rust_vec${}$len(::rust::Vec<{}> const *ptr) noexcept;",
instance, inner,
);
writeln!(
out,
- "::std::size_t cxxbridge1$rust_vec${}$capacity(const ::rust::Vec<{}> *ptr) noexcept;",
+ "::std::size_t cxxbridge1$rust_vec${}$capacity(::rust::Vec<{}> const *ptr) noexcept;",
instance, inner,
);
writeln!(
out,
- "const {} *cxxbridge1$rust_vec${}$data(const ::rust::Vec<{0}> *ptr) noexcept;",
+ "{} const *cxxbridge1$rust_vec${}$data(::rust::Vec<{0}> const *ptr) noexcept;",
inner, instance,
);
writeln!(
@@ -1475,6 +1495,11 @@ fn write_rust_vec_extern(out: &mut OutFile, key: NamedImplKey) {
"void cxxbridge1$rust_vec${}$set_len(::rust::Vec<{}> *ptr, ::std::size_t len) noexcept;",
instance, inner,
);
+ writeln!(
+ out,
+ "void cxxbridge1$rust_vec${}$truncate(::rust::Vec<{}> *ptr, ::std::size_t len) noexcept;",
+ instance, inner,
+ );
}
fn write_rust_box_impl(out: &mut OutFile, key: NamedImplKey) {
@@ -1554,7 +1579,7 @@ fn write_rust_vec_impl(out: &mut OutFile, key: NamedImplKey) {
writeln!(out, "template <>");
begin_function_definition(out);
- writeln!(out, "const {} *Vec<{0}>::data() const noexcept {{", inner);
+ writeln!(out, "{} const *Vec<{0}>::data() const noexcept {{", inner);
writeln!(out, " return cxxbridge1$rust_vec${}$data(this);", instance);
writeln!(out, "}}");
@@ -1585,6 +1610,16 @@ fn write_rust_vec_impl(out: &mut OutFile, key: NamedImplKey) {
instance,
);
writeln!(out, "}}");
+
+ writeln!(out, "template <>");
+ begin_function_definition(out);
+ writeln!(out, "void Vec<{}>::truncate(::std::size_t len) {{", inner,);
+ writeln!(
+ out,
+ " return cxxbridge1$rust_vec${}$truncate(this, len);",
+ instance,
+ );
+ writeln!(out, "}}");
}
fn write_unique_ptr(out: &mut OutFile, key: NamedImplKey) {
@@ -1637,6 +1672,7 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
"static_assert(alignof(::std::unique_ptr<{}>) == alignof(void *), \"\");",
inner,
);
+ begin_function_definition(out);
writeln!(
out,
"void cxxbridge1$unique_ptr${}$null(::std::unique_ptr<{}> *ptr) noexcept {{",
@@ -1646,6 +1682,7 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
writeln!(out, "}}");
if can_construct_from_value {
out.builtin.maybe_uninit = true;
+ begin_function_definition(out);
writeln!(
out,
"{} *cxxbridge1$unique_ptr${}$uninit(::std::unique_ptr<{}> *ptr) noexcept {{",
@@ -1660,6 +1697,7 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
writeln!(out, " return uninit;");
writeln!(out, "}}");
}
+ begin_function_definition(out);
writeln!(
out,
"void cxxbridge1$unique_ptr${}$raw(::std::unique_ptr<{}> *ptr, {} *raw) noexcept {{",
@@ -1667,20 +1705,23 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) {
);
writeln!(out, " ::new (ptr) ::std::unique_ptr<{}>(raw);", inner);
writeln!(out, "}}");
+ begin_function_definition(out);
writeln!(
out,
- "const {} *cxxbridge1$unique_ptr${}$get(const ::std::unique_ptr<{}>& ptr) noexcept {{",
+ "{} const *cxxbridge1$unique_ptr${}$get(::std::unique_ptr<{}> const &ptr) noexcept {{",
inner, instance, inner,
);
writeln!(out, " return ptr.get();");
writeln!(out, "}}");
+ begin_function_definition(out);
writeln!(
out,
- "{} *cxxbridge1$unique_ptr${}$release(::std::unique_ptr<{}>& ptr) noexcept {{",
+ "{} *cxxbridge1$unique_ptr${}$release(::std::unique_ptr<{}> &ptr) noexcept {{",
inner, instance, inner,
);
writeln!(out, " return ptr.release();");
writeln!(out, "}}");
+ begin_function_definition(out);
writeln!(
out,
"void cxxbridge1$unique_ptr${}$drop(::std::unique_ptr<{}> *ptr) noexcept {{",
@@ -1724,6 +1765,7 @@ fn write_shared_ptr(out: &mut OutFile, key: NamedImplKey) {
"static_assert(alignof(::std::shared_ptr<{}>) == alignof(void *), \"\");",
inner,
);
+ begin_function_definition(out);
writeln!(
out,
"void cxxbridge1$shared_ptr${}$null(::std::shared_ptr<{}> *ptr) noexcept {{",
@@ -1733,6 +1775,7 @@ fn write_shared_ptr(out: &mut OutFile, key: NamedImplKey) {
writeln!(out, "}}");
if can_construct_from_value {
out.builtin.maybe_uninit = true;
+ begin_function_definition(out);
writeln!(
out,
"{} *cxxbridge1$shared_ptr${}$uninit(::std::shared_ptr<{}> *ptr) noexcept {{",
@@ -1747,20 +1790,23 @@ fn write_shared_ptr(out: &mut OutFile, key: NamedImplKey) {
writeln!(out, " return uninit;");
writeln!(out, "}}");
}
+ begin_function_definition(out);
writeln!(
out,
- "void cxxbridge1$shared_ptr${}$clone(const ::std::shared_ptr<{}>& self, ::std::shared_ptr<{}> *ptr) noexcept {{",
+ "void cxxbridge1$shared_ptr${}$clone(::std::shared_ptr<{}> const &self, ::std::shared_ptr<{}> *ptr) noexcept {{",
instance, inner, inner,
);
writeln!(out, " ::new (ptr) ::std::shared_ptr<{}>(self);", inner);
writeln!(out, "}}");
+ begin_function_definition(out);
writeln!(
out,
- "const {} *cxxbridge1$shared_ptr${}$get(const ::std::shared_ptr<{}>& self) noexcept {{",
+ "{} const *cxxbridge1$shared_ptr${}$get(::std::shared_ptr<{}> const &self) noexcept {{",
inner, instance, inner,
);
writeln!(out, " return self.get();");
writeln!(out, "}}");
+ begin_function_definition(out);
writeln!(
out,
"void cxxbridge1$shared_ptr${}$drop(::std::shared_ptr<{}> *self) noexcept {{",
@@ -1795,23 +1841,26 @@ fn write_weak_ptr(out: &mut OutFile, key: NamedImplKey) {
);
writeln!(out, " ::new (ptr) ::std::weak_ptr<{}>();", inner);
writeln!(out, "}}");
+ begin_function_definition(out);
writeln!(
out,
- "void cxxbridge1$weak_ptr${}$clone(const ::std::weak_ptr<{}>& self, ::std::weak_ptr<{}> *ptr) noexcept {{",
+ "void cxxbridge1$weak_ptr${}$clone(::std::weak_ptr<{}> const &self, ::std::weak_ptr<{}> *ptr) noexcept {{",
instance, inner, inner,
);
writeln!(out, " ::new (ptr) ::std::weak_ptr<{}>(self);", inner);
writeln!(out, "}}");
+ begin_function_definition(out);
writeln!(
out,
- "void cxxbridge1$weak_ptr${}$downgrade(const ::std::shared_ptr<{}>& shared, ::std::weak_ptr<{}> *weak) noexcept {{",
+ "void cxxbridge1$weak_ptr${}$downgrade(::std::shared_ptr<{}> const &shared, ::std::weak_ptr<{}> *weak) noexcept {{",
instance, inner, inner,
);
writeln!(out, " ::new (weak) ::std::weak_ptr<{}>(shared);", inner);
writeln!(out, "}}");
+ begin_function_definition(out);
writeln!(
out,
- "void cxxbridge1$weak_ptr${}$upgrade(const ::std::weak_ptr<{}>& weak, ::std::shared_ptr<{}> *shared) noexcept {{",
+ "void cxxbridge1$weak_ptr${}$upgrade(::std::weak_ptr<{}> const &weak, ::std::shared_ptr<{}> *shared) noexcept {{",
instance, inner, inner,
);
writeln!(
@@ -1820,6 +1869,7 @@ fn write_weak_ptr(out: &mut OutFile, key: NamedImplKey) {
inner,
);
writeln!(out, "}}");
+ begin_function_definition(out);
writeln!(
out,
"void cxxbridge1$weak_ptr${}$drop(::std::weak_ptr<{}> *self) noexcept {{",
@@ -1840,12 +1890,13 @@ fn write_cxx_vector(out: &mut OutFile, key: NamedImplKey) {
writeln!(
out,
- "::std::size_t cxxbridge1$std$vector${}$size(const ::std::vector<{}> &s) noexcept {{",
+ "::std::size_t cxxbridge1$std$vector${}$size(::std::vector<{}> const &s) noexcept {{",
instance, inner,
);
writeln!(out, " return s.size();");
writeln!(out, "}}");
+ begin_function_definition(out);
writeln!(
out,
"{} *cxxbridge1$std$vector${}$get_unchecked(::std::vector<{}> *s, ::std::size_t pos) noexcept {{",
@@ -1855,6 +1906,7 @@ fn write_cxx_vector(out: &mut OutFile, key: NamedImplKey) {
writeln!(out, "}}");
if out.types.is_maybe_trivial(element) {
+ begin_function_definition(out);
writeln!(
out,
"void cxxbridge1$std$vector${}$push_back(::std::vector<{}> *v, {} *value) noexcept {{",
@@ -1864,6 +1916,7 @@ fn write_cxx_vector(out: &mut OutFile, key: NamedImplKey) {
writeln!(out, " ::rust::destroy(value);");
writeln!(out, "}}");
+ begin_function_definition(out);
writeln!(
out,
"void cxxbridge1$std$vector${}$pop_back(::std::vector<{}> *v, {} *out) noexcept {{",
diff --git a/include/cxx.h b/include/cxx.h
index dffcb01a..907ee829 100644
--- a/include/cxx.h
+++ b/include/cxx.h
@@ -46,6 +46,13 @@ public:
String(const char16_t *);
String(const char16_t *, std::size_t);
+ // Replace invalid Unicode data with the replacement character (U+FFFD).
+ static String lossy(const std::string &) noexcept;
+ static String lossy(const char *) noexcept;
+ static String lossy(const char *, std::size_t) noexcept;
+ static String lossy(const char16_t *) noexcept;
+ static String lossy(const char16_t *, std::size_t) noexcept;
+
String &operator=(const String &) &noexcept;
String &operator=(String &&) &noexcept;
@@ -85,6 +92,9 @@ public:
String(unsafe_bitcopy_t, const String &) noexcept;
private:
+ struct lossy_t;
+ String(lossy_t, const char *, std::size_t) noexcept;
+ String(lossy_t, const char16_t *, std::size_t) noexcept;
friend void swap(String &lhs, String &rhs) noexcept { lhs.swap(rhs); }
// Size and alignment statically verified by rust_string.rs.
@@ -324,6 +334,8 @@ public:
void push_back(T &&value);
template <typename... Args>
void emplace_back(Args &&...args);
+ void truncate(std::size_t len);
+ void clear();
using iterator = typename Slice<T>::iterator;
iterator begin() noexcept;
@@ -945,6 +957,11 @@ void Vec<T>::emplace_back(Args &&...args) {
}
template <typename T>
+void Vec<T>::clear() {
+ this->truncate(0);
+}
+
+template <typename T>
typename Vec<T>::iterator Vec<T>::begin() noexcept {
return Slice<T>(this->data(), this->size()).begin();
}
diff --git a/macro/Android.bp b/macro/Android.bp
index 6f418506..6f6b12a3 100644
--- a/macro/Android.bp
+++ b/macro/Android.bp
@@ -1,4 +1,5 @@
// This file is generated by cargo2android.py --run --dependencies --add_workspace.
+// Do not modify this file as changes will be overridden on upgrade.
package {
// See: http://go/android-license-faq
@@ -13,6 +14,8 @@ package {
rust_proc_macro {
name: "libcxxbridge_macro",
crate_name: "cxxbridge_macro",
+ cargo_env_compat: true,
+ cargo_pkg_version: "1.0.85",
srcs: ["src/lib.rs"],
edition: "2018",
rustlibs: [
@@ -21,9 +24,3 @@ rust_proc_macro {
"libsyn",
],
}
-
-// dependent_library ["feature_list"]
-// proc-macro2-1.0.19 "default,proc-macro"
-// quote-1.0.7 "default,proc-macro"
-// syn-1.0.36 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote"
-// unicode-xid-0.2.1 "default"
diff --git a/macro/Cargo.toml b/macro/Cargo.toml
index 65f15c3a..ed230388 100644
--- a/macro/Cargo.toml
+++ b/macro/Cargo.toml
@@ -1,28 +1,31 @@
[package]
name = "cxxbridge-macro"
-version = "1.0.54"
+version = "1.0.85"
authors = ["David Tolnay <dtolnay@gmail.com>"]
-edition = "2018"
-license = "MIT OR Apache-2.0"
+categories = ["development-tools::ffi"]
description = "Implementation detail of the `cxx` crate."
-repository = "https://github.com/dtolnay/cxx"
-homepage = "https://cxx.rs"
+edition = "2018"
exclude = ["build.rs", "README.md"]
+homepage = "https://cxx.rs"
keywords = ["ffi"]
-categories = ["development-tools::ffi"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/dtolnay/cxx"
+rust-version = "1.48"
[lib]
proc-macro = true
[features]
-experimental = ["clang-ast", "flate2", "memmap", "serde", "serde_json"]
+# incomplete features that are not covered by a compatibility guarantee:
+experimental-async-fn = []
+experimental-enum-variants-from-header = ["clang-ast", "flate2", "memmap", "serde", "serde_json"]
[dependencies]
-proc-macro2 = "1.0"
+proc-macro2 = "1.0.39"
quote = "1.0.4"
-syn = { version = "1.0.70", features = ["full"] }
+syn = { version = "1.0.95", features = ["full"] }
-# optional dependencies
+# optional dependencies:
clang-ast = { version = "0.1", optional = true }
flate2 = { version = "1.0", optional = true }
memmap = { version = "0.7", optional = true }
diff --git a/macro/src/clang.rs b/macro/src/clang.rs
index 099d5a68..381e5086 100644
--- a/macro/src/clang.rs
+++ b/macro/src/clang.rs
@@ -48,4 +48,4 @@ pub struct Type {
}
#[cfg(all(test, target_pointer_width = "64"))]
-const _: [(); std::mem::size_of::<Node>()] = [(); 88];
+const _: [(); core::mem::size_of::<Node>()] = [(); 88];
diff --git a/macro/src/derive.rs b/macro/src/derive.rs
index ea36e3e3..afe85d1c 100644
--- a/macro/src/derive.rs
+++ b/macro/src/derive.rs
@@ -15,12 +15,14 @@ pub fn expand_struct(strct: &Struct, actual_derives: &mut Option<TokenStream>) -
Trait::Clone => expanded.extend(struct_clone(strct, span)),
Trait::Debug => expanded.extend(struct_debug(strct, span)),
Trait::Default => expanded.extend(struct_default(strct, span)),
- Trait::Eq => traits.push(quote_spanned!(span=> ::std::cmp::Eq)),
+ Trait::Eq => traits.push(quote_spanned!(span=> ::cxx::core::cmp::Eq)),
Trait::ExternType => unreachable!(),
- Trait::Hash => traits.push(quote_spanned!(span=> ::std::hash::Hash)),
+ Trait::Hash => traits.push(quote_spanned!(span=> ::cxx::core::hash::Hash)),
Trait::Ord => expanded.extend(struct_ord(strct, span)),
- Trait::PartialEq => traits.push(quote_spanned!(span=> ::std::cmp::PartialEq)),
+ Trait::PartialEq => traits.push(quote_spanned!(span=> ::cxx::core::cmp::PartialEq)),
Trait::PartialOrd => expanded.extend(struct_partial_ord(strct, span)),
+ Trait::Serialize => traits.push(quote_spanned!(span=> ::serde::Serialize)),
+ Trait::Deserialize => traits.push(quote_spanned!(span=> ::serde::Deserialize)),
}
}
@@ -55,17 +57,19 @@ pub fn expand_enum(enm: &Enum, actual_derives: &mut Option<TokenStream>) -> Toke
Trait::Debug => expanded.extend(enum_debug(enm, span)),
Trait::Default => unreachable!(),
Trait::Eq => {
- traits.push(quote_spanned!(span=> ::std::cmp::Eq));
+ traits.push(quote_spanned!(span=> ::cxx::core::cmp::Eq));
has_eq = true;
}
Trait::ExternType => unreachable!(),
- Trait::Hash => traits.push(quote_spanned!(span=> ::std::hash::Hash)),
+ Trait::Hash => traits.push(quote_spanned!(span=> ::cxx::core::hash::Hash)),
Trait::Ord => expanded.extend(enum_ord(enm, span)),
Trait::PartialEq => {
- traits.push(quote_spanned!(span=> ::std::cmp::PartialEq));
+ traits.push(quote_spanned!(span=> ::cxx::core::cmp::PartialEq));
has_partial_eq = true;
}
Trait::PartialOrd => expanded.extend(enum_partial_ord(enm, span)),
+ Trait::Serialize => traits.push(quote_spanned!(span=> ::serde::Serialize)),
+ Trait::Deserialize => traits.push(quote_spanned!(span=> ::serde::Deserialize)),
}
}
@@ -79,10 +83,10 @@ pub fn expand_enum(enm: &Enum, actual_derives: &mut Option<TokenStream>) -> Toke
if !has_eq {
// Required to be derived in order for the enum's "variants" to be
// usable in patterns.
- traits.push(quote!(::std::cmp::Eq));
+ traits.push(quote!(::cxx::core::cmp::Eq));
}
if !has_partial_eq {
- traits.push(quote!(::std::cmp::PartialEq));
+ traits.push(quote!(::cxx::core::cmp::PartialEq));
}
*actual_derives = Some(quote!(#[derive(#(#traits),*)]));
@@ -95,7 +99,7 @@ fn struct_copy(strct: &Struct, span: Span) -> TokenStream {
let generics = &strct.generics;
quote_spanned! {span=>
- impl #generics ::std::marker::Copy for #ident #generics {}
+ impl #generics ::cxx::core::marker::Copy for #ident #generics {}
}
}
@@ -114,12 +118,12 @@ fn struct_clone(strct: &Struct, span: Span) -> TokenStream {
quote_spanned!(span=> &self.#ident)
});
quote_spanned!(span=> #ident {
- #(#fields: ::std::clone::Clone::clone(#values),)*
+ #(#fields: ::cxx::core::clone::Clone::clone(#values),)*
})
};
quote_spanned! {span=>
- impl #generics ::std::clone::Clone for #ident #generics {
+ impl #generics ::cxx::core::clone::Clone for #ident #generics {
fn clone(&self) -> Self {
#body
}
@@ -135,8 +139,8 @@ fn struct_debug(strct: &Struct, span: Span) -> TokenStream {
let field_names = fields.clone().map(Ident::to_string);
quote_spanned! {span=>
- impl #generics ::std::fmt::Debug for #ident #generics {
- fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ impl #generics ::cxx::core::fmt::Debug for #ident #generics {
+ fn fmt(&self, formatter: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {
formatter.debug_struct(#struct_name)
#(.field(#field_names, &self.#fields))*
.finish()
@@ -152,11 +156,11 @@ fn struct_default(strct: &Struct, span: Span) -> TokenStream {
quote_spanned! {span=>
#[allow(clippy::derivable_impls)] // different spans than the derived impl
- impl #generics ::std::default::Default for #ident #generics {
+ impl #generics ::cxx::core::default::Default for #ident #generics {
fn default() -> Self {
#ident {
#(
- #fields: ::std::default::Default::default(),
+ #fields: ::cxx::core::default::Default::default(),
)*
}
}
@@ -170,15 +174,15 @@ fn struct_ord(strct: &Struct, span: Span) -> TokenStream {
let fields = strct.fields.iter().map(|field| &field.name.rust);
quote_spanned! {span=>
- impl #generics ::std::cmp::Ord for #ident #generics {
- fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
+ impl #generics ::cxx::core::cmp::Ord for #ident #generics {
+ fn cmp(&self, other: &Self) -> ::cxx::core::cmp::Ordering {
#(
- match ::std::cmp::Ord::cmp(&self.#fields, &other.#fields) {
- ::std::cmp::Ordering::Equal => {}
+ match ::cxx::core::cmp::Ord::cmp(&self.#fields, &other.#fields) {
+ ::cxx::core::cmp::Ordering::Equal => {}
ordering => return ordering,
}
)*
- ::std::cmp::Ordering::Equal
+ ::cxx::core::cmp::Ordering::Equal
}
}
}
@@ -190,24 +194,24 @@ fn struct_partial_ord(strct: &Struct, span: Span) -> TokenStream {
let body = if derive::contains(&strct.derives, Trait::Ord) {
quote! {
- ::std::option::Option::Some(::std::cmp::Ord::cmp(self, other))
+ ::cxx::core::option::Option::Some(::cxx::core::cmp::Ord::cmp(self, other))
}
} else {
let fields = strct.fields.iter().map(|field| &field.name.rust);
quote! {
#(
- match ::std::cmp::PartialOrd::partial_cmp(&self.#fields, &other.#fields) {
- ::std::option::Option::Some(::std::cmp::Ordering::Equal) => {}
+ match ::cxx::core::cmp::PartialOrd::partial_cmp(&self.#fields, &other.#fields) {
+ ::cxx::core::option::Option::Some(::cxx::core::cmp::Ordering::Equal) => {}
ordering => return ordering,
}
)*
- ::std::option::Option::Some(::std::cmp::Ordering::Equal)
+ ::cxx::core::option::Option::Some(::cxx::core::cmp::Ordering::Equal)
}
};
quote_spanned! {span=>
- impl #generics ::std::cmp::PartialOrd for #ident #generics {
- fn partial_cmp(&self, other: &Self) -> ::std::option::Option<::std::cmp::Ordering> {
+ impl #generics ::cxx::core::cmp::PartialOrd for #ident #generics {
+ fn partial_cmp(&self, other: &Self) -> ::cxx::core::option::Option<::cxx::core::cmp::Ordering> {
#body
}
}
@@ -218,7 +222,7 @@ fn enum_copy(enm: &Enum, span: Span) -> TokenStream {
let ident = &enm.name.rust;
quote_spanned! {span=>
- impl ::std::marker::Copy for #ident {}
+ impl ::cxx::core::marker::Copy for #ident {}
}
}
@@ -226,7 +230,7 @@ fn enum_clone(enm: &Enum, span: Span) -> TokenStream {
let ident = &enm.name.rust;
quote_spanned! {span=>
- impl ::std::clone::Clone for #ident {
+ impl ::cxx::core::clone::Clone for #ident {
fn clone(&self) -> Self {
*self
}
@@ -246,11 +250,11 @@ fn enum_debug(enm: &Enum, span: Span) -> TokenStream {
let fallback = format!("{}({{}})", ident);
quote_spanned! {span=>
- impl ::std::fmt::Debug for #ident {
- fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ impl ::cxx::core::fmt::Debug for #ident {
+ fn fmt(&self, formatter: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {
match *self {
#(#variants)*
- _ => ::std::write!(formatter, #fallback, self.repr),
+ _ => ::cxx::core::write!(formatter, #fallback, self.repr),
}
}
}
@@ -261,9 +265,9 @@ fn enum_ord(enm: &Enum, span: Span) -> TokenStream {
let ident = &enm.name.rust;
quote_spanned! {span=>
- impl ::std::cmp::Ord for #ident {
- fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
- ::std::cmp::Ord::cmp(&self.repr, &other.repr)
+ impl ::cxx::core::cmp::Ord for #ident {
+ fn cmp(&self, other: &Self) -> ::cxx::core::cmp::Ordering {
+ ::cxx::core::cmp::Ord::cmp(&self.repr, &other.repr)
}
}
}
@@ -273,9 +277,9 @@ fn enum_partial_ord(enm: &Enum, span: Span) -> TokenStream {
let ident = &enm.name.rust;
quote_spanned! {span=>
- impl ::std::cmp::PartialOrd for #ident {
- fn partial_cmp(&self, other: &Self) -> ::std::option::Option<::std::cmp::Ordering> {
- ::std::cmp::PartialOrd::partial_cmp(&self.repr, &other.repr)
+ impl ::cxx::core::cmp::PartialOrd for #ident {
+ fn partial_cmp(&self, other: &Self) -> ::cxx::core::option::Option<::cxx::core::cmp::Ordering> {
+ ::cxx::core::cmp::PartialOrd::partial_cmp(&self.repr, &other.repr)
}
}
}
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 5a879cbd..8f5836a6 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -1,5 +1,6 @@
use crate::syntax::atom::Atom::*;
use crate::syntax::attrs::{self, OtherAttrs};
+use crate::syntax::cfg::CfgExpr;
use crate::syntax::file::Module;
use crate::syntax::instantiate::{ImplKey, NamedImplKey};
use crate::syntax::qualified::QualifiedName;
@@ -19,11 +20,13 @@ use syn::{parse_quote, punctuated, Generics, Lifetime, Result, Token};
pub fn bridge(mut ffi: Module) -> Result<TokenStream> {
let ref mut errors = Errors::new();
+ let mut cfg = CfgExpr::Unconditional;
let mut doc = Doc::new();
let attrs = attrs::parse(
errors,
mem::take(&mut ffi.attrs),
attrs::Parser {
+ cfg: Some(&mut cfg),
doc: Some(&mut doc),
..Default::default()
},
@@ -33,7 +36,7 @@ pub fn bridge(mut ffi: Module) -> Result<TokenStream> {
let trusted = ffi.unsafety.is_some();
let namespace = &ffi.namespace;
let ref mut apis = syntax::parse_items(errors, content, trusted, namespace);
- #[cfg(feature = "experimental")]
+ #[cfg(feature = "experimental-enum-variants-from-header")]
crate::load::load(errors, apis);
let ref types = Types::collect(errors, apis);
errors.propagate()?;
@@ -53,7 +56,7 @@ fn expand(ffi: Module, doc: Doc, attrs: OtherAttrs, apis: &[Api], types: &Types)
for api in apis {
if let Api::RustType(ety) = api {
expanded.extend(expand_rust_type_import(ety));
- hidden.extend(expand_rust_type_assert_sized(ety));
+ hidden.extend(expand_rust_type_assert_unpin(ety, types));
}
}
@@ -70,7 +73,7 @@ fn expand(ffi: Module, doc: Doc, attrs: OtherAttrs, apis: &[Api], types: &Types)
let ident = &ety.name.rust;
if !types.structs.contains_key(ident) && !types.enums.contains_key(ident) {
expanded.extend(expand_cxx_type(ety));
- hidden.extend(expand_cxx_type_assert_pinned(ety));
+ hidden.extend(expand_cxx_type_assert_pinned(ety, types));
}
}
Api::CxxFunction(efn) => {
@@ -78,7 +81,7 @@ fn expand(ffi: Module, doc: Doc, attrs: OtherAttrs, apis: &[Api], types: &Types)
}
Api::RustType(ety) => {
expanded.extend(expand_rust_type_impl(ety));
- hidden.extend(expand_rust_type_layout(ety));
+ hidden.extend(expand_rust_type_layout(ety, types));
}
Api::RustFunction(efn) => hidden.extend(expand_rust_function_shim(efn, types)),
Api::TypeAlias(alias) => {
@@ -169,12 +172,13 @@ fn expand_struct(strct: &Struct) -> TokenStream {
quote! {
#doc
- #attrs
#derives
+ #attrs
#[repr(C)]
#struct_def
unsafe impl #generics ::cxx::ExternType for #ident #generics {
+ #[allow(unused_attributes)] // incorrect lint
#[doc(hidden)]
type Id = #type_id;
type Kind = ::cxx::kind::Trivial;
@@ -186,6 +190,7 @@ fn expand_struct(strct: &Struct) -> TokenStream {
fn expand_struct_operators(strct: &Struct) -> TokenStream {
let ident = &strct.name.rust;
+ let generics = &strct.generics;
let mut operators = TokenStream::new();
for derive in &strct.derives {
@@ -194,22 +199,26 @@ fn expand_struct_operators(strct: &Struct) -> TokenStream {
Trait::PartialEq => {
let link_name = mangle::operator(&strct.name, "eq");
let local_name = format_ident!("__operator_eq_{}", strct.name.rust);
+ let prevent_unwind_label = format!("::{} as PartialEq>::eq", strct.name.rust);
operators.extend(quote_spanned! {span=>
#[doc(hidden)]
#[export_name = #link_name]
- extern "C" fn #local_name(lhs: &#ident, rhs: &#ident) -> bool {
- *lhs == *rhs
+ extern "C" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> bool {
+ let __fn = concat!("<", module_path!(), #prevent_unwind_label);
+ ::cxx::private::prevent_unwind(__fn, || *lhs == *rhs)
}
});
if !derive::contains(&strct.derives, Trait::Eq) {
let link_name = mangle::operator(&strct.name, "ne");
let local_name = format_ident!("__operator_ne_{}", strct.name.rust);
+ let prevent_unwind_label = format!("::{} as PartialEq>::ne", strct.name.rust);
operators.extend(quote_spanned! {span=>
#[doc(hidden)]
#[export_name = #link_name]
- extern "C" fn #local_name(lhs: &#ident, rhs: &#ident) -> bool {
- *lhs != *rhs
+ extern "C" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> bool {
+ let __fn = concat!("<", module_path!(), #prevent_unwind_label);
+ ::cxx::private::prevent_unwind(__fn, || *lhs != *rhs)
}
});
}
@@ -217,42 +226,50 @@ fn expand_struct_operators(strct: &Struct) -> TokenStream {
Trait::PartialOrd => {
let link_name = mangle::operator(&strct.name, "lt");
let local_name = format_ident!("__operator_lt_{}", strct.name.rust);
+ let prevent_unwind_label = format!("::{} as PartialOrd>::lt", strct.name.rust);
operators.extend(quote_spanned! {span=>
#[doc(hidden)]
#[export_name = #link_name]
- extern "C" fn #local_name(lhs: &#ident, rhs: &#ident) -> bool {
- *lhs < *rhs
+ extern "C" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> bool {
+ let __fn = concat!("<", module_path!(), #prevent_unwind_label);
+ ::cxx::private::prevent_unwind(__fn, || *lhs < *rhs)
}
});
let link_name = mangle::operator(&strct.name, "le");
let local_name = format_ident!("__operator_le_{}", strct.name.rust);
+ let prevent_unwind_label = format!("::{} as PartialOrd>::le", strct.name.rust);
operators.extend(quote_spanned! {span=>
#[doc(hidden)]
#[export_name = #link_name]
- extern "C" fn #local_name(lhs: &#ident, rhs: &#ident) -> bool {
- *lhs <= *rhs
+ extern "C" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> bool {
+ let __fn = concat!("<", module_path!(), #prevent_unwind_label);
+ ::cxx::private::prevent_unwind(__fn, || *lhs <= *rhs)
}
});
if !derive::contains(&strct.derives, Trait::Ord) {
let link_name = mangle::operator(&strct.name, "gt");
let local_name = format_ident!("__operator_gt_{}", strct.name.rust);
+ let prevent_unwind_label = format!("::{} as PartialOrd>::gt", strct.name.rust);
operators.extend(quote_spanned! {span=>
#[doc(hidden)]
#[export_name = #link_name]
- extern "C" fn #local_name(lhs: &#ident, rhs: &#ident) -> bool {
- *lhs > *rhs
+ extern "C" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> bool {
+ let __fn = concat!("<", module_path!(), #prevent_unwind_label);
+ ::cxx::private::prevent_unwind(__fn, || *lhs > *rhs)
}
});
let link_name = mangle::operator(&strct.name, "ge");
let local_name = format_ident!("__operator_ge_{}", strct.name.rust);
+ let prevent_unwind_label = format!("::{} as PartialOrd>::ge", strct.name.rust);
operators.extend(quote_spanned! {span=>
#[doc(hidden)]
#[export_name = #link_name]
- extern "C" fn #local_name(lhs: &#ident, rhs: &#ident) -> bool {
- *lhs >= *rhs
+ extern "C" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> bool {
+ let __fn = concat!("<", module_path!(), #prevent_unwind_label);
+ ::cxx::private::prevent_unwind(__fn, || *lhs >= *rhs)
}
});
}
@@ -260,14 +277,14 @@ fn expand_struct_operators(strct: &Struct) -> TokenStream {
Trait::Hash => {
let link_name = mangle::operator(&strct.name, "hash");
let local_name = format_ident!("__operator_hash_{}", strct.name.rust);
+ let prevent_unwind_label = format!("::{} as Hash>::hash", strct.name.rust);
operators.extend(quote_spanned! {span=>
#[doc(hidden)]
#[export_name = #link_name]
#[allow(clippy::cast_possible_truncation)]
- extern "C" fn #local_name(this: &#ident) -> usize {
- let mut hasher = ::std::collections::hash_map::DefaultHasher::new();
- ::std::hash::Hash::hash(this, &mut hasher);
- ::std::hash::Hasher::finish(&hasher) as usize
+ extern "C" fn #local_name #generics(this: &#ident #generics) -> usize {
+ let __fn = concat!("<", module_path!(), #prevent_unwind_label);
+ ::cxx::private::prevent_unwind(__fn, || ::cxx::private::hash(this))
}
});
}
@@ -325,8 +342,8 @@ fn expand_enum(enm: &Enum) -> TokenStream {
quote! {
#doc
- #attrs
#derives
+ #attrs
#[repr(transparent)]
#enum_def
@@ -336,6 +353,7 @@ fn expand_enum(enm: &Enum) -> TokenStream {
}
unsafe impl ::cxx::ExternType for #ident {
+ #[allow(unused_attributes)] // incorrect lint
#[doc(hidden)]
type Id = #type_id;
type Kind = ::cxx::kind::Trivial;
@@ -354,7 +372,7 @@ fn expand_cxx_type(ety: &ExternType) -> TokenStream {
let lifetime_fields = ety.generics.lifetimes.iter().map(|lifetime| {
let field = format_ident!("_lifetime_{}", lifetime.ident);
- quote!(#field: ::std::marker::PhantomData<&#lifetime ()>)
+ quote!(#field: ::cxx::core::marker::PhantomData<&#lifetime ()>)
});
let repr_fields = quote! {
_private: ::cxx::private::Opaque,
@@ -377,6 +395,7 @@ fn expand_cxx_type(ety: &ExternType) -> TokenStream {
#extern_type_def
unsafe impl #generics ::cxx::ExternType for #ident #generics {
+ #[allow(unused_attributes)] // incorrect lint
#[doc(hidden)]
type Id = #type_id;
type Kind = ::cxx::kind::Opaque;
@@ -384,12 +403,15 @@ fn expand_cxx_type(ety: &ExternType) -> TokenStream {
}
}
-fn expand_cxx_type_assert_pinned(ety: &ExternType) -> TokenStream {
+fn expand_cxx_type_assert_pinned(ety: &ExternType, types: &Types) -> TokenStream {
let ident = &ety.name.rust;
let infer = Token![_](ident.span());
+ let resolve = types.resolve(ident);
+ let lifetimes = resolve.generics.to_underscore_lifetimes();
+
quote! {
- let _ = {
+ let _: fn() = {
// Derived from https://github.com/nvzqz/static-assertions-rs.
trait __AmbiguousIfImpl<A> {
fn infer() {}
@@ -397,7 +419,7 @@ fn expand_cxx_type_assert_pinned(ety: &ExternType) -> TokenStream {
impl<T> __AmbiguousIfImpl<()> for T
where
- T: ?::std::marker::Sized
+ T: ?::cxx::core::marker::Sized
{}
#[allow(dead_code)]
@@ -405,14 +427,14 @@ fn expand_cxx_type_assert_pinned(ety: &ExternType) -> TokenStream {
impl<T> __AmbiguousIfImpl<__Invalid> for T
where
- T: ?::std::marker::Sized + ::std::marker::Unpin,
+ T: ?::cxx::core::marker::Sized + ::cxx::core::marker::Unpin,
{}
// If there is only one specialized trait impl, type inference with
// `_` can be resolved and this can compile. Fails to compile if
// user has added a manual Unpin impl for their opaque C++ type as
// then `__AmbiguousIfImpl<__Invalid>` also exists.
- <#ident as __AmbiguousIfImpl<#infer>>::infer
+ <#ident #lifetimes as __AmbiguousIfImpl<#infer>>::infer
};
}
}
@@ -482,7 +504,7 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
Some(ret) => quote!(#ret),
None => quote!(()),
};
- quote!(-> ::std::result::Result<#ok, ::cxx::Exception>)
+ quote!(-> ::cxx::core::result::Result<#ok, ::cxx::Exception>)
} else {
expand_return_type(&efn.ret)
};
@@ -500,9 +522,9 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
}
Type::RustBox(ty) => {
if types.is_considered_improper_ctype(&ty.inner) {
- quote_spanned!(span=> ::std::boxed::Box::into_raw(#var).cast())
+ quote_spanned!(span=> ::cxx::alloc::boxed::Box::into_raw(#var).cast())
} else {
- quote_spanned!(span=> ::std::boxed::Box::into_raw(#var))
+ quote_spanned!(span=> ::cxx::alloc::boxed::Box::into_raw(#var))
}
}
Type::UniquePtr(ty) => {
@@ -529,13 +551,13 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
inner if types.is_considered_improper_ctype(inner) => {
let var = match ty.pinned {
false => quote!(#var),
- true => quote_spanned!(span=> ::std::pin::Pin::into_inner_unchecked(#var)),
+ true => quote_spanned!(span=> ::cxx::core::pin::Pin::into_inner_unchecked(#var)),
};
match ty.mutable {
false => {
- quote_spanned!(span=> #var as *const #inner as *const ::std::ffi::c_void)
+ quote_spanned!(span=> #var as *const #inner as *const ::cxx::core::ffi::c_void)
}
- true => quote_spanned!(span=> #var as *mut #inner as *mut ::std::ffi::c_void),
+ true => quote_spanned!(span=> #var as *mut #inner as *mut ::cxx::core::ffi::c_void),
}
}
_ => quote!(#var),
@@ -579,7 +601,7 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
// These are arguments for which C++ has taken ownership of the data
// behind the mut reference it received.
quote_spanned! {span=>
- let mut #var = ::std::mem::MaybeUninit::new(#var);
+ let mut #var = ::cxx::core::mem::MaybeUninit::new(#var);
}
})
.collect::<TokenStream>();
@@ -588,7 +610,7 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
let call = if indirect_return {
let ret = expand_extern_type(efn.ret.as_ref().unwrap(), types, true);
setup.extend(quote_spanned! {span=>
- let mut __return = ::std::mem::MaybeUninit::<#ret>::uninit();
+ let mut __return = ::cxx::core::mem::MaybeUninit::<#ret>::uninit();
});
setup.extend(if efn.throws {
quote_spanned! {span=>
@@ -621,9 +643,9 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
}
Type::RustBox(ty) => {
if types.is_considered_improper_ctype(&ty.inner) {
- quote_spanned!(span=> ::std::boxed::Box::from_raw(#call.cast()))
+ quote_spanned!(span=> ::cxx::alloc::boxed::Box::from_raw(#call.cast()))
} else {
- quote_spanned!(span=> ::std::boxed::Box::from_raw(#call))
+ quote_spanned!(span=> ::cxx::alloc::boxed::Box::from_raw(#call))
}
}
Type::RustVec(vec) => {
@@ -659,7 +681,7 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
match ty.pinned {
false => deref_mut,
true => {
- quote_spanned!(span=> ::std::pin::Pin::new_unchecked(#deref_mut))
+ quote_spanned!(span=> ::cxx::core::pin::Pin::new_unchecked(#deref_mut))
}
}
}
@@ -684,7 +706,7 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
},
};
if efn.throws {
- expr = quote_spanned!(span=> ::std::result::Result::Ok(#expr));
+ expr = quote_spanned!(span=> ::cxx::core::result::Result::Ok(#expr));
}
};
let mut dispatch = quote!(#setup #expr);
@@ -755,16 +777,17 @@ fn expand_function_pointer_trampoline(
let c_trampoline = mangle::c_trampoline(efn, var, types);
let r_trampoline = mangle::r_trampoline(efn, var, types);
let local_name = parse_quote!(__);
- let catch_unwind_label = format!("::{}::{}", efn.name.rust, var.rust);
+ let prevent_unwind_label = format!("::{}::{}", efn.name.rust, var.rust);
let body_span = efn.semi_token.span;
let shim = expand_rust_function_shim_impl(
sig,
types,
&r_trampoline,
local_name,
- catch_unwind_label,
+ prevent_unwind_label,
None,
Some(&efn.generics),
+ &efn.attrs,
body_span,
);
let var = &var.rust;
@@ -777,9 +800,9 @@ fn expand_function_pointer_trampoline(
fn trampoline();
}
#shim
- trampoline as usize as *const ::std::ffi::c_void
+ trampoline as usize as *const ::cxx::core::ffi::c_void
},
- ptr: #var as usize as *const ::std::ffi::c_void,
+ ptr: #var as usize as *const ::cxx::core::ffi::c_void,
};
}
}
@@ -810,6 +833,7 @@ fn expand_rust_type_impl(ety: &ExternType) -> TokenStream {
let span = derive.span;
impls.extend(quote_spanned! {span=>
unsafe impl #generics ::cxx::ExternType for #ident #generics {
+ #[allow(unused_attributes)] // incorrect lint
#[doc(hidden)]
type Id = #type_id;
type Kind = ::cxx::kind::Opaque;
@@ -821,33 +845,37 @@ fn expand_rust_type_impl(ety: &ExternType) -> TokenStream {
impls
}
-fn expand_rust_type_assert_sized(ety: &ExternType) -> TokenStream {
- // Rustc will render as follows if not sized:
- //
- // type TheirType;
- // -----^^^^^^^^^-
- // | |
- // | doesn't have a size known at compile-time
- // required by this bound in `ffi::_::__AssertSized`
-
+fn expand_rust_type_assert_unpin(ety: &ExternType, types: &Types) -> TokenStream {
let ident = &ety.name.rust;
let begin_span = Token![::](ety.type_token.span);
let unpin = quote_spanned! {ety.semi_token.span=>
- #begin_span std::marker::Unpin
+ #begin_span cxx::core::marker::Unpin
};
+
+ let resolve = types.resolve(ident);
+ let lifetimes = resolve.generics.to_underscore_lifetimes();
+
quote_spanned! {ident.span()=>
let _ = {
- fn __AssertUnpin<T: ?::std::marker::Sized + #unpin>() {}
- __AssertUnpin::<#ident>
+ fn __AssertUnpin<T: ?::cxx::core::marker::Sized + #unpin>() {}
+ __AssertUnpin::<#ident #lifetimes>
};
}
}
-fn expand_rust_type_layout(ety: &ExternType) -> TokenStream {
+fn expand_rust_type_layout(ety: &ExternType, types: &Types) -> TokenStream {
+ // Rustc will render as follows if not sized:
+ //
+ // type TheirType;
+ // -----^^^^^^^^^-
+ // | |
+ // | doesn't have a size known at compile-time
+ // required by this bound in `__AssertSized`
+
let ident = &ety.name.rust;
let begin_span = Token![::](ety.type_token.span);
let sized = quote_spanned! {ety.semi_token.span=>
- #begin_span std::marker::Sized
+ #begin_span cxx::core::marker::Sized
};
let link_sizeof = mangle::operator(&ety.name, "sizeof");
@@ -856,21 +884,24 @@ fn expand_rust_type_layout(ety: &ExternType) -> TokenStream {
let local_sizeof = format_ident!("__sizeof_{}", ety.name.rust);
let local_alignof = format_ident!("__alignof_{}", ety.name.rust);
+ let resolve = types.resolve(ident);
+ let lifetimes = resolve.generics.to_underscore_lifetimes();
+
quote_spanned! {ident.span()=>
{
#[doc(hidden)]
- fn __AssertSized<T: ?#sized + #sized>() -> ::std::alloc::Layout {
- ::std::alloc::Layout::new::<T>()
+ fn __AssertSized<T: ?#sized + #sized>() -> ::cxx::core::alloc::Layout {
+ ::cxx::core::alloc::Layout::new::<T>()
}
#[doc(hidden)]
#[export_name = #link_sizeof]
extern "C" fn #local_sizeof() -> usize {
- __AssertSized::<#ident>().size()
+ __AssertSized::<#ident #lifetimes>().size()
}
#[doc(hidden)]
#[export_name = #link_alignof]
extern "C" fn #local_alignof() -> usize {
- __AssertSized::<#ident>().align()
+ __AssertSized::<#ident #lifetimes>().align()
}
}
}
@@ -881,7 +912,7 @@ fn expand_forbid(impls: TokenStream) -> TokenStream {
mod forbid {
pub trait Drop {}
#[allow(drop_bounds)]
- impl<T: ?::std::marker::Sized + ::std::ops::Drop> self::Drop for T {}
+ impl<T: ?::cxx::core::marker::Sized + ::cxx::core::ops::Drop> self::Drop for T {}
#impls
}
}
@@ -893,7 +924,7 @@ fn expand_rust_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
None => format_ident!("__{}", efn.name.rust),
Some(receiver) => format_ident!("__{}__{}", receiver.ty.rust, efn.name.rust),
};
- let catch_unwind_label = match &efn.receiver {
+ let prevent_unwind_label = match &efn.receiver {
None => format!("::{}", efn.name.rust),
Some(receiver) => format!("::{}::{}", receiver.ty.rust, efn.name.rust),
};
@@ -904,9 +935,10 @@ fn expand_rust_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
types,
&link_name,
local_name,
- catch_unwind_label,
+ prevent_unwind_label,
invoke,
None,
+ &efn.attrs,
body_span,
)
}
@@ -916,9 +948,10 @@ fn expand_rust_function_shim_impl(
types: &Types,
link_name: &Symbol,
local_name: Ident,
- catch_unwind_label: String,
+ prevent_unwind_label: String,
invoke: Option<&Ident>,
outer_generics: Option<&Generics>,
+ attrs: &OtherAttrs,
body_span: Span,
) -> TokenStream {
let generics = outer_generics.unwrap_or(&sig.generics);
@@ -948,14 +981,14 @@ fn expand_rust_function_shim_impl(
let span = var.span();
match &arg.ty {
Type::Ident(i) if i.rust == RustString => {
- quote_spanned!(span=> ::std::mem::take((*#var).as_mut_string()))
+ quote_spanned!(span=> ::cxx::core::mem::take((*#var).as_mut_string()))
}
- Type::RustBox(_) => quote_spanned!(span=> ::std::boxed::Box::from_raw(#var)),
+ Type::RustBox(_) => quote_spanned!(span=> ::cxx::alloc::boxed::Box::from_raw(#var)),
Type::RustVec(vec) => {
if vec.inner == RustString {
- quote_spanned!(span=> ::std::mem::take((*#var).as_mut_vec_string()))
+ quote_spanned!(span=> ::cxx::core::mem::take((*#var).as_mut_vec_string()))
} else {
- quote_spanned!(span=> ::std::mem::take((*#var).as_mut_vec()))
+ quote_spanned!(span=> ::cxx::core::mem::take((*#var).as_mut_vec()))
}
}
Type::UniquePtr(_) => quote_spanned!(span=> ::cxx::UniquePtr::from_raw(#var)),
@@ -982,7 +1015,9 @@ fn expand_rust_function_shim_impl(
true => quote_spanned!(span=> #var.as_mut_slice::<#inner>()),
}
}
- ty if types.needs_indirect_abi(ty) => quote_spanned!(span=> ::std::ptr::read(#var)),
+ ty if types.needs_indirect_abi(ty) => {
+ quote_spanned!(span=> ::cxx::core::ptr::read(#var))
+ }
_ => quote!(#var),
}
});
@@ -998,7 +1033,7 @@ fn expand_rust_function_shim_impl(
}
None => {
requires_closure = true;
- quote!(::std::mem::transmute::<*const (), #sig>(__extern))
+ quote!(::cxx::core::mem::transmute::<*const (), #sig>(__extern))
}
};
requires_closure |= !vars.is_empty();
@@ -1009,7 +1044,7 @@ fn expand_rust_function_shim_impl(
Type::Ident(ident) if ident.rust == RustString => {
Some(quote_spanned!(span=> ::cxx::private::RustString::from))
}
- Type::RustBox(_) => Some(quote_spanned!(span=> ::std::boxed::Box::into_raw)),
+ Type::RustBox(_) => Some(quote_spanned!(span=> ::cxx::alloc::boxed::Box::into_raw)),
Type::RustVec(vec) => {
if vec.inner == RustString {
Some(quote_spanned!(span=> ::cxx::private::RustVec::from_vec_string))
@@ -1049,7 +1084,7 @@ fn expand_rust_function_shim_impl(
}
Some(conversion) => {
requires_closure = true;
- quote_spanned!(span=> ::std::result::Result::map(#call, #conversion))
+ quote_spanned!(span=> ::cxx::core::result::Result::map(#call, #conversion))
}
};
@@ -1068,7 +1103,7 @@ fn expand_rust_function_shim_impl(
expr = quote_spanned!(span=> ::cxx::private::r#try(#out, #expr));
} else if indirect_return {
requires_closure = true;
- expr = quote_spanned!(span=> ::std::ptr::write(__return, #expr));
+ expr = quote_spanned!(span=> ::cxx::core::ptr::write(__return, #expr));
}
let closure = if requires_closure {
@@ -1077,7 +1112,7 @@ fn expand_rust_function_shim_impl(
quote!(#local_name)
};
- expr = quote_spanned!(span=> ::cxx::private::catch_unwind(__fn, #closure));
+ expr = quote_spanned!(span=> ::cxx::private::prevent_unwind(__fn, #closure));
let ret = if sig.throws {
quote!(-> ::cxx::private::Result)
@@ -1091,10 +1126,11 @@ fn expand_rust_function_shim_impl(
};
quote_spanned! {span=>
+ #attrs
#[doc(hidden)]
#[export_name = #link_name]
unsafe extern "C" fn #local_name #generics(#(#all_args,)* #outparam #pointer) #ret {
- let __fn = concat!(module_path!(), #catch_unwind_label);
+ let __fn = ::cxx::private::concat!(::cxx::private::module_path!(), #prevent_unwind_label);
#wrap_super
#expr
}
@@ -1129,8 +1165,8 @@ fn expand_rust_function_shim_super(
};
// Set spans that result in the `Result<...>` written by the user being
// highlighted as the cause if their error type has no Display impl.
- let result_begin = quote_spanned!(result.span=> ::std::result::Result<#ok, impl);
- let result_end = quote_spanned!(rangle.span=> ::std::fmt::Display>);
+ let result_begin = quote_spanned!(result.span=> ::cxx::core::result::Result<#ok, impl);
+ let result_end = quote_spanned!(rangle.span=> ::cxx::core::fmt::Display>);
quote!(-> #result_begin #result_end)
} else {
expand_return_type(&sig.ret)
@@ -1222,24 +1258,32 @@ fn expand_rust_box(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl
let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span);
let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span);
let unsafe_token = format_ident!("unsafe", span = begin_span);
+ let prevent_unwind_drop_label = format!("::{} as Drop>::drop", ident);
quote_spanned! {end_span=>
#[doc(hidden)]
#unsafe_token impl #impl_generics ::cxx::private::ImplBox for #ident #ty_generics {}
#[doc(hidden)]
#[export_name = #link_alloc]
- unsafe extern "C" fn #local_alloc #impl_generics() -> *mut ::std::mem::MaybeUninit<#ident #ty_generics> {
- ::std::boxed::Box::into_raw(::std::boxed::Box::new(::std::mem::MaybeUninit::uninit()))
+ unsafe extern "C" fn #local_alloc #impl_generics() -> *mut ::cxx::core::mem::MaybeUninit<#ident #ty_generics> {
+ // No prevent_unwind: the global allocator is not allowed to panic.
+ //
+ // TODO: replace with Box::new_uninit when stable.
+ // https://doc.rust-lang.org/std/boxed/struct.Box.html#method.new_uninit
+ // https://github.com/rust-lang/rust/issues/63291
+ ::cxx::alloc::boxed::Box::into_raw(::cxx::alloc::boxed::Box::new(::cxx::core::mem::MaybeUninit::uninit()))
}
#[doc(hidden)]
#[export_name = #link_dealloc]
- unsafe extern "C" fn #local_dealloc #impl_generics(ptr: *mut ::std::mem::MaybeUninit<#ident #ty_generics>) {
- ::std::boxed::Box::from_raw(ptr);
+ unsafe extern "C" fn #local_dealloc #impl_generics(ptr: *mut ::cxx::core::mem::MaybeUninit<#ident #ty_generics>) {
+ // No prevent_unwind: the global allocator is not allowed to panic.
+ let _ = ::cxx::alloc::boxed::Box::from_raw(ptr);
}
#[doc(hidden)]
#[export_name = #link_drop]
- unsafe extern "C" fn #local_drop #impl_generics(this: *mut ::std::boxed::Box<#ident #ty_generics>) {
- ::std::ptr::drop_in_place(this);
+ unsafe extern "C" fn #local_drop #impl_generics(this: *mut ::cxx::alloc::boxed::Box<#ident #ty_generics>) {
+ let __fn = concat!("<", module_path!(), #prevent_unwind_drop_label);
+ ::cxx::private::prevent_unwind(__fn, || ::cxx::core::ptr::drop_in_place(this));
}
}
}
@@ -1255,6 +1299,7 @@ fn expand_rust_vec(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl
let link_data = format!("{}data", link_prefix);
let link_reserve_total = format!("{}reserve_total", link_prefix);
let link_set_len = format!("{}set_len", link_prefix);
+ let link_truncate = format!("{}truncate", link_prefix);
let local_prefix = format_ident!("{}__vec_", elem);
let local_new = format_ident!("{}new", local_prefix);
@@ -1264,12 +1309,14 @@ fn expand_rust_vec(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl
let local_data = format_ident!("{}data", local_prefix);
let local_reserve_total = format_ident!("{}reserve_total", local_prefix);
let local_set_len = format_ident!("{}set_len", local_prefix);
+ let local_truncate = format_ident!("{}truncate", local_prefix);
let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve);
let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span);
let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span);
let unsafe_token = format_ident!("unsafe", span = begin_span);
+ let prevent_unwind_drop_label = format!("::{} as Drop>::drop", elem);
quote_spanned! {end_span=>
#[doc(hidden)]
@@ -1277,38 +1324,51 @@ fn expand_rust_vec(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl
#[doc(hidden)]
#[export_name = #link_new]
unsafe extern "C" fn #local_new #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>) {
- ::std::ptr::write(this, ::cxx::private::RustVec::new());
+ // No prevent_unwind: cannot panic.
+ ::cxx::core::ptr::write(this, ::cxx::private::RustVec::new());
}
#[doc(hidden)]
#[export_name = #link_drop]
unsafe extern "C" fn #local_drop #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>) {
- ::std::ptr::drop_in_place(this);
+ let __fn = concat!("<", module_path!(), #prevent_unwind_drop_label);
+ ::cxx::private::prevent_unwind(__fn, || ::cxx::core::ptr::drop_in_place(this));
}
#[doc(hidden)]
#[export_name = #link_len]
unsafe extern "C" fn #local_len #impl_generics(this: *const ::cxx::private::RustVec<#elem #ty_generics>) -> usize {
+ // No prevent_unwind: cannot panic.
(*this).len()
}
#[doc(hidden)]
#[export_name = #link_capacity]
unsafe extern "C" fn #local_capacity #impl_generics(this: *const ::cxx::private::RustVec<#elem #ty_generics>) -> usize {
+ // No prevent_unwind: cannot panic.
(*this).capacity()
}
#[doc(hidden)]
#[export_name = #link_data]
unsafe extern "C" fn #local_data #impl_generics(this: *const ::cxx::private::RustVec<#elem #ty_generics>) -> *const #elem #ty_generics {
+ // No prevent_unwind: cannot panic.
(*this).as_ptr()
}
#[doc(hidden)]
#[export_name = #link_reserve_total]
unsafe extern "C" fn #local_reserve_total #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>, new_cap: usize) {
+ // No prevent_unwind: the global allocator is not allowed to panic.
(*this).reserve_total(new_cap);
}
#[doc(hidden)]
#[export_name = #link_set_len]
unsafe extern "C" fn #local_set_len #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>, len: usize) {
+ // No prevent_unwind: cannot panic.
(*this).set_len(len);
}
+ #[doc(hidden)]
+ #[export_name = #link_truncate]
+ unsafe extern "C" fn #local_truncate #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>, len: usize) {
+ let __fn = concat!("<", module_path!(), #prevent_unwind_drop_label);
+ ::cxx::private::prevent_unwind(__fn, || (*this).truncate(len));
+ }
}
}
@@ -1333,13 +1393,12 @@ fn expand_unique_ptr(
let can_construct_from_value = types.is_maybe_trivial(ident);
let new_method = if can_construct_from_value {
Some(quote! {
- #[doc(hidden)]
- fn __new(value: Self) -> ::std::mem::MaybeUninit<*mut ::std::ffi::c_void> {
+ fn __new(value: Self) -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {
extern "C" {
#[link_name = #link_uninit]
- fn __uninit(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *mut ::std::ffi::c_void;
+ fn __uninit(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::core::ffi::c_void;
}
- let mut repr = ::std::mem::MaybeUninit::uninit();
+ let mut repr = ::cxx::core::mem::MaybeUninit::uninit();
unsafe { __uninit(&mut repr).cast::<#ident #ty_generics>().write(value) }
repr
}
@@ -1354,52 +1413,46 @@ fn expand_unique_ptr(
quote_spanned! {end_span=>
#unsafe_token impl #impl_generics ::cxx::private::UniquePtrTarget for #ident #ty_generics {
- #[doc(hidden)]
- fn __typename(f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {
f.write_str(#name)
}
- #[doc(hidden)]
- fn __null() -> ::std::mem::MaybeUninit<*mut ::std::ffi::c_void> {
+ fn __null() -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {
extern "C" {
#[link_name = #link_null]
- fn __null(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>);
+ fn __null(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>);
}
- let mut repr = ::std::mem::MaybeUninit::uninit();
+ let mut repr = ::cxx::core::mem::MaybeUninit::uninit();
unsafe { __null(&mut repr) }
repr
}
#new_method
- #[doc(hidden)]
- unsafe fn __raw(raw: *mut Self) -> ::std::mem::MaybeUninit<*mut ::std::ffi::c_void> {
+ unsafe fn __raw(raw: *mut Self) -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {
extern "C" {
#[link_name = #link_raw]
- fn __raw(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>, raw: *mut ::std::ffi::c_void);
+ fn __raw(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>, raw: *mut ::cxx::core::ffi::c_void);
}
- let mut repr = ::std::mem::MaybeUninit::uninit();
+ let mut repr = ::cxx::core::mem::MaybeUninit::uninit();
__raw(&mut repr, raw.cast());
repr
}
- #[doc(hidden)]
- unsafe fn __get(repr: ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *const Self {
+ unsafe fn __get(repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const Self {
extern "C" {
#[link_name = #link_get]
- fn __get(this: *const ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *const ::std::ffi::c_void;
+ fn __get(this: *const ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::core::ffi::c_void;
}
__get(&repr).cast()
}
- #[doc(hidden)]
- unsafe fn __release(mut repr: ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *mut Self {
+ unsafe fn __release(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut Self {
extern "C" {
#[link_name = #link_release]
- fn __release(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *mut ::std::ffi::c_void;
+ fn __release(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::core::ffi::c_void;
}
__release(&mut repr).cast()
}
- #[doc(hidden)]
- unsafe fn __drop(mut repr: ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) {
+ unsafe fn __drop(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) {
extern "C" {
#[link_name = #link_drop]
- fn __drop(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>);
+ fn __drop(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>);
}
__drop(&mut repr);
}
@@ -1427,11 +1480,10 @@ fn expand_shared_ptr(
let can_construct_from_value = types.is_maybe_trivial(ident);
let new_method = if can_construct_from_value {
Some(quote! {
- #[doc(hidden)]
- unsafe fn __new(value: Self, new: *mut ::std::ffi::c_void) {
+ unsafe fn __new(value: Self, new: *mut ::cxx::core::ffi::c_void) {
extern "C" {
#[link_name = #link_uninit]
- fn __uninit(new: *mut ::std::ffi::c_void) -> *mut ::std::ffi::c_void;
+ fn __uninit(new: *mut ::cxx::core::ffi::c_void) -> *mut ::cxx::core::ffi::c_void;
}
__uninit(new).cast::<#ident #ty_generics>().write(value);
}
@@ -1446,40 +1498,35 @@ fn expand_shared_ptr(
quote_spanned! {end_span=>
#unsafe_token impl #impl_generics ::cxx::private::SharedPtrTarget for #ident #ty_generics {
- #[doc(hidden)]
- fn __typename(f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {
f.write_str(#name)
}
- #[doc(hidden)]
- unsafe fn __null(new: *mut ::std::ffi::c_void) {
+ unsafe fn __null(new: *mut ::cxx::core::ffi::c_void) {
extern "C" {
#[link_name = #link_null]
- fn __null(new: *mut ::std::ffi::c_void);
+ fn __null(new: *mut ::cxx::core::ffi::c_void);
}
__null(new);
}
#new_method
- #[doc(hidden)]
- unsafe fn __clone(this: *const ::std::ffi::c_void, new: *mut ::std::ffi::c_void) {
+ unsafe fn __clone(this: *const ::cxx::core::ffi::c_void, new: *mut ::cxx::core::ffi::c_void) {
extern "C" {
#[link_name = #link_clone]
- fn __clone(this: *const ::std::ffi::c_void, new: *mut ::std::ffi::c_void);
+ fn __clone(this: *const ::cxx::core::ffi::c_void, new: *mut ::cxx::core::ffi::c_void);
}
__clone(this, new);
}
- #[doc(hidden)]
- unsafe fn __get(this: *const ::std::ffi::c_void) -> *const Self {
+ unsafe fn __get(this: *const ::cxx::core::ffi::c_void) -> *const Self {
extern "C" {
#[link_name = #link_get]
- fn __get(this: *const ::std::ffi::c_void) -> *const ::std::ffi::c_void;
+ fn __get(this: *const ::cxx::core::ffi::c_void) -> *const ::cxx::core::ffi::c_void;
}
__get(this).cast()
}
- #[doc(hidden)]
- unsafe fn __drop(this: *mut ::std::ffi::c_void) {
+ unsafe fn __drop(this: *mut ::cxx::core::ffi::c_void) {
extern "C" {
#[link_name = #link_drop]
- fn __drop(this: *mut ::std::ffi::c_void);
+ fn __drop(this: *mut ::cxx::core::ffi::c_void);
}
__drop(this);
}
@@ -1506,47 +1553,41 @@ fn expand_weak_ptr(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl
quote_spanned! {end_span=>
#unsafe_token impl #impl_generics ::cxx::private::WeakPtrTarget for #ident #ty_generics {
- #[doc(hidden)]
- fn __typename(f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {
f.write_str(#name)
}
- #[doc(hidden)]
- unsafe fn __null(new: *mut ::std::ffi::c_void) {
+ unsafe fn __null(new: *mut ::cxx::core::ffi::c_void) {
extern "C" {
#[link_name = #link_null]
- fn __null(new: *mut ::std::ffi::c_void);
+ fn __null(new: *mut ::cxx::core::ffi::c_void);
}
__null(new);
}
- #[doc(hidden)]
- unsafe fn __clone(this: *const ::std::ffi::c_void, new: *mut ::std::ffi::c_void) {
+ unsafe fn __clone(this: *const ::cxx::core::ffi::c_void, new: *mut ::cxx::core::ffi::c_void) {
extern "C" {
#[link_name = #link_clone]
- fn __clone(this: *const ::std::ffi::c_void, new: *mut ::std::ffi::c_void);
+ fn __clone(this: *const ::cxx::core::ffi::c_void, new: *mut ::cxx::core::ffi::c_void);
}
__clone(this, new);
}
- #[doc(hidden)]
- unsafe fn __downgrade(shared: *const ::std::ffi::c_void, weak: *mut ::std::ffi::c_void) {
+ unsafe fn __downgrade(shared: *const ::cxx::core::ffi::c_void, weak: *mut ::cxx::core::ffi::c_void) {
extern "C" {
#[link_name = #link_downgrade]
- fn __downgrade(shared: *const ::std::ffi::c_void, weak: *mut ::std::ffi::c_void);
+ fn __downgrade(shared: *const ::cxx::core::ffi::c_void, weak: *mut ::cxx::core::ffi::c_void);
}
__downgrade(shared, weak);
}
- #[doc(hidden)]
- unsafe fn __upgrade(weak: *const ::std::ffi::c_void, shared: *mut ::std::ffi::c_void) {
+ unsafe fn __upgrade(weak: *const ::cxx::core::ffi::c_void, shared: *mut ::cxx::core::ffi::c_void) {
extern "C" {
#[link_name = #link_upgrade]
- fn __upgrade(weak: *const ::std::ffi::c_void, shared: *mut ::std::ffi::c_void);
+ fn __upgrade(weak: *const ::cxx::core::ffi::c_void, shared: *mut ::cxx::core::ffi::c_void);
}
__upgrade(weak, shared);
}
- #[doc(hidden)]
- unsafe fn __drop(this: *mut ::std::ffi::c_void) {
+ unsafe fn __drop(this: *mut ::cxx::core::ffi::c_void) {
extern "C" {
#[link_name = #link_drop]
- fn __drop(this: *mut ::std::ffi::c_void);
+ fn __drop(this: *mut ::cxx::core::ffi::c_void);
}
__drop(this);
}
@@ -1586,33 +1627,31 @@ fn expand_cxx_vector(
let can_pass_element_by_value = types.is_maybe_trivial(elem);
let by_value_methods = if can_pass_element_by_value {
Some(quote_spanned! {end_span=>
- #[doc(hidden)]
unsafe fn __push_back(
- this: ::std::pin::Pin<&mut ::cxx::CxxVector<Self>>,
- value: &mut ::std::mem::ManuallyDrop<Self>,
+ this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<Self>>,
+ value: &mut ::cxx::core::mem::ManuallyDrop<Self>,
) {
extern "C" {
#[link_name = #link_push_back]
fn __push_back #impl_generics(
- this: ::std::pin::Pin<&mut ::cxx::CxxVector<#elem #ty_generics>>,
- value: *mut ::std::ffi::c_void,
+ this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#elem #ty_generics>>,
+ value: *mut ::cxx::core::ffi::c_void,
);
}
- __push_back(this, value as *mut ::std::mem::ManuallyDrop<Self> as *mut ::std::ffi::c_void);
+ __push_back(this, value as *mut ::cxx::core::mem::ManuallyDrop<Self> as *mut ::cxx::core::ffi::c_void);
}
- #[doc(hidden)]
unsafe fn __pop_back(
- this: ::std::pin::Pin<&mut ::cxx::CxxVector<Self>>,
- out: &mut ::std::mem::MaybeUninit<Self>,
+ this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<Self>>,
+ out: &mut ::cxx::core::mem::MaybeUninit<Self>,
) {
extern "C" {
#[link_name = #link_pop_back]
fn __pop_back #impl_generics(
- this: ::std::pin::Pin<&mut ::cxx::CxxVector<#elem #ty_generics>>,
- out: *mut ::std::ffi::c_void,
+ this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#elem #ty_generics>>,
+ out: *mut ::cxx::core::ffi::c_void,
);
}
- __pop_back(this, out as *mut ::std::mem::MaybeUninit<Self> as *mut ::std::ffi::c_void);
+ __pop_back(this, out as *mut ::cxx::core::mem::MaybeUninit<Self> as *mut ::cxx::core::ffi::c_void);
}
})
} else {
@@ -1621,11 +1660,9 @@ fn expand_cxx_vector(
quote_spanned! {end_span=>
#unsafe_token impl #impl_generics ::cxx::private::VectorElement for #elem #ty_generics {
- #[doc(hidden)]
- fn __typename(f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result {
f.write_str(#name)
}
- #[doc(hidden)]
fn __vector_size(v: &::cxx::CxxVector<Self>) -> usize {
extern "C" {
#[link_name = #link_size]
@@ -1633,59 +1670,53 @@ fn expand_cxx_vector(
}
unsafe { __vector_size(v) }
}
- #[doc(hidden)]
unsafe fn __get_unchecked(v: *mut ::cxx::CxxVector<Self>, pos: usize) -> *mut Self {
extern "C" {
#[link_name = #link_get_unchecked]
fn __get_unchecked #impl_generics(
v: *mut ::cxx::CxxVector<#elem #ty_generics>,
pos: usize,
- ) -> *mut ::std::ffi::c_void;
+ ) -> *mut ::cxx::core::ffi::c_void;
}
__get_unchecked(v, pos) as *mut Self
}
#by_value_methods
- #[doc(hidden)]
- fn __unique_ptr_null() -> ::std::mem::MaybeUninit<*mut ::std::ffi::c_void> {
+ fn __unique_ptr_null() -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {
extern "C" {
#[link_name = #link_unique_ptr_null]
- fn __unique_ptr_null(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>);
+ fn __unique_ptr_null(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>);
}
- let mut repr = ::std::mem::MaybeUninit::uninit();
+ let mut repr = ::cxx::core::mem::MaybeUninit::uninit();
unsafe { __unique_ptr_null(&mut repr) }
repr
}
- #[doc(hidden)]
- unsafe fn __unique_ptr_raw(raw: *mut ::cxx::CxxVector<Self>) -> ::std::mem::MaybeUninit<*mut ::std::ffi::c_void> {
+ unsafe fn __unique_ptr_raw(raw: *mut ::cxx::CxxVector<Self>) -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> {
extern "C" {
#[link_name = #link_unique_ptr_raw]
- fn __unique_ptr_raw #impl_generics(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>, raw: *mut ::cxx::CxxVector<#elem #ty_generics>);
+ fn __unique_ptr_raw #impl_generics(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>, raw: *mut ::cxx::CxxVector<#elem #ty_generics>);
}
- let mut repr = ::std::mem::MaybeUninit::uninit();
+ let mut repr = ::cxx::core::mem::MaybeUninit::uninit();
__unique_ptr_raw(&mut repr, raw);
repr
}
- #[doc(hidden)]
- unsafe fn __unique_ptr_get(repr: ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *const ::cxx::CxxVector<Self> {
+ unsafe fn __unique_ptr_get(repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::CxxVector<Self> {
extern "C" {
#[link_name = #link_unique_ptr_get]
- fn __unique_ptr_get #impl_generics(this: *const ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *const ::cxx::CxxVector<#elem #ty_generics>;
+ fn __unique_ptr_get #impl_generics(this: *const ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::CxxVector<#elem #ty_generics>;
}
__unique_ptr_get(&repr)
}
- #[doc(hidden)]
- unsafe fn __unique_ptr_release(mut repr: ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *mut ::cxx::CxxVector<Self> {
+ unsafe fn __unique_ptr_release(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::CxxVector<Self> {
extern "C" {
#[link_name = #link_unique_ptr_release]
- fn __unique_ptr_release #impl_generics(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) -> *mut ::cxx::CxxVector<#elem #ty_generics>;
+ fn __unique_ptr_release #impl_generics(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::CxxVector<#elem #ty_generics>;
}
__unique_ptr_release(&mut repr)
}
- #[doc(hidden)]
- unsafe fn __unique_ptr_drop(mut repr: ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>) {
+ unsafe fn __unique_ptr_drop(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) {
extern "C" {
#[link_name = #link_unique_ptr_drop]
- fn __unique_ptr_drop(this: *mut ::std::mem::MaybeUninit<*mut ::std::ffi::c_void>);
+ fn __unique_ptr_drop(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>);
}
__unique_ptr_drop(&mut repr);
}
@@ -1715,7 +1746,7 @@ fn expand_extern_type(ty: &Type, types: &Types, proper: bool) -> TokenStream {
Type::RustBox(ty) | Type::UniquePtr(ty) => {
let span = ty.name.span();
if proper && types.is_considered_improper_ctype(&ty.inner) {
- quote_spanned!(span=> *mut ::std::ffi::c_void)
+ quote_spanned!(span=> *mut ::cxx::core::ffi::c_void)
} else {
let inner = expand_extern_type(&ty.inner, types, proper);
quote_spanned!(span=> *mut #inner)
@@ -1747,8 +1778,8 @@ fn expand_extern_type(ty: &Type, types: &Types, proper: bool) -> TokenStream {
inner if proper && types.is_considered_improper_ctype(inner) => {
let star = Token![*](ampersand.span);
match ty.mutable {
- false => quote!(#star const ::std::ffi::c_void),
- true => quote!(#star #mutability ::std::ffi::c_void),
+ false => quote!(#star const ::cxx::core::ffi::c_void),
+ true => quote!(#star #mutability ::cxx::core::ffi::c_void),
}
}
_ => quote!(#ty),
@@ -1759,7 +1790,7 @@ fn expand_extern_type(ty: &Type, types: &Types, proper: bool) -> TokenStream {
let star = ty.star;
let mutability = ty.mutability;
let constness = ty.constness;
- quote!(#star #mutability #constness ::std::ffi::c_void)
+ quote!(#star #mutability #constness ::cxx::core::ffi::c_void)
} else {
quote!(#ty)
}
diff --git a/macro/src/generics.rs b/macro/src/generics.rs
index 3de0330b..7862536d 100644
--- a/macro/src/generics.rs
+++ b/macro/src/generics.rs
@@ -1,9 +1,9 @@
use crate::syntax::instantiate::NamedImplKey;
use crate::syntax::resolve::Resolution;
-use crate::syntax::Impl;
+use crate::syntax::{Impl, Lifetimes};
use proc_macro2::TokenStream;
use quote::ToTokens;
-use syn::Token;
+use syn::{Lifetime, Token};
pub struct ImplGenerics<'a> {
explicit_impl: Option<&'a Impl>,
@@ -61,3 +61,31 @@ impl<'a> ToTokens for TyGenerics<'a> {
}
}
}
+
+pub struct UnderscoreLifetimes<'a> {
+ generics: &'a Lifetimes,
+}
+
+impl Lifetimes {
+ pub fn to_underscore_lifetimes(&self) -> UnderscoreLifetimes {
+ UnderscoreLifetimes { generics: self }
+ }
+}
+
+impl<'a> ToTokens for UnderscoreLifetimes<'a> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let Lifetimes {
+ lt_token,
+ lifetimes,
+ gt_token,
+ } = self.generics;
+ lt_token.to_tokens(tokens);
+ for pair in lifetimes.pairs() {
+ let (lifetime, punct) = pair.into_tuple();
+ let lifetime = Lifetime::new("'_", lifetime.span());
+ lifetime.to_tokens(tokens);
+ punct.to_tokens(tokens);
+ }
+ gt_token.to_tokens(tokens);
+ }
+}
diff --git a/macro/src/lib.rs b/macro/src/lib.rs
index 324881d8..138e3a29 100644
--- a/macro/src/lib.rs
+++ b/macro/src/lib.rs
@@ -1,6 +1,7 @@
#![allow(
clippy::cast_sign_loss,
clippy::default_trait_access,
+ clippy::derive_partial_eq_without_eq,
clippy::doc_markdown,
clippy::enum_glob_use,
clippy::if_same_then_else,
@@ -34,11 +35,12 @@ mod derive;
mod expand;
mod generics;
mod syntax;
+mod tokens;
mod type_id;
-#[cfg(feature = "experimental")]
+#[cfg(feature = "experimental-enum-variants-from-header")]
mod clang;
-#[cfg(feature = "experimental")]
+#[cfg(feature = "experimental-enum-variants-from-header")]
mod load;
use crate::syntax::file::Module;
diff --git a/macro/src/load.rs b/macro/src/load.rs
index d769ebf6..dccece44 100644
--- a/macro/src/load.rs
+++ b/macro/src/load.rs
@@ -1,5 +1,6 @@
use crate::clang::{Clang, Node};
use crate::syntax::attrs::OtherAttrs;
+use crate::syntax::cfg::CfgExpr;
use crate::syntax::namespace::Namespace;
use crate::syntax::report::Errors;
use crate::syntax::{Api, Discriminant, Doc, Enum, EnumRepr, ForeignName, Pair, Variant};
@@ -58,10 +59,10 @@ pub fn load(cx: &mut Errors, apis: &mut [Api]) {
let is_gzipped = memmap.get(..2) == Some(b"\x1f\x8b");
if is_gzipped {
gunzipped = Vec::new();
- let decode_result = GzDecoder::new(&mut gunzipped).write_all(&memmap);
+ let decode_result = GzDecoder::new(&mut gunzipped).write_all(memmap);
decode_result.map(|_| gunzipped.as_slice())
} else {
- Ok(&memmap as &[u8])
+ Ok(memmap as &[u8])
}
}
Err(error) => Err(error),
@@ -142,7 +143,7 @@ fn traverse<'a>(
};
let repr = translate_qual_type(
cx,
- &enm,
+ enm,
fixed_underlying_type
.desugared_qual_type
.as_ref()
@@ -207,6 +208,7 @@ fn traverse<'a>(
}
};
enm.variants.push(Variant {
+ cfg: CfgExpr::Unconditional,
doc: Doc::new(),
attrs: OtherAttrs::none(),
name: Pair {
@@ -262,7 +264,7 @@ fn translate_qual_type(cx: &mut Errors, enm: &Enum, qual_type: &str) -> Path {
.unwrap()
.span();
let ident = Ident::new(rust_std_name, span);
- let path = quote_spanned!(span=> ::std::os::raw::#ident);
+ let path = quote_spanned!(span=> ::cxx::core::ffi::#ident);
parse_quote!(#path)
}
diff --git a/macro/src/tokens.rs b/macro/src/tokens.rs
new file mode 100644
index 00000000..805af227
--- /dev/null
+++ b/macro/src/tokens.rs
@@ -0,0 +1,75 @@
+use crate::syntax::Receiver;
+use proc_macro2::TokenStream;
+use quote::{quote_spanned, ToTokens};
+use syn::Token;
+
+pub struct ReceiverType<'a>(&'a Receiver);
+pub struct ReceiverTypeSelf<'a>(&'a Receiver);
+
+impl Receiver {
+ // &TheType
+ pub fn ty(&self) -> ReceiverType {
+ ReceiverType(self)
+ }
+
+ // &Self
+ pub fn ty_self(&self) -> ReceiverTypeSelf {
+ ReceiverTypeSelf(self)
+ }
+}
+
+impl ToTokens for ReceiverType<'_> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let Receiver {
+ pinned: _,
+ ampersand,
+ lifetime,
+ mutable: _,
+ var: _,
+ colon_token: _,
+ ty,
+ shorthand: _,
+ pin_tokens,
+ mutability,
+ } = &self.0;
+ if let Some((pin, langle, _rangle)) = pin_tokens {
+ tokens.extend(quote_spanned!(pin.span=> ::cxx::core::pin::Pin));
+ langle.to_tokens(tokens);
+ }
+ ampersand.to_tokens(tokens);
+ lifetime.to_tokens(tokens);
+ mutability.to_tokens(tokens);
+ ty.to_tokens(tokens);
+ if let Some((_pin, _langle, rangle)) = pin_tokens {
+ rangle.to_tokens(tokens);
+ }
+ }
+}
+
+impl ToTokens for ReceiverTypeSelf<'_> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let Receiver {
+ pinned: _,
+ ampersand,
+ lifetime,
+ mutable: _,
+ var: _,
+ colon_token: _,
+ ty,
+ shorthand: _,
+ pin_tokens,
+ mutability,
+ } = &self.0;
+ if let Some((pin, langle, _rangle)) = pin_tokens {
+ tokens.extend(quote_spanned!(pin.span=> ::cxx::core::pin::Pin));
+ langle.to_tokens(tokens);
+ }
+ ampersand.to_tokens(tokens);
+ lifetime.to_tokens(tokens);
+ mutability.to_tokens(tokens);
+ Token![Self](ty.rust.span()).to_tokens(tokens);
+ if let Some((_pin, _langle, rangle)) = pin_tokens {
+ rangle.to_tokens(tokens);
+ }
+ }
+}
diff --git a/macro/src/type_id.rs b/macro/src/type_id.rs
index 74f0c1c9..7bca67b1 100644
--- a/macro/src/type_id.rs
+++ b/macro/src/type_id.rs
@@ -1,6 +1,7 @@
use crate::syntax::qualified::QualifiedName;
use proc_macro2::{TokenStream, TokenTree};
use quote::{format_ident, quote, ToTokens};
+use syn::ext::IdentExt;
pub enum Crate {
Cxx,
@@ -24,7 +25,7 @@ pub fn expand(krate: Crate, arg: QualifiedName) -> TokenStream {
if !ids.is_empty() {
ids.push(quote!(()));
}
- for ch in word.to_string().chars() {
+ for ch in word.unraw().to_string().chars() {
ids.push(match ch {
'A'..='Z' | 'a'..='z' => {
let t = format_ident!("{}", ch);
diff --git a/src/c_char.rs b/src/c_char.rs
new file mode 100644
index 00000000..333d8491
--- /dev/null
+++ b/src/c_char.rs
@@ -0,0 +1,69 @@
+#[allow(missing_docs)]
+pub type c_char = c_char_definition::c_char;
+
+// Validate that our definition is consistent with libstd's definition, without
+// introducing a dependency on libstd in ordinary builds.
+#[cfg(all(test, feature = "std"))]
+const _: self::c_char = 0 as std::os::raw::c_char;
+
+#[allow(dead_code)]
+mod c_char_definition {
+ // These are the targets on which c_char is unsigned.
+ #[cfg(any(
+ all(
+ target_os = "linux",
+ any(
+ target_arch = "aarch64",
+ target_arch = "arm",
+ target_arch = "hexagon",
+ target_arch = "powerpc",
+ target_arch = "powerpc64",
+ target_arch = "s390x",
+ target_arch = "riscv64",
+ target_arch = "riscv32"
+ )
+ ),
+ all(
+ target_os = "android",
+ any(target_arch = "aarch64", target_arch = "arm")
+ ),
+ all(target_os = "l4re", target_arch = "x86_64"),
+ all(
+ target_os = "freebsd",
+ any(
+ target_arch = "aarch64",
+ target_arch = "arm",
+ target_arch = "powerpc",
+ target_arch = "powerpc64",
+ target_arch = "riscv64"
+ )
+ ),
+ all(
+ target_os = "netbsd",
+ any(target_arch = "aarch64", target_arch = "arm", target_arch = "powerpc")
+ ),
+ all(target_os = "openbsd", target_arch = "aarch64"),
+ all(
+ target_os = "vxworks",
+ any(
+ target_arch = "aarch64",
+ target_arch = "arm",
+ target_arch = "powerpc64",
+ target_arch = "powerpc"
+ )
+ ),
+ all(target_os = "fuchsia", target_arch = "aarch64")
+ ))]
+ pub use self::unsigned::c_char;
+
+ // On every other target, c_char is signed.
+ pub use self::signed::*;
+
+ mod unsigned {
+ pub type c_char = u8;
+ }
+
+ mod signed {
+ pub type c_char = i8;
+ }
+}
diff --git a/src/cxx.cc b/src/cxx.cc
index 5dca531b..a7cb6797 100644
--- a/src/cxx.cc
+++ b/src/cxx.cc
@@ -40,8 +40,12 @@ void cxxbridge1$string$clone(rust::String *self,
const rust::String &other) noexcept;
bool cxxbridge1$string$from_utf8(rust::String *self, const char *ptr,
std::size_t len) noexcept;
+void cxxbridge1$string$from_utf8_lossy(rust::String *self, const char *ptr,
+ std::size_t len) noexcept;
bool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr,
std::size_t len) noexcept;
+void cxxbridge1$string$from_utf16_lossy(rust::String *self, const char16_t *ptr,
+ std::size_t len) noexcept;
void cxxbridge1$string$drop(rust::String *self) noexcept;
const char *cxxbridge1$string$ptr(const rust::String *self) noexcept;
std::size_t cxxbridge1$string$len(const rust::String *self) noexcept;
@@ -81,6 +85,12 @@ void panic [[noreturn]] (const char *msg) {
template void panic<std::out_of_range> [[noreturn]] (const char *msg);
+template <typename T>
+static bool is_aligned(const void *ptr) noexcept {
+ auto iptr = reinterpret_cast<std::uintptr_t>(ptr);
+ return !(iptr % alignof(T));
+}
+
String::String() noexcept { cxxbridge1$string$new(this); }
String::String(const String &other) noexcept {
@@ -121,17 +131,60 @@ String::String(const char *s, std::size_t len) {
String::String(const char16_t *s) {
assert(s != nullptr);
+ assert(is_aligned<char16_t>(s));
initString(this, s, std::char_traits<char16_t>::length(s));
}
String::String(const char16_t *s, std::size_t len) {
assert(s != nullptr || len == 0);
+ assert(is_aligned<char16_t>(s));
initString(this,
s == nullptr && len == 0 ? reinterpret_cast<const char16_t *>(2)
: s,
len);
}
+struct String::lossy_t {};
+
+String::String(lossy_t, const char *s, std::size_t len) noexcept {
+ cxxbridge1$string$from_utf8_lossy(
+ this, s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
+ len);
+}
+
+String::String(lossy_t, const char16_t *s, std::size_t len) noexcept {
+ cxxbridge1$string$from_utf16_lossy(
+ this,
+ s == nullptr && len == 0 ? reinterpret_cast<const char16_t *>(2) : s,
+ len);
+}
+
+String String::lossy(const std::string &s) noexcept {
+ return String::lossy(s.data(), s.length());
+}
+
+String String::lossy(const char *s) noexcept {
+ assert(s != nullptr);
+ return String::lossy(s, std::strlen(s));
+}
+
+String String::lossy(const char *s, std::size_t len) noexcept {
+ assert(s != nullptr || len == 0);
+ return String(lossy_t{}, s, len);
+}
+
+String String::lossy(const char16_t *s) noexcept {
+ assert(s != nullptr);
+ assert(is_aligned<char16_t>(s));
+ return String(lossy_t{}, s, std::char_traits<char16_t>::length(s));
+}
+
+String String::lossy(const char16_t *s, std::size_t len) noexcept {
+ assert(s != nullptr || len == 0);
+ assert(is_aligned<char16_t>(s));
+ return String(lossy_t{}, s, len);
+}
+
String &String::operator=(const String &other) &noexcept {
if (this != &other) {
cxxbridge1$string$drop(this);
@@ -453,6 +506,17 @@ union MaybeUninit {
};
} // namespace
+namespace repr {
+struct PtrLen final {
+ void *ptr;
+ std::size_t len;
+};
+} // namespace repr
+
+extern "C" {
+repr::PtrLen cxxbridge1$exception(const char *, std::size_t len) noexcept;
+}
+
namespace detail {
// On some platforms size_t is the same C++ type as one of the sized integer
// types; on others it is a distinct type. Only in the latter case do we need to
@@ -466,6 +530,23 @@ using isize_if_unique =
typename std::conditional<std::is_same<rust::isize, int64_t>::value ||
std::is_same<rust::isize, int32_t>::value,
struct isize_ignore, rust::isize>::type;
+
+class Fail final {
+ repr::PtrLen &throw$;
+
+public:
+ Fail(repr::PtrLen &throw$) noexcept : throw$(throw$) {}
+ void operator()(const char *) noexcept;
+ void operator()(const std::string &) noexcept;
+};
+
+void Fail::operator()(const char *catch$) noexcept {
+ throw$ = cxxbridge1$exception(catch$, std::strlen(catch$));
+}
+
+void Fail::operator()(const std::string &catch$) noexcept {
+ throw$ = cxxbridge1$exception(catch$.data(), catch$.length());
+}
} // namespace detail
} // namespace cxxbridge1
@@ -568,7 +649,9 @@ static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *),
void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total( \
rust::Vec<CXX_TYPE> *ptr, std::size_t new_cap) noexcept; \
void cxxbridge1$rust_vec$##RUST_TYPE##$set_len(rust::Vec<CXX_TYPE> *ptr, \
- std::size_t len) noexcept;
+ std::size_t len) noexcept; \
+ void cxxbridge1$rust_vec$##RUST_TYPE##$truncate(rust::Vec<CXX_TYPE> *ptr, \
+ std::size_t len) noexcept;
#define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE) \
template <> \
@@ -598,6 +681,10 @@ static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *),
template <> \
void Vec<CXX_TYPE>::set_len(std::size_t len) noexcept { \
cxxbridge1$rust_vec$##RUST_TYPE##$set_len(this, len); \
+ } \
+ template <> \
+ void Vec<CXX_TYPE>::truncate(std::size_t len) { \
+ cxxbridge1$rust_vec$##RUST_TYPE##$truncate(this, len); \
}
#define SHARED_PTR_OPS(RUST_TYPE, CXX_TYPE) \
diff --git a/src/cxx_string.rs b/src/cxx_string.rs
index 626c2c85..9ecbcc64 100644
--- a/src/cxx_string.rs
+++ b/src/cxx_string.rs
@@ -1,5 +1,8 @@
use crate::actually_private::Private;
+use crate::lossy;
+#[cfg(feature = "alloc")]
use alloc::borrow::Cow;
+#[cfg(feature = "alloc")]
use alloc::string::String;
use core::cmp::Ordering;
use core::fmt::{self, Debug, Display};
@@ -144,6 +147,8 @@ impl CxxString {
/// Cow::Owned String.
///
/// [replacement character]: https://doc.rust-lang.org/std/char/constant.REPLACEMENT_CHARACTER.html
+ #[cfg(feature = "alloc")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
pub fn to_string_lossy(&self) -> Cow<str> {
String::from_utf8_lossy(self.as_bytes())
}
@@ -204,13 +209,13 @@ impl CxxString {
impl Display for CxxString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- Display::fmt(self.to_string_lossy().as_ref(), f)
+ lossy::display(self.as_bytes(), f)
}
}
impl Debug for CxxString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- Debug::fmt(self.to_string_lossy().as_ref(), f)
+ lossy::debug(self.as_bytes(), f)
}
}
diff --git a/src/cxx_vector.rs b/src/cxx_vector.rs
index d1fa23a2..abf9297a 100644
--- a/src/cxx_vector.rs
+++ b/src/cxx_vector.rs
@@ -368,7 +368,6 @@ pub unsafe trait VectorElement: Sized {
macro_rules! vector_element_by_value_methods {
(opaque, $segment:expr, $ty:ty) => {};
(trivial, $segment:expr, $ty:ty) => {
- #[doc(hidden)]
unsafe fn __push_back(v: Pin<&mut CxxVector<$ty>>, value: &mut ManuallyDrop<$ty>) {
extern "C" {
attr! {
@@ -378,7 +377,6 @@ macro_rules! vector_element_by_value_methods {
}
unsafe { __push_back(v, value) }
}
- #[doc(hidden)]
unsafe fn __pop_back(v: Pin<&mut CxxVector<$ty>>, out: &mut MaybeUninit<$ty>) {
extern "C" {
attr! {
@@ -397,11 +395,9 @@ macro_rules! impl_vector_element {
const_assert_eq!(1, mem::align_of::<CxxVector<$ty>>());
unsafe impl VectorElement for $ty {
- #[doc(hidden)]
fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
f.write_str($name)
}
- #[doc(hidden)]
fn __vector_size(v: &CxxVector<$ty>) -> usize {
extern "C" {
attr! {
@@ -411,7 +407,6 @@ macro_rules! impl_vector_element {
}
unsafe { __vector_size(v) }
}
- #[doc(hidden)]
unsafe fn __get_unchecked(v: *mut CxxVector<$ty>, pos: usize) -> *mut $ty {
extern "C" {
attr! {
@@ -422,7 +417,6 @@ macro_rules! impl_vector_element {
unsafe { __get_unchecked(v, pos) }
}
vector_element_by_value_methods!($kind, $segment, $ty);
- #[doc(hidden)]
fn __unique_ptr_null() -> MaybeUninit<*mut c_void> {
extern "C" {
attr! {
@@ -434,7 +428,6 @@ macro_rules! impl_vector_element {
unsafe { __unique_ptr_null(&mut repr) }
repr
}
- #[doc(hidden)]
unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> MaybeUninit<*mut c_void> {
extern "C" {
attr! {
@@ -446,7 +439,6 @@ macro_rules! impl_vector_element {
unsafe { __unique_ptr_raw(&mut repr, raw) }
repr
}
- #[doc(hidden)]
unsafe fn __unique_ptr_get(repr: MaybeUninit<*mut c_void>) -> *const CxxVector<Self> {
extern "C" {
attr! {
@@ -456,7 +448,6 @@ macro_rules! impl_vector_element {
}
unsafe { __unique_ptr_get(&repr) }
}
- #[doc(hidden)]
unsafe fn __unique_ptr_release(mut repr: MaybeUninit<*mut c_void>) -> *mut CxxVector<Self> {
extern "C" {
attr! {
@@ -466,7 +457,6 @@ macro_rules! impl_vector_element {
}
unsafe { __unique_ptr_release(&mut repr) }
}
- #[doc(hidden)]
unsafe fn __unique_ptr_drop(mut repr: MaybeUninit<*mut c_void>) {
extern "C" {
attr! {
diff --git a/src/exception.rs b/src/exception.rs
index 2ae470e7..259b27d4 100644
--- a/src/exception.rs
+++ b/src/exception.rs
@@ -1,7 +1,10 @@
+#![cfg(feature = "alloc")]
+
use alloc::boxed::Box;
use core::fmt::{self, Display};
/// Exception thrown from an `extern "C++"` function.
+#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
#[derive(Debug)]
pub struct Exception {
pub(crate) what: Box<str>,
@@ -13,6 +16,8 @@ impl Display for Exception {
}
}
+#[cfg(feature = "std")]
+#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
impl std::error::Error for Exception {}
impl Exception {
diff --git a/src/extern_type.rs b/src/extern_type.rs
index 8c9c2860..d131ae12 100644
--- a/src/extern_type.rs
+++ b/src/extern_type.rs
@@ -1,5 +1,6 @@
use self::kind::{Kind, Opaque, Trivial};
use crate::CxxString;
+#[cfg(feature = "alloc")]
use alloc::string::String;
/// A type for which the layout is determined by its C++ definition.
@@ -186,9 +187,11 @@ pub fn verify_extern_type<T: ExternType<Id = Id>, Id>() {}
pub fn verify_extern_kind<T: ExternType<Kind = Kind>, Kind: self::Kind>() {}
macro_rules! impl_extern_type {
- ($([$kind:ident] $($ty:path = $cxxpath:literal)*)*) => {
+ ($([$kind:ident] $($(#[$($attr:tt)*])* $ty:path = $cxxpath:literal)*)*) => {
$($(
+ $(#[$($attr)*])*
unsafe impl ExternType for $ty {
+ #[allow(unused_attributes)] // incorrect lint; this doc(hidden) attr *is* respected by rustdoc
#[doc(hidden)]
type Id = crate::type_id!($cxxpath);
type Kind = $kind;
@@ -212,6 +215,9 @@ impl_extern_type! {
isize = "rust::isize"
f32 = "float"
f64 = "double"
+
+ #[cfg(feature = "alloc")]
+ #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
String = "rust::String"
[Opaque]
diff --git a/src/fmt.rs b/src/fmt.rs
index db14a7c0..69614f80 100644
--- a/src/fmt.rs
+++ b/src/fmt.rs
@@ -1,4 +1,4 @@
-use std::fmt::{self, Display};
+use core::fmt::{self, Display};
pub(crate) fn display(fmt: impl Fn(&mut fmt::Formatter) -> fmt::Result) -> impl Display {
DisplayInvoke(fmt)
diff --git a/src/hash.rs b/src/hash.rs
new file mode 100644
index 00000000..4c92173f
--- /dev/null
+++ b/src/hash.rs
@@ -0,0 +1,12 @@
+use core::hash::{Hash, Hasher};
+
+#[doc(hidden)]
+pub fn hash<V: Hash>(value: &V) -> usize {
+ #[cfg(feature = "std")]
+ let mut hasher = std::collections::hash_map::DefaultHasher::new();
+ #[cfg(not(feature = "std"))]
+ let mut hasher = crate::sip::SipHasher13::new();
+
+ Hash::hash(value, &mut hasher);
+ Hasher::finish(&hasher) as usize
+}
diff --git a/src/lib.rs b/src/lib.rs
index 9880e711..3ddd887d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,7 +2,7 @@
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
-//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
//!
//! <br>
//!
@@ -364,10 +364,11 @@
//! </table>
#![no_std]
-#![doc(html_root_url = "https://docs.rs/cxx/1.0.54")]
+#![doc(html_root_url = "https://docs.rs/cxx/1.0.85")]
#![deny(improper_ctypes, improper_ctypes_definitions, missing_docs)]
#![cfg_attr(not(no_unsafe_op_in_unsafe_fn_lint), deny(unsafe_op_in_unsafe_fn))]
#![cfg_attr(no_unsafe_op_in_unsafe_fn_lint, allow(unused_unsafe))]
+#![cfg_attr(doc_cfg, feature(doc_cfg))]
#![allow(non_camel_case_types)]
#![allow(
clippy::cognitive_complexity,
@@ -388,6 +389,7 @@
clippy::or_fun_call,
clippy::ptr_arg,
clippy::toplevel_ref_arg,
+ clippy::transmute_undefined_repr, // clippy bug: https://github.com/rust-lang/rust-clippy/issues/8417
clippy::useless_let_if_seq,
clippy::wrong_self_convention
)]
@@ -395,18 +397,53 @@
#[cfg(built_with_cargo)]
extern crate link_cplusplus;
-extern crate alloc;
extern crate self as cxx;
-extern crate std;
+
+#[doc(hidden)]
+pub extern crate core;
+
+#[cfg(feature = "alloc")]
+#[doc(hidden)]
+pub extern crate alloc;
+
+#[cfg(not(feature = "alloc"))]
+extern crate core as alloc;
+
+#[cfg(feature = "std")]
+#[doc(hidden)]
+pub extern crate std;
+
+// Block inadvertent use of items from libstd, which does not otherwise produce
+// a compile-time error on edition 2018+.
+#[cfg(not(feature = "std"))]
+extern crate core as std;
+
+#[cfg(not(any(feature = "alloc", cxx_experimental_no_alloc)))]
+compile_error! {
+ 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'"#
+}
+
+#[cfg(all(compile_error_if_alloc, feature = "alloc"))]
+compile_error! {
+ r#"feature="alloc" is unexpectedly enabled"#
+}
+
+#[cfg(all(compile_error_if_std, feature = "std"))]
+compile_error! {
+ r#"feature="std" is unexpectedly enabled"#
+}
#[macro_use]
mod macros;
+mod c_char;
mod cxx_vector;
mod exception;
mod extern_type;
mod fmt;
mod function;
+mod hash;
+mod lossy;
pub mod memory;
mod opaque;
mod result;
@@ -416,6 +453,7 @@ mod rust_string;
mod rust_type;
mod rust_vec;
mod shared_ptr;
+mod sip;
#[path = "cxx_string.rs"]
mod string;
mod symbols;
@@ -426,6 +464,7 @@ pub mod vector;
mod weak_ptr;
pub use crate::cxx_vector::CxxVector;
+#[cfg(feature = "alloc")]
pub use crate::exception::Exception;
pub use crate::extern_type::{kind, ExternType};
pub use crate::shared_ptr::SharedPtr;
@@ -451,21 +490,27 @@ pub type Vector<T> = CxxVector<T>;
// Not public API.
#[doc(hidden)]
pub mod private {
+ pub use crate::c_char::c_char;
pub use crate::cxx_vector::VectorElement;
pub use crate::extern_type::{verify_extern_kind, verify_extern_type};
pub use crate::function::FatFunction;
+ pub use crate::hash::hash;
pub use crate::opaque::Opaque;
+ #[cfg(feature = "alloc")]
pub use crate::result::{r#try, Result};
pub use crate::rust_slice::RustSlice;
pub use crate::rust_str::RustStr;
+ #[cfg(feature = "alloc")]
pub use crate::rust_string::RustString;
pub use crate::rust_type::{ImplBox, ImplVec, RustType};
+ #[cfg(feature = "alloc")]
pub use crate::rust_vec::RustVec;
pub use crate::shared_ptr::SharedPtrTarget;
pub use crate::string::StackString;
pub use crate::unique_ptr::UniquePtrTarget;
- pub use crate::unwind::catch_unwind;
+ pub use crate::unwind::prevent_unwind;
pub use crate::weak_ptr::WeakPtrTarget;
+ pub use core::{concat, module_path};
pub use cxxbridge_macro::type_id;
}
diff --git a/src/lossy.rs b/src/lossy.rs
new file mode 100644
index 00000000..d68a2e7b
--- /dev/null
+++ b/src/lossy.rs
@@ -0,0 +1,67 @@
+use core::char;
+use core::fmt::{self, Write as _};
+use core::str;
+
+pub fn display(mut bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
+ loop {
+ match str::from_utf8(bytes) {
+ Ok(valid) => return f.write_str(valid),
+ Err(utf8_error) => {
+ let valid_up_to = utf8_error.valid_up_to();
+ let valid = unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) };
+ f.write_str(valid)?;
+ f.write_char(char::REPLACEMENT_CHARACTER)?;
+ if let Some(error_len) = utf8_error.error_len() {
+ bytes = &bytes[valid_up_to + error_len..];
+ } else {
+ return Ok(());
+ }
+ }
+ }
+ }
+}
+
+pub fn debug(mut bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_char('"')?;
+
+ while !bytes.is_empty() {
+ let from_utf8_result = str::from_utf8(bytes);
+ let valid = match from_utf8_result {
+ Ok(valid) => valid,
+ Err(utf8_error) => {
+ let valid_up_to = utf8_error.valid_up_to();
+ unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) }
+ }
+ };
+
+ let mut written = 0;
+ for (i, ch) in valid.char_indices() {
+ let esc = ch.escape_debug();
+ if esc.len() != 1 {
+ f.write_str(&valid[written..i])?;
+ for ch in esc {
+ f.write_char(ch)?;
+ }
+ written = i + ch.len_utf8();
+ }
+ }
+ f.write_str(&valid[written..])?;
+
+ match from_utf8_result {
+ Ok(_valid) => break,
+ Err(utf8_error) => {
+ let end_of_broken = if let Some(error_len) = utf8_error.error_len() {
+ valid.len() + error_len
+ } else {
+ bytes.len()
+ };
+ for b in &bytes[valid.len()..end_of_broken] {
+ write!(f, "\\x{:02x}", b)?;
+ }
+ bytes = &bytes[end_of_broken..];
+ }
+ }
+ }
+
+ f.write_char('"')
+}
diff --git a/src/result.rs b/src/result.rs
index d7a31f02..ba77858e 100644
--- a/src/result.rs
+++ b/src/result.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "alloc")]
#![allow(missing_docs)]
use crate::exception::Exception;
@@ -11,9 +12,9 @@ use core::str;
#[repr(C)]
#[derive(Copy, Clone)]
-struct PtrLen {
- ptr: NonNull<u8>,
- len: usize,
+pub struct PtrLen {
+ pub ptr: NonNull<u8>,
+ pub len: usize,
}
#[repr(C)]
diff --git a/src/rust_string.rs b/src/rust_string.rs
index 051e35c3..0e0c5a83 100644
--- a/src/rust_string.rs
+++ b/src/rust_string.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "alloc")]
#![allow(missing_docs)]
use alloc::string::String;
diff --git a/src/rust_vec.rs b/src/rust_vec.rs
index 9f4484db..acb7e890 100644
--- a/src/rust_vec.rs
+++ b/src/rust_vec.rs
@@ -1,3 +1,4 @@
+#![cfg(feature = "alloc")]
#![allow(missing_docs)]
use crate::rust_string::RustString;
@@ -67,6 +68,10 @@ impl<T> RustVec<T> {
pub unsafe fn set_len(&mut self, len: usize) {
unsafe { self.as_mut_vec().set_len(len) }
}
+
+ pub fn truncate(&mut self, len: usize) {
+ self.as_mut_vec().truncate(len);
+ }
}
impl RustVec<RustString> {
diff --git a/src/shared_ptr.rs b/src/shared_ptr.rs
index 317773d4..64c86619 100644
--- a/src/shared_ptr.rs
+++ b/src/shared_ptr.rs
@@ -101,6 +101,10 @@ where
}
}
+// SharedPtr is not a self-referential type and is safe to move out of a Pin,
+// regardless whether the pointer's target is Unpin.
+impl<T> Unpin for SharedPtr<T> where T: SharedPtrTarget {}
+
impl<T> Drop for SharedPtr<T>
where
T: SharedPtrTarget,
@@ -204,11 +208,9 @@ pub unsafe trait SharedPtrTarget {
macro_rules! impl_shared_ptr_target {
($segment:expr, $name:expr, $ty:ty) => {
unsafe impl SharedPtrTarget for $ty {
- #[doc(hidden)]
fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
f.write_str($name)
}
- #[doc(hidden)]
unsafe fn __null(new: *mut c_void) {
extern "C" {
attr! {
@@ -218,7 +220,6 @@ macro_rules! impl_shared_ptr_target {
}
unsafe { __null(new) }
}
- #[doc(hidden)]
unsafe fn __new(value: Self, new: *mut c_void) {
extern "C" {
attr! {
@@ -228,7 +229,6 @@ macro_rules! impl_shared_ptr_target {
}
unsafe { __uninit(new).cast::<$ty>().write(value) }
}
- #[doc(hidden)]
unsafe fn __clone(this: *const c_void, new: *mut c_void) {
extern "C" {
attr! {
@@ -238,7 +238,6 @@ macro_rules! impl_shared_ptr_target {
}
unsafe { __clone(this, new) }
}
- #[doc(hidden)]
unsafe fn __get(this: *const c_void) -> *const Self {
extern "C" {
attr! {
@@ -248,7 +247,6 @@ macro_rules! impl_shared_ptr_target {
}
unsafe { __get(this) }.cast()
}
- #[doc(hidden)]
unsafe fn __drop(this: *mut c_void) {
extern "C" {
attr! {
diff --git a/src/sip.rs b/src/sip.rs
new file mode 100644
index 00000000..9e1d050a
--- /dev/null
+++ b/src/sip.rs
@@ -0,0 +1,228 @@
+// Vendored from libstd:
+// https://github.com/rust-lang/rust/blob/1.57.0/library/core/src/hash/sip.rs
+//
+// TODO: maybe depend on a hasher from crates.io if this becomes annoying to
+// maintain, or change this to a simpler one.
+
+#![cfg(not(feature = "std"))]
+
+use core::cmp;
+use core::hash::Hasher;
+use core::mem;
+use core::ptr;
+
+/// An implementation of SipHash 1-3.
+///
+/// This is currently the default hashing function used by standard library
+/// (e.g., `collections::HashMap` uses it by default).
+///
+/// See: <https://131002.net/siphash>
+pub struct SipHasher13 {
+ k0: u64,
+ k1: u64,
+ length: usize, // how many bytes we've processed
+ state: State, // hash State
+ tail: u64, // unprocessed bytes le
+ ntail: usize, // how many bytes in tail are valid
+}
+
+#[derive(Clone, Copy)]
+#[repr(C)]
+struct State {
+ // v0, v2 and v1, v3 show up in pairs in the algorithm,
+ // and simd implementations of SipHash will use vectors
+ // of v02 and v13. By placing them in this order in the struct,
+ // the compiler can pick up on just a few simd optimizations by itself.
+ v0: u64,
+ v2: u64,
+ v1: u64,
+ v3: u64,
+}
+
+macro_rules! compress {
+ ($state:expr) => {
+ compress!($state.v0, $state.v1, $state.v2, $state.v3)
+ };
+ ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => {
+ $v0 = $v0.wrapping_add($v1);
+ $v1 = $v1.rotate_left(13);
+ $v1 ^= $v0;
+ $v0 = $v0.rotate_left(32);
+ $v2 = $v2.wrapping_add($v3);
+ $v3 = $v3.rotate_left(16);
+ $v3 ^= $v2;
+ $v0 = $v0.wrapping_add($v3);
+ $v3 = $v3.rotate_left(21);
+ $v3 ^= $v0;
+ $v2 = $v2.wrapping_add($v1);
+ $v1 = $v1.rotate_left(17);
+ $v1 ^= $v2;
+ $v2 = $v2.rotate_left(32);
+ };
+}
+
+/// Loads an integer of the desired type from a byte stream, in LE order. Uses
+/// `copy_nonoverlapping` to let the compiler generate the most efficient way
+/// to load it from a possibly unaligned address.
+///
+/// Unsafe because: unchecked indexing at i..i+size_of(int_ty)
+macro_rules! load_int_le {
+ ($buf:expr, $i:expr, $int_ty:ident) => {{
+ debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len());
+ let mut data = 0 as $int_ty;
+ ptr::copy_nonoverlapping(
+ $buf.as_ptr().add($i),
+ &mut data as *mut _ as *mut u8,
+ mem::size_of::<$int_ty>(),
+ );
+ data.to_le()
+ }};
+}
+
+/// Loads a u64 using up to 7 bytes of a byte slice. It looks clumsy but the
+/// `copy_nonoverlapping` calls that occur (via `load_int_le!`) all have fixed
+/// sizes and avoid calling `memcpy`, which is good for speed.
+///
+/// Unsafe because: unchecked indexing at start..start+len
+unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 {
+ debug_assert!(len < 8);
+ let mut i = 0; // current byte index (from LSB) in the output u64
+ let mut out = 0;
+ if i + 3 < len {
+ // SAFETY: `i` cannot be greater than `len`, and the caller must guarantee
+ // that the index start..start+len is in bounds.
+ out = unsafe { load_int_le!(buf, start + i, u32) } as u64;
+ i += 4;
+ }
+ if i + 1 < len {
+ // SAFETY: same as above.
+ out |= (unsafe { load_int_le!(buf, start + i, u16) } as u64) << (i * 8);
+ i += 2
+ }
+ if i < len {
+ // SAFETY: same as above.
+ out |= (unsafe { *buf.get_unchecked(start + i) } as u64) << (i * 8);
+ i += 1;
+ }
+ debug_assert_eq!(i, len);
+ out
+}
+
+impl SipHasher13 {
+ /// Creates a new `SipHasher13` with the two initial keys set to 0.
+ pub fn new() -> Self {
+ Self::new_with_keys(0, 0)
+ }
+
+ /// Creates a `SipHasher13` that is keyed off the provided keys.
+ fn new_with_keys(key0: u64, key1: u64) -> Self {
+ let mut state = SipHasher13 {
+ k0: key0,
+ k1: key1,
+ length: 0,
+ state: State {
+ v0: 0,
+ v1: 0,
+ v2: 0,
+ v3: 0,
+ },
+ tail: 0,
+ ntail: 0,
+ };
+ state.reset();
+ state
+ }
+
+ fn reset(&mut self) {
+ self.length = 0;
+ self.state.v0 = self.k0 ^ 0x736f6d6570736575;
+ self.state.v1 = self.k1 ^ 0x646f72616e646f6d;
+ self.state.v2 = self.k0 ^ 0x6c7967656e657261;
+ self.state.v3 = self.k1 ^ 0x7465646279746573;
+ self.ntail = 0;
+ }
+}
+
+impl Hasher for SipHasher13 {
+ // Note: no integer hashing methods (`write_u*`, `write_i*`) are defined
+ // for this type. We could add them, copy the `short_write` implementation
+ // in librustc_data_structures/sip128.rs, and add `write_u*`/`write_i*`
+ // methods to `SipHasher`, `SipHasher13`, and `DefaultHasher`. This would
+ // greatly speed up integer hashing by those hashers, at the cost of
+ // slightly slowing down compile speeds on some benchmarks. See #69152 for
+ // details.
+ fn write(&mut self, msg: &[u8]) {
+ let length = msg.len();
+ self.length += length;
+
+ let mut needed = 0;
+
+ if self.ntail != 0 {
+ needed = 8 - self.ntail;
+ // SAFETY: `cmp::min(length, needed)` is guaranteed to not be over `length`
+ self.tail |= unsafe { u8to64_le(msg, 0, cmp::min(length, needed)) } << (8 * self.ntail);
+ if length < needed {
+ self.ntail += length;
+ return;
+ } else {
+ self.state.v3 ^= self.tail;
+ Sip13Rounds::c_rounds(&mut self.state);
+ self.state.v0 ^= self.tail;
+ self.ntail = 0;
+ }
+ }
+
+ // Buffered tail is now flushed, process new input.
+ let len = length - needed;
+ let left = len & 0x7; // len % 8
+
+ let mut i = needed;
+ while i < len - left {
+ // SAFETY: because `len - left` is the biggest multiple of 8 under
+ // `len`, and because `i` starts at `needed` where `len` is `length - needed`,
+ // `i + 8` is guaranteed to be less than or equal to `length`.
+ let mi = unsafe { load_int_le!(msg, i, u64) };
+
+ self.state.v3 ^= mi;
+ Sip13Rounds::c_rounds(&mut self.state);
+ self.state.v0 ^= mi;
+
+ i += 8;
+ }
+
+ // SAFETY: `i` is now `needed + len.div_euclid(8) * 8`,
+ // so `i + left` = `needed + len` = `length`, which is by
+ // definition equal to `msg.len()`.
+ self.tail = unsafe { u8to64_le(msg, i, left) };
+ self.ntail = left;
+ }
+
+ fn finish(&self) -> u64 {
+ let mut state = self.state;
+
+ let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;
+
+ state.v3 ^= b;
+ Sip13Rounds::c_rounds(&mut state);
+ state.v0 ^= b;
+
+ state.v2 ^= 0xff;
+ Sip13Rounds::d_rounds(&mut state);
+
+ state.v0 ^ state.v1 ^ state.v2 ^ state.v3
+ }
+}
+
+struct Sip13Rounds;
+
+impl Sip13Rounds {
+ fn c_rounds(state: &mut State) {
+ compress!(state);
+ }
+
+ fn d_rounds(state: &mut State) {
+ compress!(state);
+ compress!(state);
+ compress!(state);
+ }
+}
diff --git a/src/symbols/exception.rs b/src/symbols/exception.rs
index cf0701ba..b8fe1b5d 100644
--- a/src/symbols/exception.rs
+++ b/src/symbols/exception.rs
@@ -1,10 +1,18 @@
+#![cfg(feature = "alloc")]
+
+use crate::result::PtrLen;
use alloc::boxed::Box;
use alloc::string::String;
+use core::ptr::NonNull;
use core::slice;
#[export_name = "cxxbridge1$exception"]
-unsafe extern "C" fn exception(ptr: *const u8, len: usize) -> *const u8 {
+unsafe extern "C" fn exception(ptr: *const u8, len: usize) -> PtrLen {
let slice = unsafe { slice::from_raw_parts(ptr, len) };
- let boxed = String::from_utf8_lossy(slice).into_owned().into_boxed_str();
- Box::leak(boxed).as_ptr()
+ let string = String::from_utf8_lossy(slice);
+ let len = string.len();
+ let raw_str = Box::into_raw(string.into_owned().into_boxed_str());
+ let raw_u8 = raw_str.cast::<u8>();
+ let nonnull = unsafe { NonNull::new_unchecked(raw_u8) };
+ PtrLen { ptr: nonnull, len }
}
diff --git a/src/symbols/rust_str.rs b/src/symbols/rust_str.rs
index 3d5ec344..3b33bc4a 100644
--- a/src/symbols/rust_str.rs
+++ b/src/symbols/rust_str.rs
@@ -1,3 +1,4 @@
+#[cfg(feature = "alloc")]
use alloc::string::String;
use core::mem::MaybeUninit;
use core::ptr;
@@ -10,6 +11,7 @@ unsafe extern "C" fn str_new(this: &mut MaybeUninit<&str>) {
unsafe { ptr::write(this, "") }
}
+#[cfg(feature = "alloc")]
#[export_name = "cxxbridge1$str$ref"]
unsafe extern "C" fn str_ref<'a>(this: &mut MaybeUninit<&'a str>, string: &'a String) {
let this = this.as_mut_ptr();
diff --git a/src/symbols/rust_string.rs b/src/symbols/rust_string.rs
index 49d40697..8b7c8c48 100644
--- a/src/symbols/rust_string.rs
+++ b/src/symbols/rust_string.rs
@@ -1,3 +1,5 @@
+#![cfg(feature = "alloc")]
+
use alloc::borrow::ToOwned;
use alloc::string::String;
use core::mem::{ManuallyDrop, MaybeUninit};
@@ -37,6 +39,18 @@ unsafe extern "C" fn string_from_utf8(
}
}
+#[export_name = "cxxbridge1$string$from_utf8_lossy"]
+unsafe extern "C" fn string_from_utf8_lossy(
+ this: &mut MaybeUninit<String>,
+ ptr: *const u8,
+ len: usize,
+) {
+ let slice = unsafe { slice::from_raw_parts(ptr, len) };
+ let owned = String::from_utf8_lossy(slice).into_owned();
+ let this = this.as_mut_ptr();
+ unsafe { ptr::write(this, owned) }
+}
+
#[export_name = "cxxbridge1$string$from_utf16"]
unsafe extern "C" fn string_from_utf16(
this: &mut MaybeUninit<String>,
@@ -54,6 +68,18 @@ unsafe extern "C" fn string_from_utf16(
}
}
+#[export_name = "cxxbridge1$string$from_utf16_lossy"]
+unsafe extern "C" fn string_from_utf16_lossy(
+ this: &mut MaybeUninit<String>,
+ ptr: *const u16,
+ len: usize,
+) {
+ let slice = unsafe { slice::from_raw_parts(ptr, len) };
+ let owned = String::from_utf16_lossy(slice);
+ let this = this.as_mut_ptr();
+ unsafe { ptr::write(this, owned) }
+}
+
#[export_name = "cxxbridge1$string$drop"]
unsafe extern "C" fn string_drop(this: &mut ManuallyDrop<String>) {
unsafe { ManuallyDrop::drop(this) }
diff --git a/src/symbols/rust_vec.rs b/src/symbols/rust_vec.rs
index 6f2dab9d..89c7da44 100644
--- a/src/symbols/rust_vec.rs
+++ b/src/symbols/rust_vec.rs
@@ -1,9 +1,11 @@
+#![cfg(feature = "alloc")]
+
+use crate::c_char::c_char;
use crate::rust_string::RustString;
use crate::rust_vec::RustVec;
use alloc::vec::Vec;
use core::mem;
use core::ptr;
-use std::os::raw::c_char;
macro_rules! rust_vec_shims {
($segment:expr, $ty:ty) => {
@@ -54,6 +56,12 @@ macro_rules! rust_vec_shims {
unsafe { (*this).set_len(len) }
}
}
+ attr! {
+ #[export_name = concat!("cxxbridge1$rust_vec$", $segment, "$truncate")]
+ unsafe extern "C" fn __truncate(this: *mut RustVec<$ty>, len: usize) {
+ unsafe { (*this).truncate(len) }
+ }
+ }
};
};
}
diff --git a/src/unique_ptr.rs b/src/unique_ptr.rs
index 63a1ca78..33992059 100644
--- a/src/unique_ptr.rs
+++ b/src/unique_ptr.rs
@@ -112,6 +112,10 @@ where
unsafe impl<T> Send for UniquePtr<T> where T: Send + UniquePtrTarget {}
unsafe impl<T> Sync for UniquePtr<T> where T: Sync + UniquePtrTarget {}
+// UniquePtr is not a self-referential type and is safe to move out of a Pin,
+// regardless whether the pointer's target is Unpin.
+impl<T> Unpin for UniquePtr<T> where T: UniquePtrTarget {}
+
impl<T> Drop for UniquePtr<T>
where
T: UniquePtrTarget,
@@ -241,11 +245,9 @@ extern "C" {
}
unsafe impl UniquePtrTarget for CxxString {
- #[doc(hidden)]
fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("CxxString")
}
- #[doc(hidden)]
fn __null() -> MaybeUninit<*mut c_void> {
let mut repr = MaybeUninit::uninit();
unsafe {
@@ -253,21 +255,17 @@ unsafe impl UniquePtrTarget for CxxString {
}
repr
}
- #[doc(hidden)]
unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
let mut repr = MaybeUninit::uninit();
unsafe { unique_ptr_std_string_raw(&mut repr, raw) }
repr
}
- #[doc(hidden)]
unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
unsafe { unique_ptr_std_string_get(&repr) }
}
- #[doc(hidden)]
unsafe fn __release(mut repr: MaybeUninit<*mut c_void>) -> *mut Self {
unsafe { unique_ptr_std_string_release(&mut repr) }
}
- #[doc(hidden)]
unsafe fn __drop(mut repr: MaybeUninit<*mut c_void>) {
unsafe { unique_ptr_std_string_drop(&mut repr) }
}
@@ -277,27 +275,21 @@ unsafe impl<T> UniquePtrTarget for CxxVector<T>
where
T: VectorElement,
{
- #[doc(hidden)]
fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "CxxVector<{}>", display(T::__typename))
}
- #[doc(hidden)]
fn __null() -> MaybeUninit<*mut c_void> {
T::__unique_ptr_null()
}
- #[doc(hidden)]
unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
unsafe { T::__unique_ptr_raw(raw) }
}
- #[doc(hidden)]
unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
unsafe { T::__unique_ptr_get(repr) }
}
- #[doc(hidden)]
unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self {
unsafe { T::__unique_ptr_release(repr) }
}
- #[doc(hidden)]
unsafe fn __drop(repr: MaybeUninit<*mut c_void>) {
unsafe { T::__unique_ptr_drop(repr) }
}
diff --git a/src/unwind.rs b/src/unwind.rs
index 4967a219..18852da7 100644
--- a/src/unwind.rs
+++ b/src/unwind.rs
@@ -1,26 +1,39 @@
#![allow(missing_docs)]
-use std::io::{self, Write};
-use std::panic::{self, AssertUnwindSafe};
-use std::process;
+use core::mem;
-pub fn catch_unwind<F, R>(label: &'static str, foreign_call: F) -> R
+pub fn prevent_unwind<F, R>(label: &'static str, foreign_call: F) -> R
where
F: FnOnce() -> R,
{
- // Regarding the AssertUnwindSafe: we immediately abort on panic so it
- // doesn't matter whether the types involved are unwind-safe. The UnwindSafe
- // bound on catch_unwind is about ensuring nothing is in a broken state if
- // your program plans to continue after the panic.
- match panic::catch_unwind(AssertUnwindSafe(foreign_call)) {
- Ok(ret) => ret,
- Err(_) => abort(label),
- }
+ // Goal is to make it impossible to propagate a panic across the C interface
+ // of an extern "Rust" function, which would be Undefined Behavior. We
+ // transform such panicks into a deterministic abort instead. When cxx is
+ // built in an application using panic=abort, this guard object is compiled
+ // out because its destructor is statically unreachable. When built with
+ // panic=unwind, an unwind from the foreign call will attempt to drop the
+ // guard object leading to a double panic, which is defined by Rust to
+ // abort. In no_std programs, on most platforms the current mechanism for
+ // this is for core::intrinsics::abort to invoke an invalid instruction. On
+ // Unix, the process will probably terminate with a signal like SIGABRT,
+ // SIGILL, SIGTRAP, SIGSEGV or SIGBUS. The precise behaviour is not
+ // guaranteed and not stable, but is safe.
+ let guard = Guard { label };
+
+ let ret = foreign_call();
+
+ // If we made it here, no uncaught panic occurred during the foreign call.
+ mem::forget(guard);
+ ret
}
-#[cold]
-fn abort(label: &'static str) -> ! {
- let mut stderr = io::stderr();
- let _ = writeln!(stderr, "Error: panic in ffi function {}, aborting.", label);
- process::abort();
+struct Guard {
+ label: &'static str,
+}
+
+impl Drop for Guard {
+ #[cold]
+ fn drop(&mut self) {
+ panic!("panic in ffi function {}, aborting.", self.label);
+ }
}
diff --git a/src/weak_ptr.rs b/src/weak_ptr.rs
index 8a9f1a68..e9320f37 100644
--- a/src/weak_ptr.rs
+++ b/src/weak_ptr.rs
@@ -114,11 +114,9 @@ pub unsafe trait WeakPtrTarget {
macro_rules! impl_weak_ptr_target {
($segment:expr, $name:expr, $ty:ty) => {
unsafe impl WeakPtrTarget for $ty {
- #[doc(hidden)]
fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
f.write_str($name)
}
- #[doc(hidden)]
unsafe fn __null(new: *mut c_void) {
extern "C" {
attr! {
@@ -128,7 +126,6 @@ macro_rules! impl_weak_ptr_target {
}
unsafe { __null(new) }
}
- #[doc(hidden)]
unsafe fn __clone(this: *const c_void, new: *mut c_void) {
extern "C" {
attr! {
@@ -138,7 +135,6 @@ macro_rules! impl_weak_ptr_target {
}
unsafe { __clone(this, new) }
}
- #[doc(hidden)]
unsafe fn __downgrade(shared: *const c_void, weak: *mut c_void) {
extern "C" {
attr! {
@@ -148,7 +144,6 @@ macro_rules! impl_weak_ptr_target {
}
unsafe { __downgrade(shared, weak) }
}
- #[doc(hidden)]
unsafe fn __upgrade(weak: *const c_void, shared: *mut c_void) {
extern "C" {
attr! {
@@ -158,7 +153,6 @@ macro_rules! impl_weak_ptr_target {
}
unsafe { __upgrade(weak, shared) }
}
- #[doc(hidden)]
unsafe fn __drop(this: *mut c_void) {
extern "C" {
attr! {
diff --git a/syntax/attrs.rs b/syntax/attrs.rs
index fa6c8097..46d010e0 100644
--- a/syntax/attrs.rs
+++ b/syntax/attrs.rs
@@ -1,11 +1,12 @@
+use crate::syntax::cfg::CfgExpr;
use crate::syntax::namespace::Namespace;
use crate::syntax::report::Errors;
use crate::syntax::Atom::{self, *};
-use crate::syntax::{Derive, Doc, ForeignName};
+use crate::syntax::{cfg, Derive, Doc, ForeignName};
use proc_macro2::{Ident, TokenStream};
use quote::ToTokens;
use syn::parse::{Nothing, Parse, ParseStream, Parser as _};
-use syn::{Attribute, Error, LitStr, Path, Result, Token};
+use syn::{parenthesized, token, Attribute, Error, LitStr, Path, Result, Token};
// Intended usage:
//
@@ -27,6 +28,7 @@ use syn::{Attribute, Error, LitStr, Path, Result, Token};
//
#[derive(Default)]
pub struct Parser<'a> {
+ pub cfg: Option<&'a mut CfgExpr>,
pub doc: Option<&'a mut Doc>,
pub derives: Option<&'a mut Vec<Derive>>,
pub repr: Option<&'a mut Option<Atom>>,
@@ -34,6 +36,7 @@ pub struct Parser<'a> {
pub cxx_name: Option<&'a mut Option<ForeignName>>,
pub rust_name: Option<&'a mut Option<Ident>>,
pub variants_from_header: Option<&'a mut Option<Attribute>>,
+ pub ignore_unrecognized: bool,
// Suppress clippy needless_update lint ("struct update has no effect, all
// the fields in the struct have already been specified") when preemptively
@@ -46,9 +49,12 @@ pub fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser) -> Othe
for attr in attrs {
if attr.path.is_ident("doc") {
match parse_doc_attribute.parse2(attr.tokens.clone()) {
- Ok(lit) => {
+ Ok(attr) => {
if let Some(doc) = &mut parser.doc {
- doc.push(lit);
+ match attr {
+ DocAttribute::Doc(lit) => doc.push(lit),
+ DocAttribute::Hidden => doc.hidden = true,
+ }
continue;
}
}
@@ -122,7 +128,23 @@ pub fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser) -> Othe
break;
}
}
- } else if attr.path.is_ident("variants_from_header") && cfg!(feature = "experimental") {
+ } else if attr.path.is_ident("cfg") {
+ match cfg::parse_attribute.parse2(attr.tokens.clone()) {
+ Ok(cfg_expr) => {
+ if let Some(cfg) = &mut parser.cfg {
+ cfg.merge(cfg_expr);
+ passthrough_attrs.push(attr);
+ continue;
+ }
+ }
+ Err(err) => {
+ cx.push(err);
+ break;
+ }
+ }
+ } else if attr.path.is_ident("variants_from_header")
+ && cfg!(feature = "experimental-enum-variants-from-header")
+ {
if let Err(err) = Nothing::parse.parse2(attr.tokens.clone()) {
cx.push(err);
}
@@ -140,6 +162,9 @@ pub fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser) -> Othe
// https://doc.rust-lang.org/reference/attributes/diagnostics.html
passthrough_attrs.push(attr);
continue;
+ } else if attr.path.is_ident("serde") {
+ passthrough_attrs.push(attr);
+ continue;
} else if attr.path.segments.len() > 1 {
let tool = &attr.path.segments.first().unwrap().ident;
if tool == "rustfmt" {
@@ -150,16 +175,37 @@ pub fn parse(cx: &mut Errors, attrs: Vec<Attribute>, mut parser: Parser) -> Othe
continue;
}
}
- cx.error(attr, "unsupported attribute");
- break;
+ if !parser.ignore_unrecognized {
+ cx.error(attr, "unsupported attribute");
+ break;
+ }
}
OtherAttrs(passthrough_attrs)
}
-fn parse_doc_attribute(input: ParseStream) -> Result<LitStr> {
- input.parse::<Token![=]>()?;
- let lit: LitStr = input.parse()?;
- Ok(lit)
+enum DocAttribute {
+ Doc(LitStr),
+ Hidden,
+}
+
+mod kw {
+ syn::custom_keyword!(hidden);
+}
+
+fn parse_doc_attribute(input: ParseStream) -> Result<DocAttribute> {
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Token![=]) {
+ input.parse::<Token![=]>()?;
+ let lit: LitStr = input.parse()?;
+ Ok(DocAttribute::Doc(lit))
+ } else if lookahead.peek(token::Paren) {
+ let content;
+ parenthesized!(content in input);
+ content.parse::<kw::hidden>()?;
+ Ok(DocAttribute::Hidden)
+ } else {
+ Err(lookahead.error())
+ }
}
fn parse_derive_attribute(cx: &mut Errors, input: ParseStream) -> Result<Vec<Derive>> {
@@ -222,12 +268,17 @@ fn parse_rust_name_attribute(input: ParseStream) -> Result<Ident> {
}
}
+#[derive(Clone)]
pub struct OtherAttrs(Vec<Attribute>);
impl OtherAttrs {
pub fn none() -> Self {
OtherAttrs(Vec::new())
}
+
+ pub fn extend(&mut self, other: Self) {
+ self.0.extend(other.0);
+ }
}
impl ToTokens for OtherAttrs {
diff --git a/syntax/cfg.rs b/syntax/cfg.rs
new file mode 100644
index 00000000..d486b995
--- /dev/null
+++ b/syntax/cfg.rs
@@ -0,0 +1,77 @@
+use proc_macro2::Ident;
+use std::mem;
+use syn::parse::{Error, ParseStream, Result};
+use syn::{parenthesized, token, LitStr, Token};
+
+#[derive(Clone)]
+pub enum CfgExpr {
+ Unconditional,
+ Eq(Ident, Option<LitStr>),
+ All(Vec<CfgExpr>),
+ Any(Vec<CfgExpr>),
+ Not(Box<CfgExpr>),
+}
+
+impl CfgExpr {
+ pub fn merge(&mut self, expr: CfgExpr) {
+ if let CfgExpr::Unconditional = self {
+ *self = expr;
+ } else if let CfgExpr::All(list) = self {
+ list.push(expr);
+ } else {
+ let prev = mem::replace(self, CfgExpr::Unconditional);
+ *self = CfgExpr::All(vec![prev, expr]);
+ }
+ }
+}
+
+pub fn parse_attribute(input: ParseStream) -> Result<CfgExpr> {
+ let content;
+ parenthesized!(content in input);
+ let cfg_expr = content.call(parse_single)?;
+ content.parse::<Option<Token![,]>>()?;
+ Ok(cfg_expr)
+}
+
+fn parse_single(input: ParseStream) -> Result<CfgExpr> {
+ let ident: Ident = input.parse()?;
+ let lookahead = input.lookahead1();
+ if input.peek(token::Paren) {
+ let content;
+ parenthesized!(content in input);
+ if ident == "all" {
+ let list = content.call(parse_multiple)?;
+ Ok(CfgExpr::All(list))
+ } else if ident == "any" {
+ let list = content.call(parse_multiple)?;
+ Ok(CfgExpr::Any(list))
+ } else if ident == "not" {
+ let expr = content.call(parse_single)?;
+ content.parse::<Option<Token![,]>>()?;
+ Ok(CfgExpr::Not(Box::new(expr)))
+ } else {
+ Err(Error::new(ident.span(), "unrecognized cfg expression"))
+ }
+ } else if lookahead.peek(Token![=]) {
+ input.parse::<Token![=]>()?;
+ let string: LitStr = input.parse()?;
+ Ok(CfgExpr::Eq(ident, Some(string)))
+ } else if lookahead.peek(Token![,]) || input.is_empty() {
+ Ok(CfgExpr::Eq(ident, None))
+ } else {
+ Err(lookahead.error())
+ }
+}
+
+fn parse_multiple(input: ParseStream) -> Result<Vec<CfgExpr>> {
+ let mut vec = Vec::new();
+ while !input.is_empty() {
+ let expr = input.call(parse_single)?;
+ vec.push(expr);
+ if input.is_empty() {
+ break;
+ }
+ input.parse::<Token![,]>()?;
+ }
+ Ok(vec)
+}
diff --git a/syntax/check.rs b/syntax/check.rs
index 698782f9..b203ca1f 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -123,10 +123,9 @@ fn check_type_rust_vec(cx: &mut Check, ty: &Ty1) {
}
match Atom::from(&ident.rust) {
- None | Some(Char) | Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(Usize)
- | Some(I8) | Some(I16) | Some(I32) | Some(I64) | Some(Isize) | Some(F32)
- | Some(F64) | Some(RustString) => return,
- Some(Bool) => { /* todo */ }
+ None | Some(Bool) | Some(Char) | Some(U8) | Some(U16) | Some(U32) | Some(U64)
+ | Some(Usize) | Some(I8) | Some(I16) | Some(I32) | Some(I64) | Some(Isize)
+ | Some(F32) | Some(F64) | Some(RustString) => return,
Some(CxxString) => {}
}
}
diff --git a/syntax/derive.rs b/syntax/derive.rs
index 96b3eea7..7727fbc9 100644
--- a/syntax/derive.rs
+++ b/syntax/derive.rs
@@ -19,6 +19,8 @@ pub enum Trait {
Ord,
PartialEq,
PartialOrd,
+ Serialize,
+ Deserialize,
}
impl Derive {
@@ -34,6 +36,8 @@ impl Derive {
"Ord" => Trait::Ord,
"PartialEq" => Trait::PartialEq,
"PartialOrd" => Trait::PartialOrd,
+ "Serialize" => Trait::Serialize,
+ "Deserialize" => Trait::Deserialize,
_ => return None,
};
let span = ident.span();
@@ -60,6 +64,8 @@ impl AsRef<str> for Trait {
Trait::Ord => "Ord",
Trait::PartialEq => "PartialEq",
Trait::PartialOrd => "PartialOrd",
+ Trait::Serialize => "Serialize",
+ Trait::Deserialize => "Deserialize",
}
}
}
diff --git a/syntax/discriminant.rs b/syntax/discriminant.rs
index fff8f758..21a6d00a 100644
--- a/syntax/discriminant.rs
+++ b/syntax/discriminant.rs
@@ -180,6 +180,7 @@ impl Discriminant {
}
}
+ #[cfg(feature = "experimental-enum-variants-from-header")]
pub const fn checked_succ(self) -> Option<Self> {
match self.sign {
Sign::Negative => {
diff --git a/syntax/doc.rs b/syntax/doc.rs
index cd764fac..5de824f3 100644
--- a/syntax/doc.rs
+++ b/syntax/doc.rs
@@ -3,12 +3,14 @@ use quote::{quote, ToTokens};
use syn::LitStr;
pub struct Doc {
+ pub(crate) hidden: bool,
fragments: Vec<LitStr>,
}
impl Doc {
pub fn new() -> Self {
Doc {
+ hidden: false,
fragments: Vec::new(),
}
}
@@ -17,10 +19,12 @@ impl Doc {
self.fragments.push(lit);
}
+ #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
pub fn is_empty(&self) -> bool {
self.fragments.is_empty()
}
+ #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
pub fn to_string(&self) -> String {
let mut doc = String::new();
for lit in &self.fragments {
@@ -34,8 +38,9 @@ impl Doc {
impl ToTokens for Doc {
fn to_tokens(&self, tokens: &mut TokenStream) {
let fragments = &self.fragments;
- tokens.extend(quote! {
- #(#[doc = #fragments])*
- });
+ tokens.extend(quote! { #(#[doc = #fragments])* });
+ if self.hidden {
+ tokens.extend(quote! { #[doc(hidden)] });
+ }
}
}
diff --git a/syntax/file.rs b/syntax/file.rs
index 99466b8e..71f11eec 100644
--- a/syntax/file.rs
+++ b/syntax/file.rs
@@ -1,3 +1,4 @@
+use crate::syntax::cfg::CfgExpr;
use crate::syntax::namespace::Namespace;
use quote::quote;
use syn::parse::{Error, Parse, ParseStream, Result};
@@ -7,6 +8,7 @@ use syn::{
};
pub struct Module {
+ pub cfg: CfgExpr,
pub namespace: Namespace,
pub attrs: Vec<Attribute>,
pub vis: Visibility,
@@ -36,6 +38,7 @@ pub struct ItemForeignMod {
impl Parse for Module {
fn parse(input: ParseStream) -> Result<Self> {
+ let cfg = CfgExpr::Unconditional;
let namespace = Namespace::ROOT;
let mut attrs = input.call(Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
@@ -62,6 +65,7 @@ impl Parse for Module {
}
Ok(Module {
+ cfg,
namespace,
attrs,
vis,
diff --git a/syntax/impls.rs b/syntax/impls.rs
index 06d68dc2..36e1f322 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -8,12 +8,14 @@ use std::ops::{Deref, DerefMut};
impl PartialEq for Include {
fn eq(&self, other: &Self) -> bool {
let Include {
+ cfg: _,
path,
kind,
begin_span: _,
end_span: _,
} = self;
let Include {
+ cfg: _,
path: path2,
kind: kind2,
begin_span: _,
@@ -307,6 +309,7 @@ impl Eq for Signature {}
impl PartialEq for Signature {
fn eq(&self, other: &Self) -> bool {
let Signature {
+ asyncness,
unsafety,
fn_token: _,
generics: _,
@@ -318,6 +321,7 @@ impl PartialEq for Signature {
throws_tokens: _,
} = self;
let Signature {
+ asyncness: asyncness2,
unsafety: unsafety2,
fn_token: _,
generics: _,
@@ -328,13 +332,15 @@ impl PartialEq for Signature {
paren_token: _,
throws_tokens: _,
} = other;
- unsafety.is_some() == unsafety2.is_some()
+ asyncness.is_some() == asyncness2.is_some()
+ && unsafety.is_some() == unsafety2.is_some()
&& receiver == receiver2
&& ret == ret2
&& throws == throws2
&& args.len() == args2.len()
&& args.iter().zip(args2).all(|(arg, arg2)| {
let Var {
+ cfg: _,
doc: _,
attrs: _,
visibility: _,
@@ -343,6 +349,7 @@ impl PartialEq for Signature {
ty,
} = arg;
let Var {
+ cfg: _,
doc: _,
attrs: _,
visibility: _,
@@ -358,6 +365,7 @@ impl PartialEq for Signature {
impl Hash for Signature {
fn hash<H: Hasher>(&self, state: &mut H) {
let Signature {
+ asyncness,
unsafety,
fn_token: _,
generics: _,
@@ -368,10 +376,12 @@ impl Hash for Signature {
paren_token: _,
throws_tokens: _,
} = self;
+ asyncness.is_some().hash(state);
unsafety.is_some().hash(state);
receiver.hash(state);
for arg in args {
let Var {
+ cfg: _,
doc: _,
attrs: _,
visibility: _,
diff --git a/syntax/map.rs b/syntax/map.rs
index 4873409d..526b793b 100644
--- a/syntax/map.rs
+++ b/syntax/map.rs
@@ -124,6 +124,7 @@ mod unordered {
self.0.entry(key)
}
+ #[allow(dead_code)] // only used by cxx-build, not cxxbridge-macro
pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q>,
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 1d986345..4f19d964 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -2,6 +2,7 @@
pub mod atom;
pub mod attrs;
+pub mod cfg;
pub mod check;
pub mod derive;
mod discriminant;
@@ -30,13 +31,14 @@ pub mod types;
mod visit;
use self::attrs::OtherAttrs;
+use self::cfg::CfgExpr;
use self::namespace::Namespace;
use self::parse::kw;
use self::symbol::Symbol;
use proc_macro2::{Ident, Span};
use syn::punctuated::Punctuated;
use syn::token::{Brace, Bracket, Paren};
-use syn::{Attribute, Expr, Generics, Lifetime, LitInt, Path, Token, Type as RustType};
+use syn::{Attribute, Expr, Generics, Lifetime, LitInt, Token, Type as RustType};
pub use self::atom::Atom;
pub use self::derive::{Derive, Trait};
@@ -59,6 +61,7 @@ pub enum Api {
}
pub struct Include {
+ pub cfg: CfgExpr,
pub path: String,
pub kind: IncludeKind,
pub begin_span: Span,
@@ -75,6 +78,7 @@ pub enum IncludeKind {
}
pub struct ExternType {
+ pub cfg: CfgExpr,
pub lang: Lang,
pub doc: Doc,
pub derives: Vec<Derive>,
@@ -90,6 +94,7 @@ pub struct ExternType {
}
pub struct Struct {
+ pub cfg: CfgExpr,
pub doc: Doc,
pub derives: Vec<Derive>,
pub attrs: OtherAttrs,
@@ -102,6 +107,7 @@ pub struct Struct {
}
pub struct Enum {
+ pub cfg: CfgExpr,
pub doc: Doc,
pub derives: Vec<Derive>,
pub attrs: OtherAttrs,
@@ -118,11 +124,18 @@ pub struct Enum {
}
pub enum EnumRepr {
- Native { atom: Atom, repr_type: Type },
- Foreign { rust_type: Path },
+ Native {
+ atom: Atom,
+ repr_type: Type,
+ },
+ #[cfg(feature = "experimental-enum-variants-from-header")]
+ Foreign {
+ rust_type: syn::Path,
+ },
}
pub struct ExternFn {
+ pub cfg: CfgExpr,
pub lang: Lang,
pub doc: Doc,
pub attrs: OtherAttrs,
@@ -134,6 +147,7 @@ pub struct ExternFn {
}
pub struct TypeAlias {
+ pub cfg: CfgExpr,
pub doc: Doc,
pub derives: Vec<Derive>,
pub attrs: OtherAttrs,
@@ -147,6 +161,7 @@ pub struct TypeAlias {
}
pub struct Impl {
+ pub cfg: CfgExpr,
pub impl_token: Token![impl],
pub impl_generics: Lifetimes,
pub negative: bool,
@@ -164,6 +179,7 @@ pub struct Lifetimes {
}
pub struct Signature {
+ pub asyncness: Option<Token![async]>,
pub unsafety: Option<Token![unsafe]>,
pub fn_token: Token![fn],
pub generics: Generics,
@@ -176,6 +192,7 @@ pub struct Signature {
}
pub struct Var {
+ pub cfg: CfgExpr,
pub doc: Doc,
pub attrs: OtherAttrs,
pub visibility: Token![pub],
@@ -198,6 +215,7 @@ pub struct Receiver {
}
pub struct Variant {
+ pub cfg: CfgExpr,
pub doc: Doc,
pub attrs: OtherAttrs,
pub name: Pair,
diff --git a/syntax/names.rs b/syntax/names.rs
index 7a125ae7..8b93ac5c 100644
--- a/syntax/names.rs
+++ b/syntax/names.rs
@@ -20,17 +20,6 @@ impl Pair {
.chain(iter::once(&self.cxx as &dyn Segment));
Symbol::from_idents(segments)
}
-
- pub fn to_fully_qualified(&self) -> String {
- let mut fully_qualified = String::new();
- for segment in &self.namespace {
- fully_qualified += "::";
- fully_qualified += &segment.to_string();
- }
- fully_qualified += "::";
- fully_qualified += &self.cxx.to_string();
- fully_qualified
- }
}
impl NamedType {
diff --git a/syntax/parse.rs b/syntax/parse.rs
index 32d36eb3..1754c600 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -1,4 +1,5 @@
use crate::syntax::attrs::OtherAttrs;
+use crate::syntax::cfg::CfgExpr;
use crate::syntax::discriminant::DiscriminantSet;
use crate::syntax::file::{Item, ItemForeignMod};
use crate::syntax::report::Errors;
@@ -43,7 +44,7 @@ pub fn parse_items(
Item::ForeignMod(foreign_mod) => {
parse_foreign_mod(cx, foreign_mod, &mut apis, trusted, namespace)
}
- Item::Impl(item) => match parse_impl(item) {
+ Item::Impl(item) => match parse_impl(cx, item) {
Ok(imp) => apis.push(imp),
Err(err) => cx.push(err),
},
@@ -55,6 +56,7 @@ pub fn parse_items(
}
fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) -> Result<Api> {
+ let mut cfg = CfgExpr::Unconditional;
let mut doc = Doc::new();
let mut derives = Vec::new();
let mut namespace = namespace.clone();
@@ -64,6 +66,7 @@ fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) ->
cx,
mem::take(&mut item.attrs),
attrs::Parser {
+ cfg: Some(&mut cfg),
doc: Some(&mut doc),
derives: Some(&mut derives),
namespace: Some(&mut namespace),
@@ -124,6 +127,7 @@ fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) ->
let mut fields = Vec::new();
for field in named_fields.named {
let ident = field.ident.unwrap();
+ let mut cfg = CfgExpr::Unconditional;
let mut doc = Doc::new();
let mut cxx_name = None;
let mut rust_name = None;
@@ -131,6 +135,7 @@ fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) ->
cx,
field.attrs,
attrs::Parser {
+ cfg: Some(&mut cfg),
doc: Some(&mut doc),
cxx_name: Some(&mut cxx_name),
rust_name: Some(&mut rust_name),
@@ -148,6 +153,7 @@ fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) ->
let name = pair(Namespace::default(), &ident, cxx_name, rust_name);
let colon_token = field.colon_token.unwrap();
fields.push(Var {
+ cfg,
doc,
attrs,
visibility,
@@ -168,6 +174,7 @@ fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) ->
let brace_token = named_fields.brace_token;
Ok(Api::Struct(Struct {
+ cfg,
doc,
derives,
attrs,
@@ -181,6 +188,7 @@ fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) ->
}
fn parse_enum(cx: &mut Errors, item: ItemEnum, namespace: &Namespace) -> Api {
+ let mut cfg = CfgExpr::Unconditional;
let mut doc = Doc::new();
let mut derives = Vec::new();
let mut repr = None;
@@ -192,6 +200,7 @@ fn parse_enum(cx: &mut Errors, item: ItemEnum, namespace: &Namespace) -> Api {
cx,
item.attrs,
attrs::Parser {
+ cfg: Some(&mut cfg),
doc: Some(&mut doc),
derives: Some(&mut derives),
repr: Some(&mut repr),
@@ -254,6 +263,7 @@ fn parse_enum(cx: &mut Errors, item: ItemEnum, namespace: &Namespace) -> Api {
let variants_from_header = variants_from_header_attr.is_some();
Api::Enum(Enum {
+ cfg,
doc,
derives,
attrs,
@@ -275,6 +285,7 @@ fn parse_variant(
mut variant: RustVariant,
discriminants: &mut DiscriminantSet,
) -> Result<Variant> {
+ let mut cfg = CfgExpr::Unconditional;
let mut doc = Doc::new();
let mut cxx_name = None;
let mut rust_name = None;
@@ -282,6 +293,7 @@ fn parse_variant(
cx,
mem::take(&mut variant.attrs),
attrs::Parser {
+ cfg: Some(&mut cfg),
doc: Some(&mut doc),
cxx_name: Some(&mut cxx_name),
rust_name: Some(&mut rust_name),
@@ -311,6 +323,7 @@ fn parse_variant(
let expr = variant.discriminant.map(|(_, expr)| expr);
Ok(Variant {
+ cfg,
doc,
attrs,
name,
@@ -345,11 +358,13 @@ fn parse_foreign_mod(
let trusted = trusted || foreign_mod.unsafety.is_some();
+ let mut cfg = CfgExpr::Unconditional;
let mut namespace = namespace.clone();
- attrs::parse(
+ let attrs = attrs::parse(
cx,
foreign_mod.attrs,
attrs::Parser {
+ cfg: Some(&mut cfg),
namespace: Some(&mut namespace),
..Default::default()
},
@@ -359,23 +374,26 @@ fn parse_foreign_mod(
for foreign in foreign_mod.items {
match foreign {
ForeignItem::Type(foreign) => {
- let ety = parse_extern_type(cx, foreign, lang, trusted, &namespace);
+ let ety = parse_extern_type(cx, foreign, lang, trusted, &cfg, &namespace, &attrs);
items.push(ety);
}
ForeignItem::Fn(foreign) => {
- match parse_extern_fn(cx, foreign, lang, trusted, &namespace) {
+ match parse_extern_fn(cx, foreign, lang, trusted, &cfg, &namespace, &attrs) {
Ok(efn) => items.push(efn),
Err(err) => cx.push(err),
}
}
ForeignItem::Macro(foreign) if foreign.mac.path.is_ident("include") => {
match foreign.mac.parse_body_with(parse_include) {
- Ok(include) => items.push(Api::Include(include)),
+ Ok(mut include) => {
+ include.cfg = cfg.clone();
+ items.push(Api::Include(include));
+ }
Err(err) => cx.push(err),
}
}
ForeignItem::Verbatim(tokens) => {
- match parse_extern_verbatim(cx, tokens, lang, trusted, &namespace) {
+ match parse_extern_verbatim(cx, tokens, lang, trusted, &cfg, &namespace, &attrs) {
Ok(api) => items.push(api),
Err(err) => cx.push(err),
}
@@ -443,17 +461,22 @@ fn parse_extern_type(
foreign_type: ForeignItemType,
lang: Lang,
trusted: bool,
+ extern_block_cfg: &CfgExpr,
namespace: &Namespace,
+ attrs: &OtherAttrs,
) -> Api {
+ let mut cfg = extern_block_cfg.clone();
let mut doc = Doc::new();
let mut derives = Vec::new();
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
- let attrs = attrs::parse(
+ let mut attrs = attrs.clone();
+ attrs.extend(attrs::parse(
cx,
foreign_type.attrs,
attrs::Parser {
+ cfg: Some(&mut cfg),
doc: Some(&mut doc),
derives: Some(&mut derives),
namespace: Some(&mut namespace),
@@ -461,7 +484,7 @@ fn parse_extern_type(
rust_name: Some(&mut rust_name),
..Default::default()
},
- );
+ ));
let type_token = foreign_type.type_token;
let visibility = visibility_pub(&foreign_type.vis, type_token.span);
@@ -479,6 +502,7 @@ fn parse_extern_type(
Lang::Cxx => Api::CxxType,
Lang::Rust => Api::RustType,
})(ExternType {
+ cfg,
lang,
doc,
derives,
@@ -499,23 +523,28 @@ fn parse_extern_fn(
mut foreign_fn: ForeignItemFn,
lang: Lang,
trusted: bool,
+ extern_block_cfg: &CfgExpr,
namespace: &Namespace,
+ attrs: &OtherAttrs,
) -> Result<Api> {
+ let mut cfg = extern_block_cfg.clone();
let mut doc = Doc::new();
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
- let attrs = attrs::parse(
+ let mut attrs = attrs.clone();
+ attrs.extend(attrs::parse(
cx,
mem::take(&mut foreign_fn.attrs),
attrs::Parser {
+ cfg: Some(&mut cfg),
doc: Some(&mut doc),
namespace: Some(&mut namespace),
cxx_name: Some(&mut cxx_name),
rust_name: Some(&mut rust_name),
..Default::default()
},
- );
+ ));
let generics = &foreign_fn.sig.generics;
if generics.where_clause.is_some()
@@ -537,10 +566,13 @@ fn parse_extern_fn(
));
}
- if foreign_fn.sig.asyncness.is_some() {
+ if foreign_fn.sig.asyncness.is_some() && !cfg!(feature = "experimental-async-fn") {
return Err(Error::new_spanned(
foreign_fn,
- "async function is not directly supported yet, but see https://cxx.rs/async.html for a working approach",
+ "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",
));
}
@@ -591,12 +623,14 @@ fn parse_extern_fn(
};
let ty = parse_type(&arg.ty)?;
if ident != "self" {
+ let cfg = CfgExpr::Unconditional;
let doc = Doc::new();
let attrs = OtherAttrs::none();
let visibility = Token![pub](ident.span());
let name = pair(Namespace::default(), &ident, None, None);
let colon_token = arg.colon_token;
args.push_value(Var {
+ cfg,
doc,
attrs,
visibility,
@@ -634,6 +668,7 @@ fn parse_extern_fn(
let mut throws_tokens = None;
let ret = parse_return_type(&foreign_fn.sig.output, &mut throws_tokens)?;
let throws = throws_tokens.is_some();
+ let asyncness = foreign_fn.sig.asyncness;
let unsafety = foreign_fn.sig.unsafety;
let fn_token = foreign_fn.sig.fn_token;
let inherited_span = unsafety.map_or(fn_token.span, |unsafety| unsafety.span);
@@ -647,12 +682,14 @@ fn parse_extern_fn(
Lang::Cxx => Api::CxxFunction,
Lang::Rust => Api::RustFunction,
}(ExternFn {
+ cfg,
lang,
doc,
attrs,
visibility,
name,
sig: Signature {
+ asyncness,
unsafety,
fn_token,
generics,
@@ -673,13 +710,25 @@ fn parse_extern_verbatim(
tokens: TokenStream,
lang: Lang,
trusted: bool,
+ extern_block_cfg: &CfgExpr,
namespace: &Namespace,
+ attrs: &OtherAttrs,
) -> Result<Api> {
|input: ParseStream| -> Result<Api> {
- let attrs = input.call(Attribute::parse_outer)?;
+ let unparsed_attrs = input.call(Attribute::parse_outer)?;
let visibility: Visibility = input.parse()?;
if input.peek(Token![type]) {
- parse_extern_verbatim_type(cx, attrs, visibility, input, lang, trusted, namespace)
+ parse_extern_verbatim_type(
+ cx,
+ unparsed_attrs,
+ visibility,
+ input,
+ lang,
+ trusted,
+ extern_block_cfg,
+ namespace,
+ attrs,
+ )
} else if input.peek(Token![fn]) {
parse_extern_verbatim_fn(input)
} else {
@@ -695,12 +744,14 @@ fn parse_extern_verbatim(
fn parse_extern_verbatim_type(
cx: &mut Errors,
- attrs: Vec<Attribute>,
+ unparsed_attrs: Vec<Attribute>,
visibility: Visibility,
input: ParseStream,
lang: Lang,
trusted: bool,
+ extern_block_cfg: &CfgExpr,
namespace: &Namespace,
+ attrs: &OtherAttrs,
) -> Result<Api> {
let type_token: Token![type] = input.parse()?;
let ident: Ident = input.parse()?;
@@ -746,12 +797,33 @@ fn parse_extern_verbatim_type(
if lookahead.peek(Token![=]) {
// type Alias = crate::path::to::Type;
parse_type_alias(
- cx, attrs, visibility, type_token, ident, lifetimes, input, lang, namespace,
+ cx,
+ unparsed_attrs,
+ visibility,
+ type_token,
+ ident,
+ lifetimes,
+ input,
+ lang,
+ extern_block_cfg,
+ namespace,
+ attrs,
)
} else if lookahead.peek(Token![:]) || lookahead.peek(Token![;]) {
// type Opaque: Bound2 + Bound2;
parse_extern_type_bounded(
- cx, attrs, visibility, type_token, ident, lifetimes, input, lang, trusted, namespace,
+ cx,
+ unparsed_attrs,
+ visibility,
+ type_token,
+ ident,
+ lifetimes,
+ input,
+ lang,
+ trusted,
+ extern_block_cfg,
+ namespace,
+ attrs,
)
} else {
Err(lookahead.error())
@@ -766,28 +838,33 @@ fn parse_extern_verbatim_fn(input: ParseStream) -> Result<Api> {
fn parse_type_alias(
cx: &mut Errors,
- attrs: Vec<Attribute>,
+ unparsed_attrs: Vec<Attribute>,
visibility: Visibility,
type_token: Token![type],
ident: Ident,
generics: Lifetimes,
input: ParseStream,
lang: Lang,
+ extern_block_cfg: &CfgExpr,
namespace: &Namespace,
+ attrs: &OtherAttrs,
) -> Result<Api> {
let eq_token: Token![=] = input.parse()?;
let ty: RustType = input.parse()?;
let semi_token: Token![;] = input.parse()?;
+ let mut cfg = extern_block_cfg.clone();
let mut doc = Doc::new();
let mut derives = Vec::new();
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
- let attrs = attrs::parse(
+ let mut attrs = attrs.clone();
+ attrs.extend(attrs::parse(
cx,
- attrs,
+ unparsed_attrs,
attrs::Parser {
+ cfg: Some(&mut cfg),
doc: Some(&mut doc),
derives: Some(&mut derives),
namespace: Some(&mut namespace),
@@ -795,7 +872,7 @@ fn parse_type_alias(
rust_name: Some(&mut rust_name),
..Default::default()
},
- );
+ ));
if lang == Lang::Rust {
let span = quote!(#type_token #semi_token);
@@ -807,6 +884,7 @@ fn parse_type_alias(
let name = pair(namespace, &ident, cxx_name, rust_name);
Ok(Api::TypeAlias(TypeAlias {
+ cfg,
doc,
derives,
attrs,
@@ -822,7 +900,7 @@ fn parse_type_alias(
fn parse_extern_type_bounded(
cx: &mut Errors,
- attrs: Vec<Attribute>,
+ unparsed_attrs: Vec<Attribute>,
visibility: Visibility,
type_token: Token![type],
ident: Ident,
@@ -830,7 +908,9 @@ fn parse_extern_type_bounded(
input: ParseStream,
lang: Lang,
trusted: bool,
+ extern_block_cfg: &CfgExpr,
namespace: &Namespace,
+ attrs: &OtherAttrs,
) -> Result<Api> {
let mut bounds = Vec::new();
let colon_token: Option<Token![:]> = input.parse()?;
@@ -865,15 +945,18 @@ fn parse_extern_type_bounded(
}
let semi_token: Token![;] = input.parse()?;
+ let mut cfg = extern_block_cfg.clone();
let mut doc = Doc::new();
let mut derives = Vec::new();
let mut namespace = namespace.clone();
let mut cxx_name = None;
let mut rust_name = None;
- let attrs = attrs::parse(
+ let mut attrs = attrs.clone();
+ attrs.extend(attrs::parse(
cx,
- attrs,
+ unparsed_attrs,
attrs::Parser {
+ cfg: Some(&mut cfg),
doc: Some(&mut doc),
derives: Some(&mut derives),
namespace: Some(&mut namespace),
@@ -881,7 +964,7 @@ fn parse_extern_type_bounded(
rust_name: Some(&mut rust_name),
..Default::default()
},
- );
+ ));
let visibility = visibility_pub(&visibility, type_token.span);
let name = pair(namespace, &ident, cxx_name, rust_name);
@@ -890,6 +973,7 @@ fn parse_extern_type_bounded(
Lang::Cxx => Api::CxxType,
Lang::Rust => Api::RustType,
}(ExternType {
+ cfg,
lang,
doc,
derives,
@@ -905,9 +989,19 @@ fn parse_extern_type_bounded(
}))
}
-fn parse_impl(imp: ItemImpl) -> Result<Api> {
+fn parse_impl(cx: &mut Errors, imp: ItemImpl) -> Result<Api> {
let impl_token = imp.impl_token;
+ let mut cfg = CfgExpr::Unconditional;
+ attrs::parse(
+ cx,
+ imp.attrs,
+ attrs::Parser {
+ cfg: Some(&mut cfg),
+ ..Default::default()
+ },
+ );
+
if !imp.items.is_empty() {
let mut span = Group::new(Delimiter::Brace, TokenStream::new());
span.set_span(imp.brace_token.span);
@@ -993,6 +1087,7 @@ fn parse_impl(imp: ItemImpl) -> Result<Api> {
let brace_token = imp.brace_token;
Ok(Api::Impl(Impl {
+ cfg,
impl_token,
impl_generics,
negative,
@@ -1008,6 +1103,7 @@ fn parse_include(input: ParseStream) -> Result<Include> {
let lit: LitStr = input.parse()?;
let span = lit.span();
return Ok(Include {
+ cfg: CfgExpr::Unconditional,
path: lit.value(),
kind: IncludeKind::Quoted,
begin_span: span,
@@ -1037,6 +1133,7 @@ fn parse_include(input: ParseStream) -> Result<Include> {
let rangle: Token![>] = input.parse()?;
return Ok(Include {
+ cfg: CfgExpr::Unconditional,
path,
kind: IncludeKind::Bracketed,
begin_span: langle.span,
@@ -1297,11 +1394,13 @@ fn parse_type_fn(ty: &TypeBareFn) -> Result<Type> {
}
};
let ty = parse_type(&arg.ty)?;
+ let cfg = CfgExpr::Unconditional;
let doc = Doc::new();
let attrs = OtherAttrs::none();
let visibility = Token![pub](ident.span());
let name = pair(Namespace::default(), &ident, None, None);
Ok(Var {
+ cfg,
doc,
attrs,
visibility,
@@ -1316,6 +1415,7 @@ fn parse_type_fn(ty: &TypeBareFn) -> Result<Type> {
let ret = parse_return_type(&ty.output, &mut throws_tokens)?;
let throws = throws_tokens.is_some();
+ let asyncness = None;
let unsafety = ty.unsafety;
let fn_token = ty.fn_token;
let generics = Generics::default();
@@ -1323,6 +1423,7 @@ fn parse_type_fn(ty: &TypeBareFn) -> Result<Type> {
let paren_token = ty.paren_token;
Ok(Type::Fn(Box::new(Signature {
+ asyncness,
unsafety,
fn_token,
generics,
diff --git a/syntax/qualified.rs b/syntax/qualified.rs
index 96f07c19..5f182fa9 100644
--- a/syntax/qualified.rs
+++ b/syntax/qualified.rs
@@ -1,5 +1,5 @@
use syn::ext::IdentExt;
-use syn::parse::{ParseStream, Result};
+use syn::parse::{Error, ParseStream, Result};
use syn::{Ident, LitStr, Token};
pub struct QualifiedName {
@@ -8,21 +8,8 @@ pub struct QualifiedName {
impl QualifiedName {
pub fn parse_unquoted(input: ParseStream) -> Result<Self> {
- let mut segments = Vec::new();
- let mut trailing_punct = true;
- let leading_colons: Option<Token![::]> = input.parse()?;
- while trailing_punct && input.peek(Ident::peek_any) {
- let ident = Ident::parse_any(input)?;
- segments.push(ident);
- let colons: Option<Token![::]> = input.parse()?;
- trailing_punct = colons.is_some();
- }
- if segments.is_empty() && leading_colons.is_none() {
- return Err(input.error("expected path"));
- } else if trailing_punct {
- return Err(input.error("expected path segment"));
- }
- Ok(QualifiedName { segments })
+ let allow_raw = true;
+ parse_unquoted(input, allow_raw)
}
pub fn parse_quoted_or_unquoted(input: ParseStream) -> Result<Self> {
@@ -32,10 +19,41 @@ impl QualifiedName {
let segments = Vec::new();
Ok(QualifiedName { segments })
} else {
- lit.parse_with(Self::parse_unquoted)
+ lit.parse_with(|input: ParseStream| {
+ let allow_raw = false;
+ parse_unquoted(input, allow_raw)
+ })
}
} else {
Self::parse_unquoted(input)
}
}
}
+
+fn parse_unquoted(input: ParseStream, allow_raw: bool) -> Result<QualifiedName> {
+ let mut segments = Vec::new();
+ let mut trailing_punct = true;
+ let leading_colons: Option<Token![::]> = input.parse()?;
+ while trailing_punct && input.peek(Ident::peek_any) {
+ let mut ident = Ident::parse_any(input)?;
+ if let Some(unraw) = ident.to_string().strip_prefix("r#") {
+ if !allow_raw {
+ let msg = format!(
+ "raw identifier `{}` is not allowed in a quoted namespace; use `{}`, or remove quotes",
+ ident, unraw,
+ );
+ return Err(Error::new(ident.span(), msg));
+ }
+ ident = Ident::new(unraw, ident.span());
+ }
+ segments.push(ident);
+ let colons: Option<Token![::]> = input.parse()?;
+ trailing_punct = colons.is_some();
+ }
+ if segments.is_empty() && leading_colons.is_none() {
+ return Err(input.error("expected path"));
+ } else if trailing_punct {
+ return Err(input.error("expected path segment"));
+ }
+ Ok(QualifiedName { segments })
+}
diff --git a/syntax/symbol.rs b/syntax/symbol.rs
index a13a4f3c..4c1607e3 100644
--- a/syntax/symbol.rs
+++ b/syntax/symbol.rs
@@ -38,12 +38,6 @@ impl Symbol {
assert!(!symbol.0.is_empty());
symbol
}
-
- /// For example, for taking a symbol and then making a new symbol
- /// for a vec of that symbol.
- pub fn prefix_with(&self, prefix: &str) -> Symbol {
- Symbol(format!("{}{}", prefix, self.to_string()))
- }
}
pub trait Segment {
diff --git a/syntax/tokens.rs b/syntax/tokens.rs
index 33f20fa3..a9f42bd4 100644
--- a/syntax/tokens.rs
+++ b/syntax/tokens.rs
@@ -1,7 +1,7 @@
use crate::syntax::atom::Atom::*;
use crate::syntax::{
Array, Atom, Derive, Enum, EnumRepr, ExternFn, ExternType, Impl, Lifetimes, NamedType, Ptr,
- Receiver, Ref, Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var,
+ Ref, Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var,
};
use proc_macro2::{Ident, Span, TokenStream};
use quote::{quote_spanned, ToTokens};
@@ -13,10 +13,13 @@ impl ToTokens for Type {
Type::Ident(ident) => {
if ident.rust == Char {
let span = ident.rust.span();
- tokens.extend(quote_spanned!(span=> ::std::os::raw::));
+ tokens.extend(quote_spanned!(span=> ::cxx::private::));
} else if ident.rust == CxxString {
let span = ident.rust.span();
tokens.extend(quote_spanned!(span=> ::cxx::));
+ } else if ident.rust == RustString {
+ let span = ident.rust.span();
+ tokens.extend(quote_spanned!(span=> ::cxx::alloc::string::));
}
ident.to_tokens(tokens);
}
@@ -39,6 +42,7 @@ impl ToTokens for Type {
impl ToTokens for Var {
fn to_tokens(&self, tokens: &mut TokenStream) {
let Var {
+ cfg: _,
doc: _,
attrs: _,
visibility: _,
@@ -65,8 +69,11 @@ impl ToTokens for Ty1 {
"UniquePtr" | "SharedPtr" | "WeakPtr" | "CxxVector" => {
tokens.extend(quote_spanned!(span=> ::cxx::));
}
+ "Box" => {
+ tokens.extend(quote_spanned!(span=> ::cxx::alloc::boxed::));
+ }
"Vec" => {
- tokens.extend(quote_spanned!(span=> ::std::vec::));
+ tokens.extend(quote_spanned!(span=> ::cxx::alloc::vec::));
}
_ => {}
}
@@ -89,7 +96,7 @@ impl ToTokens for Ref {
mutability,
} = self;
if let Some((pin, langle, _rangle)) = pin_tokens {
- tokens.extend(quote_spanned!(pin.span=> ::std::pin::Pin));
+ tokens.extend(quote_spanned!(pin.span=> ::cxx::core::pin::Pin));
langle.to_tokens(tokens);
}
ampersand.to_tokens(tokens);
@@ -214,6 +221,7 @@ impl ToTokens for ExternFn {
impl ToTokens for Impl {
fn to_tokens(&self, tokens: &mut TokenStream) {
let Impl {
+ cfg: _,
impl_token,
impl_generics,
negative: _,
@@ -246,6 +254,7 @@ impl ToTokens for Lifetimes {
impl ToTokens for Signature {
fn to_tokens(&self, tokens: &mut TokenStream) {
let Signature {
+ asyncness: _,
unsafety: _,
fn_token,
generics: _,
@@ -284,6 +293,7 @@ impl ToTokens for EnumRepr {
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
EnumRepr::Native { atom, repr_type: _ } => atom.to_tokens(tokens),
+ #[cfg(feature = "experimental-enum-variants-from-header")]
EnumRepr::Foreign { rust_type } => rust_type.to_tokens(tokens),
}
}
@@ -296,74 +306,3 @@ impl ToTokens for NamedType {
generics.to_tokens(tokens);
}
}
-
-pub struct ReceiverType<'a>(&'a Receiver);
-pub struct ReceiverTypeSelf<'a>(&'a Receiver);
-
-impl Receiver {
- // &TheType
- pub fn ty(&self) -> ReceiverType {
- ReceiverType(self)
- }
-
- // &Self
- pub fn ty_self(&self) -> ReceiverTypeSelf {
- ReceiverTypeSelf(self)
- }
-}
-
-impl ToTokens for ReceiverType<'_> {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- let Receiver {
- pinned: _,
- ampersand,
- lifetime,
- mutable: _,
- var: _,
- colon_token: _,
- ty,
- shorthand: _,
- pin_tokens,
- mutability,
- } = &self.0;
- if let Some((pin, langle, _rangle)) = pin_tokens {
- tokens.extend(quote_spanned!(pin.span=> ::std::pin::Pin));
- langle.to_tokens(tokens);
- }
- ampersand.to_tokens(tokens);
- lifetime.to_tokens(tokens);
- mutability.to_tokens(tokens);
- ty.to_tokens(tokens);
- if let Some((_pin, _langle, rangle)) = pin_tokens {
- rangle.to_tokens(tokens);
- }
- }
-}
-
-impl ToTokens for ReceiverTypeSelf<'_> {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- let Receiver {
- pinned: _,
- ampersand,
- lifetime,
- mutable: _,
- var: _,
- colon_token: _,
- ty,
- shorthand: _,
- pin_tokens,
- mutability,
- } = &self.0;
- if let Some((pin, langle, _rangle)) = pin_tokens {
- tokens.extend(quote_spanned!(pin.span=> ::std::pin::Pin));
- langle.to_tokens(tokens);
- }
- ampersand.to_tokens(tokens);
- lifetime.to_tokens(tokens);
- mutability.to_tokens(tokens);
- Token![Self](ty.rust.span()).to_tokens(tokens);
- if let Some((_pin, _langle, rangle)) = pin_tokens {
- rangle.to_tokens(tokens);
- }
- }
-}
diff --git a/syntax/types.rs b/syntax/types.rs
index c54682bd..82b45300 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -92,6 +92,7 @@ impl<'a> Types<'a> {
EnumRepr::Native { atom: _, repr_type } => {
all.insert(repr_type);
}
+ #[cfg(feature = "experimental-enum-variants-from-header")]
EnumRepr::Foreign { rust_type: _ } => {}
}
let ident = &enm.name.rust;
diff --git a/tests/BUCK b/tests/BUCK
index d131ddb9..865eebc9 100644
--- a/tests/BUCK
+++ b/tests/BUCK
@@ -3,6 +3,7 @@ load("//tools/buck:rust_cxx_bridge.bzl", "rust_cxx_bridge")
rust_test(
name = "test",
srcs = ["test.rs"],
+ edition = "2018",
deps = [
":ffi",
"//:cxx",
@@ -17,6 +18,7 @@ rust_library(
"ffi/module.rs",
],
crate = "cxx_test_suite",
+ edition = "2018",
deps = [
":impl",
"//:cxx",
@@ -30,20 +32,26 @@ cxx_library(
":bridge/source",
":module/source",
],
- headers = {
+ exported_deps = ["//:core"],
+ exported_headers = {
"ffi/lib.rs.h": ":bridge/header",
"ffi/module.rs.h": ":module/header",
"ffi/tests.h": "ffi/tests.h",
},
- deps = ["//:core"],
)
rust_cxx_bridge(
name = "bridge",
src = "ffi/lib.rs",
+ deps = [
+ ":impl",
+ ],
)
rust_cxx_bridge(
name = "module",
src = "ffi/module.rs",
+ deps = [
+ ":impl",
+ ],
)
diff --git a/tests/BUILD b/tests/BUILD
index d4af3aff..3c25d963 100644
--- a/tests/BUILD
+++ b/tests/BUILD
@@ -1,11 +1,12 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
-load("@rules_rust//rust:rust.bzl", "rust_library", "rust_test")
+load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
load("//tools/bazel:rust_cxx_bridge.bzl", "rust_cxx_bridge")
rust_test(
name = "test",
size = "small",
srcs = ["test.rs"],
+ edition = "2018",
deps = [
":cxx_test_suite",
"//:cxx",
@@ -19,6 +20,7 @@ rust_library(
"ffi/lib.rs",
"ffi/module.rs",
],
+ edition = "2018",
deps = [
":impl",
"//:cxx",
diff --git a/tests/compiletest.rs b/tests/compiletest.rs
index d2b516f5..cd58514f 100644
--- a/tests/compiletest.rs
+++ b/tests/compiletest.rs
@@ -1,5 +1,7 @@
+#[allow(unused_attributes)]
#[rustversion::attr(not(nightly), ignore)]
#[cfg_attr(skip_ui_tests, ignore)]
+#[cfg_attr(miri, ignore)]
#[test]
fn ui() {
let t = trybuild::TestCases::new();
diff --git a/tests/ffi/Cargo.toml b/tests/ffi/Cargo.toml
index e62d0906..ef91f4f6 100644
--- a/tests/ffi/Cargo.toml
+++ b/tests/ffi/Cargo.toml
@@ -1,6 +1,7 @@
[package]
name = "cxx-test-suite"
version = "0.0.0"
+authors = ["David Tolnay <dtolnay@gmail.com>"]
edition = "2018"
publish = false
@@ -8,7 +9,7 @@ publish = false
path = "lib.rs"
[dependencies]
-cxx = { path = "../.." }
+cxx = { path = "../..", default-features = false }
[build-dependencies]
cxx-build = { path = "../../gen/build" }
diff --git a/tests/ffi/lib.rs b/tests/ffi/lib.rs
index 25b4ccdc..9286cf7a 100644
--- a/tests/ffi/lib.rs
+++ b/tests/ffi/lib.rs
@@ -1,5 +1,6 @@
#![allow(
clippy::boxed_local,
+ clippy::derive_partial_eq_without_eq,
clippy::just_underscores_and_digits,
clippy::let_underscore_drop,
clippy::missing_safety_doc,
@@ -15,7 +16,7 @@
pub mod cast;
pub mod module;
-use cxx::{CxxString, CxxVector, SharedPtr, UniquePtr};
+use cxx::{type_id, CxxString, CxxVector, ExternType, SharedPtr, UniquePtr};
use std::fmt::{self, Display};
use std::mem::MaybeUninit;
use std::os::raw::c_char;
@@ -80,6 +81,7 @@ pub mod ffi {
pub struct Array {
a: [i32; 4],
+ b: Buffer,
}
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
@@ -103,6 +105,7 @@ pub mod ffi {
fn c_return_slice_char(shared: &Shared) -> &[c_char];
fn c_return_mutsliceu8(slice: &mut [u8]) -> &mut [u8];
fn c_return_rust_string() -> String;
+ fn c_return_rust_string_lossy() -> String;
fn c_return_unique_ptr_string() -> UniquePtr<CxxString>;
fn c_return_unique_ptr_vector_u8() -> UniquePtr<CxxVector<u8>>;
fn c_return_unique_ptr_vector_f64() -> UniquePtr<CxxVector<f64>>;
@@ -111,10 +114,11 @@ pub mod ffi {
fn c_return_unique_ptr_vector_opaque() -> UniquePtr<CxxVector<C>>;
fn c_return_ref_vector(c: &C) -> &CxxVector<u8>;
fn c_return_mut_vector(c: Pin<&mut C>) -> Pin<&mut CxxVector<u8>>;
- fn c_return_rust_vec() -> Vec<u8>;
+ fn c_return_rust_vec_u8() -> Vec<u8>;
fn c_return_ref_rust_vec(c: &C) -> &Vec<u8>;
fn c_return_mut_rust_vec(c: Pin<&mut C>) -> &mut Vec<u8>;
fn c_return_rust_vec_string() -> Vec<String>;
+ fn c_return_rust_vec_bool() -> Vec<bool>;
fn c_return_identity(_: usize) -> usize;
fn c_return_sum(_: usize, _: usize) -> usize;
fn c_return_enum(n: u16) -> Enum;
@@ -149,6 +153,8 @@ pub mod ffi {
fn c_take_rust_vec_index(v: Vec<u8>);
fn c_take_rust_vec_shared_index(v: Vec<Shared>);
fn c_take_rust_vec_shared_push(v: Vec<Shared>);
+ fn c_take_rust_vec_shared_truncate(v: Vec<Shared>);
+ fn c_take_rust_vec_shared_clear(v: Vec<Shared>);
fn c_take_rust_vec_shared_forward_iterator(v: Vec<Shared>);
fn c_take_rust_vec_shared_sort(v: Vec<Shared>);
fn c_take_ref_rust_vec(v: &Vec<u8>);
@@ -245,6 +251,10 @@ pub mod ffi {
CVal2,
}
+ extern "C++" {
+ type Buffer = crate::Buffer;
+ }
+
extern "Rust" {
type R;
@@ -409,6 +419,15 @@ impl ffi::Array {
}
}
+#[derive(Default)]
+#[repr(C)]
+pub struct Buffer([c_char; 12]);
+
+unsafe impl ExternType for Buffer {
+ type Id = type_id!("tests::Buffer");
+ type Kind = cxx::kind::Trivial;
+}
+
#[derive(Debug)]
struct Error;
diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc
index df7ded07..984e2220 100644
--- a/tests/ffi/tests.cc
+++ b/tests/ffi/tests.cc
@@ -110,6 +110,10 @@ rust::Slice<uint8_t> c_return_mutsliceu8(rust::Slice<uint8_t> slice) {
rust::String c_return_rust_string() { return "2020"; }
+rust::String c_return_rust_string_lossy() {
+ return rust::String::lossy("Hello \xf0\x90\x80World");
+}
+
std::unique_ptr<std::string> c_return_unique_ptr_string() {
return std::unique_ptr<std::string>(new std::string("2020"));
}
@@ -154,7 +158,7 @@ const std::vector<uint8_t> &c_return_ref_vector(const C &c) {
std::vector<uint8_t> &c_return_mut_vector(C &c) { return c.get_v(); }
-rust::Vec<uint8_t> c_return_rust_vec() {
+rust::Vec<uint8_t> c_return_rust_vec_u8() {
rust::Vec<uint8_t> vec{2, 0, 2, 0};
return vec;
}
@@ -173,6 +177,8 @@ rust::Vec<rust::String> c_return_rust_vec_string() {
return {"2", "0", "2", "0"};
}
+rust::Vec<bool> c_return_rust_vec_bool() { return {true, true, false}; }
+
size_t c_return_identity(size_t n) { return n; }
size_t c_return_sum(size_t n1, size_t n2) { return n1 + n2; }
@@ -452,6 +458,23 @@ void c_take_rust_vec_shared_push(rust::Vec<Shared> v) {
}
}
+void c_take_rust_vec_shared_truncate(rust::Vec<Shared> v) {
+ v.truncate(1);
+ if (v.size() == 1) {
+ v.truncate(0);
+ if (v.size() == 0) {
+ cxx_test_suite_set_correct();
+ }
+ }
+}
+
+void c_take_rust_vec_shared_clear(rust::Vec<Shared> v) {
+ v.clear();
+ if (v.size() == 0) {
+ cxx_test_suite_set_correct();
+ }
+}
+
void c_take_ref_rust_vec(const rust::Vec<uint8_t> &v) {
uint8_t sum = std::accumulate(v.begin(), v.end(), 0);
if (sum == 200) {
@@ -853,6 +876,12 @@ extern "C" const char *cxx_run_test() noexcept {
rust::String utf16_rstring = utf16_literal;
ASSERT(utf8_rstring == utf16_rstring);
+ const char *bad_utf8_literal = "test\x80";
+ const char16_t *bad_utf16_literal = u"test\xDD1E";
+ rust::String bad_utf8_rstring = rust::String::lossy(bad_utf8_literal);
+ rust::String bad_utf16_rstring = rust::String::lossy(bad_utf16_literal);
+ ASSERT(bad_utf8_rstring == bad_utf16_rstring);
+
rust::Vec<int> vec1{1, 2};
rust::Vec<int> vec2{3, 4};
swap(vec1, vec2);
diff --git a/tests/ffi/tests.h b/tests/ffi/tests.h
index b624d393..dc02e4ff 100644
--- a/tests/ffi/tests.h
+++ b/tests/ffi/tests.h
@@ -84,6 +84,8 @@ struct Borrow {
const std::string &s;
};
+typedef char Buffer[12];
+
size_t c_return_primitive();
Shared c_return_shared();
::A::AShared c_return_ns_shared();
@@ -100,6 +102,7 @@ rust::Str c_return_str(const Shared &shared);
rust::Slice<const char> c_return_slice_char(const Shared &shared);
rust::Slice<uint8_t> c_return_mutsliceu8(rust::Slice<uint8_t> slice);
rust::String c_return_rust_string();
+rust::String c_return_rust_string_lossy();
std::unique_ptr<std::string> c_return_unique_ptr_string();
std::unique_ptr<std::vector<uint8_t>> c_return_unique_ptr_vector_u8();
std::unique_ptr<std::vector<double>> c_return_unique_ptr_vector_f64();
@@ -108,10 +111,11 @@ std::unique_ptr<std::vector<Shared>> c_return_unique_ptr_vector_shared();
std::unique_ptr<std::vector<C>> c_return_unique_ptr_vector_opaque();
const std::vector<uint8_t> &c_return_ref_vector(const C &c);
std::vector<uint8_t> &c_return_mut_vector(C &c);
-rust::Vec<uint8_t> c_return_rust_vec();
+rust::Vec<uint8_t> c_return_rust_vec_u8();
const rust::Vec<uint8_t> &c_return_ref_rust_vec(const C &c);
rust::Vec<uint8_t> &c_return_mut_rust_vec(C &c);
rust::Vec<rust::String> c_return_rust_vec_string();
+rust::Vec<bool> c_return_rust_vec_bool();
size_t c_return_identity(size_t n);
size_t c_return_sum(size_t n1, size_t n2);
Enum c_return_enum(uint16_t n);
@@ -152,6 +156,8 @@ void c_take_rust_vec_nested_ns_shared(rust::Vec<::A::B::ABShared> v);
void c_take_rust_vec_string(rust::Vec<rust::String> v);
void c_take_rust_vec_shared_index(rust::Vec<Shared> v);
void c_take_rust_vec_shared_push(rust::Vec<Shared> v);
+void c_take_rust_vec_shared_truncate(rust::Vec<Shared> v);
+void c_take_rust_vec_shared_clear(rust::Vec<Shared> v);
void c_take_rust_vec_shared_forward_iterator(rust::Vec<Shared> v);
void c_take_rust_vec_shared_sort(rust::Vec<Shared> v);
void c_take_ref_rust_vec(const rust::Vec<uint8_t> &v);
diff --git a/tests/test.rs b/tests/test.rs
index 1f0b1660..bcf0a2cd 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -1,5 +1,6 @@
#![allow(
clippy::assertions_on_constants,
+ clippy::assertions_on_result_states,
clippy::cast_possible_truncation,
clippy::cast_possible_wrap,
clippy::float_cmp,
@@ -51,6 +52,7 @@ fn test_c_return() {
cast::c_char_to_unsigned(ffi::c_return_slice_char(&shared)),
);
assert_eq!("2020", ffi::c_return_rust_string());
+ assert_eq!("Hello \u{fffd}World", ffi::c_return_rust_string_lossy());
assert_eq!("2020", ffi::c_return_unique_ptr_string().to_str().unwrap());
assert_eq!(4, ffi::c_return_unique_ptr_vector_u8().len());
assert_eq!(
@@ -69,6 +71,8 @@ fn test_c_return() {
.map(|o| o.z)
.sum(),
);
+ assert_eq!(b"\x02\0\x02\0"[..], ffi::c_return_rust_vec_u8());
+ assert_eq!([true, true, false][..], ffi::c_return_rust_vec_bool());
assert_eq!(2020, ffi::c_return_identity(2020));
assert_eq!(2021, ffi::c_return_sum(2020, 1));
match ffi::c_return_enum(0) {
@@ -167,6 +171,10 @@ fn test_c_take() {
check!(ffi::c_take_rust_vec_shared(shared_test_vec.clone()));
check!(ffi::c_take_rust_vec_shared_index(shared_test_vec.clone()));
check!(ffi::c_take_rust_vec_shared_push(shared_test_vec.clone()));
+ check!(ffi::c_take_rust_vec_shared_truncate(
+ shared_test_vec.clone()
+ ));
+ check!(ffi::c_take_rust_vec_shared_clear(shared_test_vec.clone()));
check!(ffi::c_take_rust_vec_shared_forward_iterator(
shared_test_vec,
));
@@ -256,7 +264,10 @@ fn test_c_method_calls() {
assert_eq!(2023, *ffi::Shared { z: 2023 }.c_method_mut_on_shared());
let val = 42;
- let mut array = ffi::Array { a: [0, 0, 0, 0] };
+ let mut array = ffi::Array {
+ a: [0, 0, 0, 0],
+ b: ffi::Buffer::default(),
+ };
array.c_set_array(val);
assert_eq!(array.a.len() as i32 * val, array.r_get_array_sum());
}
diff --git a/tests/ui/array_len_expr.stderr b/tests/ui/array_len_expr.stderr
index 4b45a0b9..c58cfbc2 100644
--- a/tests/ui/array_len_expr.stderr
+++ b/tests/ui/array_len_expr.stderr
@@ -1,17 +1,17 @@
error: array length must be an integer literal
- --> $DIR/array_len_expr.rs:4:28
+ --> tests/ui/array_len_expr.rs:4:28
|
4 | arraystr: [String; "13"],
| ^^^^
error: unsupported expression, array length must be an integer literal
- --> $DIR/array_len_expr.rs:5:28
+ --> tests/ui/array_len_expr.rs:5:28
|
5 | arraysub: [String; 15 - 1],
| ^^^^^^
error: array with zero size is not supported
- --> $DIR/array_len_expr.rs:6:20
+ --> tests/ui/array_len_expr.rs:6:20
|
6 | arrayzero: [String; 0],
| ^^^^^^^^^^^
diff --git a/tests/ui/array_len_suffix.stderr b/tests/ui/array_len_suffix.stderr
index 143bcb04..1dde790e 100644
--- a/tests/ui/array_len_suffix.stderr
+++ b/tests/ui/array_len_suffix.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/array_len_suffix.rs:4:32
+ --> tests/ui/array_len_suffix.rs:4:32
|
4 | fn array() -> [String; 12u16];
| ^^^^^ expected `usize`, found `u16`
diff --git a/tests/ui/async_fn.rs b/tests/ui/async_fn.rs
index 69f26421..4e663a0b 100644
--- a/tests/ui/async_fn.rs
+++ b/tests/ui/async_fn.rs
@@ -3,6 +3,10 @@ mod ffi {
extern "Rust" {
async fn f();
}
+
+ extern "C++" {
+ async fn g();
+ }
}
async fn f() {}
diff --git a/tests/ui/async_fn.stderr b/tests/ui/async_fn.stderr
index dedec7bb..78108650 100644
--- a/tests/ui/async_fn.stderr
+++ b/tests/ui/async_fn.stderr
@@ -1,5 +1,11 @@
-error: async function is not directly supported yet, but see https://cxx.rs/async.html for a working approach
- --> $DIR/async_fn.rs:4:9
+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
+ --> tests/ui/async_fn.rs:4:9
|
4 | async fn f();
| ^^^^^^^^^^^^^
+
+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
+ --> tests/ui/async_fn.rs:8:9
+ |
+8 | async fn g();
+ | ^^^^^^^^^^^^^
diff --git a/tests/ui/bad_explicit_impl.stderr b/tests/ui/bad_explicit_impl.stderr
index cd0a3173..c4748f42 100644
--- a/tests/ui/bad_explicit_impl.stderr
+++ b/tests/ui/bad_explicit_impl.stderr
@@ -1,5 +1,5 @@
error: unsupported Self type of explicit impl
- --> $DIR/bad_explicit_impl.rs:7:5
+ --> tests/ui/bad_explicit_impl.rs:7:5
|
7 | impl fn() -> &S {}
| ^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/by_value_not_supported.stderr b/tests/ui/by_value_not_supported.stderr
index 7288c93b..254c7bb4 100644
--- a/tests/ui/by_value_not_supported.stderr
+++ b/tests/ui/by_value_not_supported.stderr
@@ -1,59 +1,59 @@
error: using opaque C++ type by value is not supported
- --> $DIR/by_value_not_supported.rs:4:9
+ --> tests/ui/by_value_not_supported.rs:4:9
|
4 | c: C,
| ^^^^
error: using opaque Rust type by value is not supported
- --> $DIR/by_value_not_supported.rs:5:9
+ --> tests/ui/by_value_not_supported.rs:5:9
|
5 | r: R,
| ^^^^
error: using C++ string by value is not supported
- --> $DIR/by_value_not_supported.rs:6:9
+ --> tests/ui/by_value_not_supported.rs:6:9
|
6 | s: CxxString,
| ^^^^^^^^^^^^
error: needs a cxx::ExternType impl in order to be used as a field of `S`, argument of `f` or return value of `f`
- --> $DIR/by_value_not_supported.rs:10:9
+ --> tests/ui/by_value_not_supported.rs:10:9
|
10 | type C;
| ^^^^^^
error: passing opaque C++ type by value is not supported
- --> $DIR/by_value_not_supported.rs:16:14
+ --> tests/ui/by_value_not_supported.rs:16:14
|
16 | fn f(c: C) -> C;
| ^^^^
error: returning opaque C++ type by value is not supported
- --> $DIR/by_value_not_supported.rs:16:23
+ --> tests/ui/by_value_not_supported.rs:16:23
|
16 | fn f(c: C) -> C;
| ^
error: passing opaque Rust type by value is not supported
- --> $DIR/by_value_not_supported.rs:17:14
+ --> tests/ui/by_value_not_supported.rs:17:14
|
17 | fn g(r: R) -> R;
| ^^^^
error: returning opaque Rust type by value is not supported
- --> $DIR/by_value_not_supported.rs:17:23
+ --> tests/ui/by_value_not_supported.rs:17:23
|
17 | fn g(r: R) -> R;
| ^
error: passing C++ string by value is not supported
- --> $DIR/by_value_not_supported.rs:18:14
+ --> tests/ui/by_value_not_supported.rs:18:14
|
18 | fn h(s: CxxString) -> CxxString;
| ^^^^^^^^^^^^
error: returning C++ string by value is not supported
- --> $DIR/by_value_not_supported.rs:18:31
+ --> tests/ui/by_value_not_supported.rs:18:31
|
18 | fn h(s: CxxString) -> CxxString;
| ^^^^^^^^^
diff --git a/tests/ui/const_fn.stderr b/tests/ui/const_fn.stderr
index a62ca837..2dd6608a 100644
--- a/tests/ui/const_fn.stderr
+++ b/tests/ui/const_fn.stderr
@@ -1,5 +1,5 @@
error: const extern function is not supported
- --> $DIR/const_fn.rs:4:9
+ --> tests/ui/const_fn.rs:4:9
|
4 | const fn f();
| ^^^^^^^^^^^^^
diff --git a/tests/ui/data_enums.stderr b/tests/ui/data_enums.stderr
index c78bce55..d8aa09e3 100644
--- a/tests/ui/data_enums.stderr
+++ b/tests/ui/data_enums.stderr
@@ -1,5 +1,5 @@
error: enums with data are not supported yet
- --> $DIR/data_enums.rs:4:9
+ --> tests/ui/data_enums.rs:4:9
|
4 | Field(u64),
| ^^^^^^^^^^
diff --git a/tests/ui/deny_elided_lifetimes.rs b/tests/ui/deny_elided_lifetimes.rs
new file mode 100644
index 00000000..0ab3f750
--- /dev/null
+++ b/tests/ui/deny_elided_lifetimes.rs
@@ -0,0 +1,27 @@
+#![deny(elided_lifetimes_in_paths)]
+
+#[cxx::bridge]
+mod ffi {
+ #[derive(PartialEq, PartialOrd, Hash)]
+ struct Struct<'a> {
+ reference: &'a i32,
+ }
+
+ extern "Rust" {
+ type Rust<'a>;
+ }
+
+ unsafe extern "C++" {
+ type Cpp<'a>;
+
+ fn lifetime_named<'a>(s: &'a i32) -> UniquePtr<Cpp<'a>>;
+
+ fn lifetime_underscore(s: &i32) -> UniquePtr<Cpp<'_>>;
+
+ fn lifetime_elided(s: &i32) -> UniquePtr<Cpp>;
+ }
+}
+
+pub struct Rust<'a>(&'a i32);
+
+fn main() {}
diff --git a/tests/ui/deny_elided_lifetimes.stderr b/tests/ui/deny_elided_lifetimes.stderr
new file mode 100644
index 00000000..857bb5b7
--- /dev/null
+++ b/tests/ui/deny_elided_lifetimes.stderr
@@ -0,0 +1,15 @@
+error: hidden lifetime parameters in types are deprecated
+ --> tests/ui/deny_elided_lifetimes.rs:21:50
+ |
+21 | fn lifetime_elided(s: &i32) -> UniquePtr<Cpp>;
+ | ^^^ expected lifetime parameter
+ |
+note: the lint level is defined here
+ --> tests/ui/deny_elided_lifetimes.rs:1:9
+ |
+1 | #![deny(elided_lifetimes_in_paths)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+help: indicate the anonymous lifetime
+ |
+21 | fn lifetime_elided(s: &i32) -> UniquePtr<Cpp<'_>>;
+ | ++++
diff --git a/tests/ui/deny_missing_docs.stderr b/tests/ui/deny_missing_docs.stderr
index e7aadfbe..54ab987b 100644
--- a/tests/ui/deny_missing_docs.stderr
+++ b/tests/ui/deny_missing_docs.stderr
@@ -1,47 +1,47 @@
error: missing documentation for a struct
- --> $DIR/deny_missing_docs.rs:11:5
+ --> tests/ui/deny_missing_docs.rs:11:5
|
11 | pub struct UndocumentedStruct {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/deny_missing_docs.rs:6:9
+ --> tests/ui/deny_missing_docs.rs:6:9
|
6 | #![deny(missing_docs)]
| ^^^^^^^^^^^^
error: missing documentation for a struct field
- --> $DIR/deny_missing_docs.rs:12:9
+ --> tests/ui/deny_missing_docs.rs:12:9
|
12 | pub undocumented_field: u8,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a struct
- --> $DIR/deny_missing_docs.rs:21:5
+ --> tests/ui/deny_missing_docs.rs:21:5
|
21 | pub enum UndocumentedEnum {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for an associated constant
- --> $DIR/deny_missing_docs.rs:22:9
+ --> tests/ui/deny_missing_docs.rs:22:9
|
22 | UndocumentedVariant = 0,
| ^^^^^^^^^^^^^^^^^^^
error: missing documentation for a struct
- --> $DIR/deny_missing_docs.rs:44:9
+ --> tests/ui/deny_missing_docs.rs:44:9
|
44 | pub type UndocumentedForeignType;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a type alias
- --> $DIR/deny_missing_docs.rs:49:9
+ --> tests/ui/deny_missing_docs.rs:49:9
|
49 | pub type UndocumentedTypeAlias = crate::bindgen::UndocumentedTypeAlias;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a function
- --> $DIR/deny_missing_docs.rs:54:9
+ --> tests/ui/deny_missing_docs.rs:54:9
|
54 | pub fn undocumented_foreign_fn() -> u8;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/derive_duplicate.stderr b/tests/ui/derive_duplicate.stderr
index ce271632..75920862 100644
--- a/tests/ui/derive_duplicate.stderr
+++ b/tests/ui/derive_duplicate.stderr
@@ -1,7 +1,7 @@
-error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `ffi::Struct`
- --> $DIR/derive_duplicate.rs:3:21
+error[E0119]: conflicting implementations of trait `Clone` for type `Struct`
+ --> tests/ui/derive_duplicate.rs:3:21
|
3 | #[derive(Clone, Clone)]
- | ----- ^^^^^ conflicting implementation for `ffi::Struct`
+ | ----- ^^^^^ conflicting implementation for `Struct`
| |
| first implementation here
diff --git a/tests/ui/derive_noncopy.stderr b/tests/ui/derive_noncopy.stderr
index d6410280..419b0f22 100644
--- a/tests/ui/derive_noncopy.stderr
+++ b/tests/ui/derive_noncopy.stderr
@@ -1,8 +1,7 @@
error[E0204]: the trait `Copy` may not be implemented for this type
- --> $DIR/derive_noncopy.rs:3:14
+ --> tests/ui/derive_noncopy.rs:4:12
|
-3 | #[derive(Copy)]
- | ^^^^
4 | struct TryCopy {
+ | ^^^^^^^
5 | other: Other,
| ------------ this field does not implement `Copy`
diff --git a/tests/ui/drop_shared.stderr b/tests/ui/drop_shared.stderr
index f2724e35..41a5287f 100644
--- a/tests/ui/drop_shared.stderr
+++ b/tests/ui/drop_shared.stderr
@@ -1,8 +1,8 @@
-error[E0119]: conflicting implementations of trait `ffi::_::forbid::Drop` for type `ffi::Shared`
- --> $DIR/drop_shared.rs:3:5
+error[E0119]: conflicting implementations of trait `forbid::Drop` for type `Shared`
+ --> tests/ui/drop_shared.rs:3:5
|
1 | #[cxx::bridge]
| -------------- first implementation here
2 | mod ffi {
3 | struct Shared {
- | ^^^^^^^^^^^^^ conflicting implementation for `ffi::Shared`
+ | ^^^^^^^^^^^^^ conflicting implementation for `Shared`
diff --git a/tests/ui/empty_enum.stderr b/tests/ui/empty_enum.stderr
index 0556da9a..60d3b5da 100644
--- a/tests/ui/empty_enum.stderr
+++ b/tests/ui/empty_enum.stderr
@@ -1,5 +1,5 @@
error: explicit #[repr(...)] is required for enum without any variants
- --> $DIR/empty_enum.rs:3:5
+ --> tests/ui/empty_enum.rs:3:5
|
3 | enum A {}
| ^^^^^^^^^
diff --git a/tests/ui/empty_struct.stderr b/tests/ui/empty_struct.stderr
index 612476bd..f6fbfc11 100644
--- a/tests/ui/empty_struct.stderr
+++ b/tests/ui/empty_struct.stderr
@@ -1,5 +1,5 @@
error: structs without any fields are not supported
- --> $DIR/empty_struct.rs:3:5
+ --> tests/ui/empty_struct.rs:3:5
|
3 | struct Empty {}
| ^^^^^^^^^^^^^^^
diff --git a/tests/ui/enum_inconsistent.stderr b/tests/ui/enum_inconsistent.stderr
index c5b427a8..d6d7837e 100644
--- a/tests/ui/enum_inconsistent.stderr
+++ b/tests/ui/enum_inconsistent.stderr
@@ -1,5 +1,5 @@
error: expected u16, found i64
- --> $DIR/enum_inconsistent.rs:5:9
+ --> tests/ui/enum_inconsistent.rs:5:9
|
5 | B = 2i64,
| ^^^^^^^^
diff --git a/tests/ui/enum_match_without_wildcard.stderr b/tests/ui/enum_match_without_wildcard.stderr
index f43678f7..5808d6f8 100644
--- a/tests/ui/enum_match_without_wildcard.stderr
+++ b/tests/ui/enum_match_without_wildcard.stderr
@@ -1,11 +1,17 @@
-error[E0004]: non-exhaustive patterns: `A { repr: 2_u8..=u8::MAX }` not covered
- --> $DIR/enum_match_without_wildcard.rs:12:11
+error[E0004]: non-exhaustive patterns: `ffi::A { repr: 2_u8..=u8::MAX }` not covered
+ --> tests/ui/enum_match_without_wildcard.rs:12:11
|
-3 | enum A {
- | ------ `ffi::A` defined here
-...
12 | match a {
- | ^ pattern `A { repr: 2_u8..=u8::MAX }` not covered
+ | ^ pattern `ffi::A { repr: 2_u8..=u8::MAX }` not covered
+ |
+note: `ffi::A` defined here
+ --> tests/ui/enum_match_without_wildcard.rs:3:10
|
- = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+3 | enum A {
+ | ^
= note: the matched value is of type `ffi::A`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
+ |
+14 ~ ffi::A::FieldB => 2021,
+15 ~ ffi::A { repr: 2_u8..=u8::MAX } => todo!(),
+ |
diff --git a/tests/ui/enum_out_of_bounds.stderr b/tests/ui/enum_out_of_bounds.stderr
index 5d02e206..3244b6a7 100644
--- a/tests/ui/enum_out_of_bounds.stderr
+++ b/tests/ui/enum_out_of_bounds.stderr
@@ -1,11 +1,11 @@
error: discriminant value `18446744073709551615` is outside the limits of u32
- --> $DIR/enum_out_of_bounds.rs:5:9
+ --> tests/ui/enum_out_of_bounds.rs:5:9
|
5 | A = 0xFFFF_FFFF_FFFF_FFFF,
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: discriminant value `2000` is outside the limits of u8
- --> $DIR/enum_out_of_bounds.rs:9:9
+ --> tests/ui/enum_out_of_bounds.rs:9:9
|
9 | B = 1u8,
| ^^^^^^^
diff --git a/tests/ui/enum_overflows.stderr b/tests/ui/enum_overflows.stderr
index ed58b61c..76c37bb0 100644
--- a/tests/ui/enum_overflows.stderr
+++ b/tests/ui/enum_overflows.stderr
@@ -1,5 +1,5 @@
error: discriminant overflow on value after 18446744073709551615
- --> $DIR/enum_overflows.rs:13:9
+ --> tests/ui/enum_overflows.rs:13:9
|
13 | F,
| ^
diff --git a/tests/ui/enum_receiver.stderr b/tests/ui/enum_receiver.stderr
index e09b4e39..ace76776 100644
--- a/tests/ui/enum_receiver.stderr
+++ b/tests/ui/enum_receiver.stderr
@@ -1,5 +1,5 @@
error: unsupported receiver type; C++ does not allow member functions on enums
- --> $DIR/enum_receiver.rs:7:20
+ --> tests/ui/enum_receiver.rs:7:20
|
7 | fn f(self: &Enum);
| ^^^^^
diff --git a/tests/ui/enum_unsatisfiable.stderr b/tests/ui/enum_unsatisfiable.stderr
index 99852ca6..e2b37bdd 100644
--- a/tests/ui/enum_unsatisfiable.stderr
+++ b/tests/ui/enum_unsatisfiable.stderr
@@ -1,5 +1,5 @@
error: these discriminant values do not fit in any supported enum repr type
- --> $DIR/enum_unsatisfiable.rs:3:5
+ --> tests/ui/enum_unsatisfiable.rs:3:5
|
3 | / enum Bad {
4 | | A = -0xFFFF_FFFF_FFFF_FFFF,
diff --git a/tests/ui/expected_named.stderr b/tests/ui/expected_named.stderr
index dab3b5a3..0068bdf3 100644
--- a/tests/ui/expected_named.stderr
+++ b/tests/ui/expected_named.stderr
@@ -1,5 +1,5 @@
error[E0106]: missing lifetime specifier
- --> $DIR/expected_named.rs:5:36
+ --> tests/ui/expected_named.rs:5:36
|
5 | fn borrowed() -> UniquePtr<Borrowed>;
| ^^^^^^^^ expected named lifetime parameter
@@ -8,4 +8,4 @@ error[E0106]: missing lifetime specifier
help: consider using the `'static` lifetime
|
5 | fn borrowed() -> UniquePtr<Borrowed<'static>>;
- | ~~~~~~~~~~~~~~~~~
+ | +++++++++
diff --git a/tests/ui/extern_fn_abi.stderr b/tests/ui/extern_fn_abi.stderr
index 3abf47ab..32ef9c3e 100644
--- a/tests/ui/extern_fn_abi.stderr
+++ b/tests/ui/extern_fn_abi.stderr
@@ -1,5 +1,5 @@
error: explicit ABI on extern function is not supported
- --> $DIR/extern_fn_abi.rs:4:9
+ --> tests/ui/extern_fn_abi.rs:4:9
|
4 | extern "Java" fn f();
| ^^^^^^^^^^^^^
diff --git a/tests/ui/extern_type_bound.stderr b/tests/ui/extern_type_bound.stderr
index ca07ef7f..1d6796bc 100644
--- a/tests/ui/extern_type_bound.stderr
+++ b/tests/ui/extern_type_bound.stderr
@@ -1,11 +1,11 @@
error: extern type bounds are not implemented yet
- --> $DIR/extern_type_bound.rs:4:22
+ --> tests/ui/extern_type_bound.rs:4:22
|
4 | type Opaque: PartialEq + PartialOrd;
| ^^^^^^^^^^^^^^^^^^^^^^
error: unsupported trait
- --> $DIR/extern_type_bound.rs:11:22
+ --> tests/ui/extern_type_bound.rs:11:22
|
11 | type Opaque: for<'de> Deserialize<'de>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/extern_type_generic.stderr b/tests/ui/extern_type_generic.stderr
index 95faec6c..2b312f0e 100644
--- a/tests/ui/extern_type_generic.stderr
+++ b/tests/ui/extern_type_generic.stderr
@@ -1,5 +1,5 @@
error: extern type with generic type parameter is not supported yet
- --> $DIR/extern_type_generic.rs:4:22
+ --> tests/ui/extern_type_generic.rs:4:22
|
4 | type Generic<T>;
| ^
diff --git a/tests/ui/extern_type_lifetime_bound.stderr b/tests/ui/extern_type_lifetime_bound.stderr
index 8c58050a..6c3fc7f1 100644
--- a/tests/ui/extern_type_lifetime_bound.stderr
+++ b/tests/ui/extern_type_lifetime_bound.stderr
@@ -1,5 +1,5 @@
error: lifetime parameter with bounds is not supported yet
- --> $DIR/extern_type_lifetime_bound.rs:4:26
+ --> tests/ui/extern_type_lifetime_bound.rs:4:26
|
4 | type Complex<'a, 'b: 'a>;
| ^^^^^^
diff --git a/tests/ui/fallible_fnptr.stderr b/tests/ui/fallible_fnptr.stderr
index 1d3fbe42..4635ec8f 100644
--- a/tests/ui/fallible_fnptr.stderr
+++ b/tests/ui/fallible_fnptr.stderr
@@ -1,5 +1,5 @@
error: function pointer returning Result is not supported yet
- --> $DIR/fallible_fnptr.rs:4:24
+ --> tests/ui/fallible_fnptr.rs:4:24
|
4 | fn f(callback: fn() -> Result<()>);
| ^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/function_with_body.stderr b/tests/ui/function_with_body.stderr
index c5641db8..f2078df4 100644
--- a/tests/ui/function_with_body.stderr
+++ b/tests/ui/function_with_body.stderr
@@ -1,5 +1,5 @@
error: expected `;`
- --> $DIR/function_with_body.rs:4:16
+ --> tests/ui/function_with_body.rs:4:16
|
4 | fn f() {}
| ^
diff --git a/tests/ui/generic_enum.stderr b/tests/ui/generic_enum.stderr
index ea83d7c8..2529af73 100644
--- a/tests/ui/generic_enum.stderr
+++ b/tests/ui/generic_enum.stderr
@@ -1,17 +1,17 @@
error: enum with generic parameters is not supported
- --> $DIR/generic_enum.rs:3:5
+ --> tests/ui/generic_enum.rs:3:5
|
3 | enum A<T> {
| ^^^^^^^^^
error: enum with generic parameters is not supported
- --> $DIR/generic_enum.rs:7:5
+ --> tests/ui/generic_enum.rs:7:5
|
7 | enum B<T> where T: Copy {
| ^^^^^^^^^
error: enum with where-clause is not supported
- --> $DIR/generic_enum.rs:11:12
+ --> tests/ui/generic_enum.rs:11:12
|
11 | enum C where void: Copy {
| ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/impl_trait_for_type.stderr b/tests/ui/impl_trait_for_type.stderr
index e05a461e..fa99de5a 100644
--- a/tests/ui/impl_trait_for_type.stderr
+++ b/tests/ui/impl_trait_for_type.stderr
@@ -1,5 +1,5 @@
error: unexpected impl, expected something like `impl UniquePtr<T> {}`
- --> $DIR/impl_trait_for_type.rs:7:10
+ --> tests/ui/impl_trait_for_type.rs:7:10
|
7 | impl UniquePtrTarget for S {}
| ^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/include.stderr b/tests/ui/include.stderr
index c85a83ea..45cc5591 100644
--- a/tests/ui/include.stderr
+++ b/tests/ui/include.stderr
@@ -1,29 +1,29 @@
error: unexpected token
- --> $DIR/include.rs:4:28
+ --> tests/ui/include.rs:4:28
|
4 | include!("path/to" what);
| ^^^^
error: unexpected token
- --> $DIR/include.rs:5:28
+ --> tests/ui/include.rs:5:28
|
5 | include!(<path/to> what);
| ^^^^
error: expected `>`
- --> $DIR/include.rs:6:17
+ --> tests/ui/include.rs:6:17
|
6 | include!(<path/to);
| ^^^^^^^^^^
error: unexpected token in include path
- --> $DIR/include.rs:7:23
+ --> tests/ui/include.rs:7:23
|
7 | include!(<path[to]>);
| ^^^^
error: expected "quoted/path/to" or <bracketed/path/to>
- --> $DIR/include.rs:8:18
+ --> tests/ui/include.rs:8:18
|
8 | include!(...);
- | ^^^
+ | ^
diff --git a/tests/ui/lifetime_extern_cxx.stderr b/tests/ui/lifetime_extern_cxx.stderr
index 099c6ce4..a5cc3bda 100644
--- a/tests/ui/lifetime_extern_cxx.stderr
+++ b/tests/ui/lifetime_extern_cxx.stderr
@@ -1,5 +1,5 @@
error: extern C++ function with lifetimes must be declared in `unsafe extern "C++"` block
- --> $DIR/lifetime_extern_cxx.rs:5:9
+ --> tests/ui/lifetime_extern_cxx.rs:5:9
|
5 | unsafe fn f<'a>(&'a self, arg: &str) -> &'a str;
| ^^^^^^^^^^^^^^^
diff --git a/tests/ui/lifetime_extern_rust.stderr b/tests/ui/lifetime_extern_rust.stderr
index 0fc806ad..b2ca4950 100644
--- a/tests/ui/lifetime_extern_rust.stderr
+++ b/tests/ui/lifetime_extern_rust.stderr
@@ -1,5 +1,5 @@
error: must be `unsafe fn f` in order to expose explicit lifetimes to C++
- --> $DIR/lifetime_extern_rust.rs:5:9
+ --> tests/ui/lifetime_extern_rust.rs:5:9
|
5 | fn f<'a>(&'a self, arg: &str) -> &'a str;
| ^^^^^^^^
diff --git a/tests/ui/missing_unsafe.stderr b/tests/ui/missing_unsafe.stderr
index df1bce22..e7dcba74 100644
--- a/tests/ui/missing_unsafe.stderr
+++ b/tests/ui/missing_unsafe.stderr
@@ -1,7 +1,9 @@
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
- --> $DIR/missing_unsafe.rs:4:12
+ --> tests/ui/missing_unsafe.rs:4:12
|
4 | fn f(x: i32);
- | ^ call to unsafe function
+ | ^ - items do not inherit unsafety from separate enclosing items
+ | |
+ | call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
diff --git a/tests/ui/multiple_parse_error.stderr b/tests/ui/multiple_parse_error.stderr
index f736fd1f..32b8e560 100644
--- a/tests/ui/multiple_parse_error.stderr
+++ b/tests/ui/multiple_parse_error.stderr
@@ -1,11 +1,11 @@
error: unit structs are not supported
- --> $DIR/multiple_parse_error.rs:3:5
+ --> tests/ui/multiple_parse_error.rs:3:5
|
3 | struct Monad<T>;
| ^^^^^^^^^^^^^^^^
error: unrecognized ABI, requires either "C++" or "Rust"
- --> $DIR/multiple_parse_error.rs:5:5
+ --> tests/ui/multiple_parse_error.rs:5:5
|
5 | extern "Haskell" {}
| ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/mut_return.stderr b/tests/ui/mut_return.stderr
index e33393d8..37e947a7 100644
--- a/tests/ui/mut_return.stderr
+++ b/tests/ui/mut_return.stderr
@@ -1,11 +1,11 @@
error: &mut return type is not allowed unless there is a &mut argument
- --> $DIR/mut_return.rs:10:9
+ --> tests/ui/mut_return.rs:10:9
|
10 | fn f(t: &Thing) -> Pin<&mut CxxString>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: &mut return type is not allowed unless there is a &mut argument
- --> $DIR/mut_return.rs:14:9
+ --> tests/ui/mut_return.rs:14:9
|
14 | fn j(t: &Thing) -> &mut [u8];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/non_integer_discriminant_enum.stderr b/tests/ui/non_integer_discriminant_enum.stderr
index 926fd905..aa4388fb 100644
--- a/tests/ui/non_integer_discriminant_enum.stderr
+++ b/tests/ui/non_integer_discriminant_enum.stderr
@@ -1,5 +1,5 @@
error: enums with non-integer literal discriminants are not supported yet
- --> $DIR/non_integer_discriminant_enum.rs:4:9
+ --> tests/ui/non_integer_discriminant_enum.rs:4:9
|
4 | Field = 2020 + 1,
| ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/nonempty_impl_block.stderr b/tests/ui/nonempty_impl_block.stderr
index e7881bb0..6f698305 100644
--- a/tests/ui/nonempty_impl_block.stderr
+++ b/tests/ui/nonempty_impl_block.stderr
@@ -1,5 +1,5 @@
error: expected an empty impl block
- --> $DIR/nonempty_impl_block.rs:7:23
+ --> tests/ui/nonempty_impl_block.rs:7:23
|
7 | impl UniquePtr<S> {
| _______________________^
diff --git a/tests/ui/nonlocal_rust_type.stderr b/tests/ui/nonlocal_rust_type.stderr
index d266353c..f6cb06cb 100644
--- a/tests/ui/nonlocal_rust_type.stderr
+++ b/tests/ui/nonlocal_rust_type.stderr
@@ -1,5 +1,5 @@
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
- --> $DIR/nonlocal_rust_type.rs:10:9
+error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
+ --> tests/ui/nonlocal_rust_type.rs:10:9
|
10 | type OptBuilder<'a>;
| ^^^^^--------------
@@ -9,11 +9,11 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
= note: define and implement a trait or new type instead
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
- --> $DIR/nonlocal_rust_type.rs:14:13
+error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
+ --> tests/ui/nonlocal_rust_type.rs:14:13
|
14 | rs: Box<OptBuilder<'a>>,
- | ^^^^---------------
+ | ^^^^--------------
| | |
| | `Option` is not defined in the current crate
| impl doesn't use only types from inside the current crate
diff --git a/tests/ui/opaque_autotraits.stderr b/tests/ui/opaque_autotraits.stderr
index 15a2b64c..521d9864 100644
--- a/tests/ui/opaque_autotraits.stderr
+++ b/tests/ui/opaque_autotraits.stderr
@@ -1,59 +1,59 @@
error[E0277]: `*const cxx::void` cannot be sent between threads safely
- --> $DIR/opaque_autotraits.rs:13:5
+ --> tests/ui/opaque_autotraits.rs:13:19
|
13 | assert_send::<ffi::Opaque>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const cxx::void` cannot be sent between threads safely
+ | ^^^^^^^^^^^ `*const cxx::void` cannot be sent between threads safely
|
= help: within `ffi::Opaque`, the trait `Send` is not implemented for `*const cxx::void`
= note: required because it appears within the type `[*const cxx::void; 0]`
= note: required because it appears within the type `cxx::private::Opaque`
note: required because it appears within the type `ffi::Opaque`
- --> $DIR/opaque_autotraits.rs:4:14
+ --> tests/ui/opaque_autotraits.rs:4:14
|
4 | type Opaque;
| ^^^^^^
note: required by a bound in `assert_send`
- --> $DIR/opaque_autotraits.rs:8:19
+ --> tests/ui/opaque_autotraits.rs:8:19
|
8 | fn assert_send<T: Send>() {}
| ^^^^ required by this bound in `assert_send`
error[E0277]: `*const cxx::void` cannot be shared between threads safely
- --> $DIR/opaque_autotraits.rs:14:5
+ --> tests/ui/opaque_autotraits.rs:14:19
|
14 | assert_sync::<ffi::Opaque>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const cxx::void` cannot be shared between threads safely
+ | ^^^^^^^^^^^ `*const cxx::void` cannot be shared between threads safely
|
= help: within `ffi::Opaque`, the trait `Sync` is not implemented for `*const cxx::void`
= note: required because it appears within the type `[*const cxx::void; 0]`
= note: required because it appears within the type `cxx::private::Opaque`
note: required because it appears within the type `ffi::Opaque`
- --> $DIR/opaque_autotraits.rs:4:14
+ --> tests/ui/opaque_autotraits.rs:4:14
|
4 | type Opaque;
| ^^^^^^
note: required by a bound in `assert_sync`
- --> $DIR/opaque_autotraits.rs:9:19
+ --> tests/ui/opaque_autotraits.rs:9:19
|
9 | fn assert_sync<T: Sync>() {}
| ^^^^ required by this bound in `assert_sync`
error[E0277]: `PhantomPinned` cannot be unpinned
- --> $DIR/opaque_autotraits.rs:15:5
+ --> tests/ui/opaque_autotraits.rs:15:20
|
15 | assert_unpin::<ffi::Opaque>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ffi::Opaque`, the trait `Unpin` is not implemented for `PhantomPinned`
+ | ^^^^^^^^^^^ within `ffi::Opaque`, the trait `Unpin` is not implemented for `PhantomPinned`
|
= note: consider using `Box::pin`
= note: required because it appears within the type `PhantomData<PhantomPinned>`
= note: required because it appears within the type `cxx::private::Opaque`
note: required because it appears within the type `ffi::Opaque`
- --> $DIR/opaque_autotraits.rs:4:14
+ --> tests/ui/opaque_autotraits.rs:4:14
|
4 | type Opaque;
| ^^^^^^
note: required by a bound in `assert_unpin`
- --> $DIR/opaque_autotraits.rs:10:20
+ --> tests/ui/opaque_autotraits.rs:10:20
|
10 | fn assert_unpin<T: Unpin>() {}
| ^^^^^ required by this bound in `assert_unpin`
diff --git a/tests/ui/opaque_not_sized.stderr b/tests/ui/opaque_not_sized.stderr
index b50a2699..85be4af3 100644
--- a/tests/ui/opaque_not_sized.stderr
+++ b/tests/ui/opaque_not_sized.stderr
@@ -1,17 +1,17 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
- --> $DIR/opaque_not_sized.rs:4:14
+ --> tests/ui/opaque_not_sized.rs:4:14
|
4 | type TypeR;
| ^^^^^ doesn't have a size known at compile-time
|
= help: within `TypeR`, the trait `Sized` is not implemented for `str`
note: required because it appears within the type `TypeR`
- --> $DIR/opaque_not_sized.rs:8:8
+ --> tests/ui/opaque_not_sized.rs:8:8
|
8 | struct TypeR(str);
| ^^^^^
note: required by a bound in `__AssertSized`
- --> $DIR/opaque_not_sized.rs:4:9
+ --> tests/ui/opaque_not_sized.rs:4:9
|
4 | type TypeR;
| ^^^^^^^^^^^ required by this bound in `__AssertSized`
diff --git a/tests/ui/pin_mut_opaque.stderr b/tests/ui/pin_mut_opaque.stderr
index 95af3cd9..8a5e019b 100644
--- a/tests/ui/pin_mut_opaque.stderr
+++ b/tests/ui/pin_mut_opaque.stderr
@@ -1,35 +1,35 @@
error: mutable reference to C++ type requires a pin -- use Pin<&mut Opaque>
- --> $DIR/pin_mut_opaque.rs:5:19
+ --> tests/ui/pin_mut_opaque.rs:5:19
|
5 | fn f(arg: &mut Opaque);
| ^^^^^^^^^^^
error: mutable reference to C++ type requires a pin -- use Pin<&mut CxxString>
- --> $DIR/pin_mut_opaque.rs:8:17
+ --> tests/ui/pin_mut_opaque.rs:8:17
|
8 | fn s(s: &mut CxxString);
| ^^^^^^^^^^^^^^
error: mutable reference to C++ type requires a pin -- use Pin<&mut CxxVector<...>>
- --> $DIR/pin_mut_opaque.rs:9:17
+ --> tests/ui/pin_mut_opaque.rs:9:17
|
9 | fn v(v: &mut CxxVector<u8>);
| ^^^^^^^^^^^^^^^^^^
error: needs a cxx::ExternType impl in order to be used as a non-pinned mutable reference in signature of `f`, `g`, `h`
- --> $DIR/pin_mut_opaque.rs:4:9
+ --> tests/ui/pin_mut_opaque.rs:4:9
|
4 | type Opaque;
| ^^^^^^^^^^^
error: mutable reference to opaque C++ type requires a pin -- use `self: Pin<&mut Opaque>`
- --> $DIR/pin_mut_opaque.rs:6:14
+ --> tests/ui/pin_mut_opaque.rs:6:14
|
6 | fn g(&mut self);
| ^^^^^^^^^
error: mutable reference to opaque C++ type requires a pin -- use `self: Pin<&mut Opaque>`
- --> $DIR/pin_mut_opaque.rs:7:20
+ --> tests/ui/pin_mut_opaque.rs:7:20
|
7 | fn h(self: &mut Opaque);
| ^^^^^^^^^^^
diff --git a/tests/ui/ptr_in_fnptr.stderr b/tests/ui/ptr_in_fnptr.stderr
index 372d4cd9..f429b1bd 100644
--- a/tests/ui/ptr_in_fnptr.stderr
+++ b/tests/ui/ptr_in_fnptr.stderr
@@ -1,5 +1,5 @@
error: pointer argument requires that the function pointer be marked unsafe
- --> $DIR/ptr_in_fnptr.rs:4:27
+ --> tests/ui/ptr_in_fnptr.rs:4:27
|
4 | fn f(callback: fn(p: *const u8));
| ^^^^^^^^^^^^
diff --git a/tests/ui/ptr_missing_unsafe.stderr b/tests/ui/ptr_missing_unsafe.stderr
index 65f53a98..d65481bc 100644
--- a/tests/ui/ptr_missing_unsafe.stderr
+++ b/tests/ui/ptr_missing_unsafe.stderr
@@ -1,5 +1,5 @@
error: pointer argument requires that the function be marked unsafe
- --> $DIR/ptr_missing_unsafe.rs:6:27
+ --> tests/ui/ptr_missing_unsafe.rs:6:27
|
6 | fn not_unsafe_ptr(c: *mut C);
| ^^^^^^^^^
diff --git a/tests/ui/ptr_no_const_mut.stderr b/tests/ui/ptr_no_const_mut.stderr
index 8a391852..4b1bf06f 100644
--- a/tests/ui/ptr_no_const_mut.stderr
+++ b/tests/ui/ptr_no_const_mut.stderr
@@ -1,13 +1,18 @@
-error: expected mut or const in raw pointer type
- --> $DIR/ptr_no_const_mut.rs:6:43
+error: expected `mut` or `const` keyword in raw pointer type
+ --> tests/ui/ptr_no_const_mut.rs:6:43
|
6 | fn get_neither_const_nor_mut() -> *C;
- | ^ expected mut or const in raw pointer type
+ | ^
|
- = help: use `*mut T` or `*const T` as appropriate
+help: add `mut` or `const` here
+ |
+6 | fn get_neither_const_nor_mut() -> *const C;
+ | +++++
+6 | fn get_neither_const_nor_mut() -> *mut C;
+ | +++
error: expected `const` or `mut`
- --> $DIR/ptr_no_const_mut.rs:6:44
+ --> tests/ui/ptr_no_const_mut.rs:6:44
|
6 | fn get_neither_const_nor_mut() -> *C;
| ^
diff --git a/tests/ui/ptr_unsupported.stderr b/tests/ui/ptr_unsupported.stderr
index a3e93434..ea1dafd8 100644
--- a/tests/ui/ptr_unsupported.stderr
+++ b/tests/ui/ptr_unsupported.stderr
@@ -1,17 +1,17 @@
error: C++ does not allow pointer to reference as a type
- --> $DIR/ptr_unsupported.rs:6:38
+ --> tests/ui/ptr_unsupported.rs:6:38
|
6 | fn get_ptr_to_reference() -> *mut &C;
| ^^^^^^^
error: unsupported unique_ptr target type
- --> $DIR/ptr_unsupported.rs:7:38
+ --> tests/ui/ptr_unsupported.rs:7:38
|
7 | fn get_uniqueptr_to_ptr() -> UniquePtr<*mut C>;
| ^^^^^^^^^^^^^^^^^
error: unsupported vector element type
- --> $DIR/ptr_unsupported.rs:8:45
+ --> tests/ui/ptr_unsupported.rs:8:45
|
8 | fn get_vector_of_ptr() -> UniquePtr<CxxVector<*mut C>>;
- | ^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/raw_ident_namespace.rs b/tests/ui/raw_ident_namespace.rs
new file mode 100644
index 00000000..2c8286c7
--- /dev/null
+++ b/tests/ui/raw_ident_namespace.rs
@@ -0,0 +1,53 @@
+use cxx::{type_id, ExternType};
+
+#[repr(transparent)]
+pub struct QuotedRaw(usize);
+
+unsafe impl ExternType for QuotedRaw {
+ type Id = type_id!("org::r#box::implementation::QuotedRaw");
+ type Kind = cxx::kind::Trivial;
+}
+
+#[repr(transparent)]
+pub struct QuotedKeyword(usize);
+
+unsafe impl ExternType for QuotedKeyword {
+ type Id = type_id!("org::box::implementation::QuotedKeyword");
+ type Kind = cxx::kind::Trivial;
+}
+
+#[repr(transparent)]
+pub struct UnquotedRaw(usize);
+
+unsafe impl ExternType for UnquotedRaw {
+ type Id = type_id!(org::r#box::implementation::UnquotedRaw);
+ type Kind = cxx::kind::Trivial;
+}
+
+#[repr(transparent)]
+pub struct UnquotedKeyword(usize);
+
+unsafe impl ExternType for UnquotedKeyword {
+ type Id = type_id!(org::box::implementation::UnquotedKeyword);
+ type Kind = cxx::kind::Trivial;
+}
+
+#[cxx::bridge]
+pub mod ffi {
+ extern "C++" {
+ #[namespace = "org::r#box::implementation"]
+ type QuotedRaw = crate::QuotedRaw;
+
+ #[namespace = "org::box::implementation"]
+ type QuotedKeyword = crate::QuotedKeyword;
+
+ #[namespace = org::r#box::implementation]
+ type UnquotedRaw = crate::UnquotedRaw;
+
+ // Not allowed by rustc (independent of cxx):
+ // #[namespace = org::box::implementation]
+ // type UnquotedKeyword = crate::UnquotedKeyword;
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/raw_ident_namespace.stderr b/tests/ui/raw_ident_namespace.stderr
new file mode 100644
index 00000000..86c8b6fd
--- /dev/null
+++ b/tests/ui/raw_ident_namespace.stderr
@@ -0,0 +1,11 @@
+error: raw identifier `r#box` is not allowed in a quoted namespace; use `box`, or remove quotes
+ --> tests/ui/raw_ident_namespace.rs:7:24
+ |
+7 | type Id = type_id!("org::r#box::implementation::QuotedRaw");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: raw identifier `r#box` is not allowed in a quoted namespace; use `box`, or remove quotes
+ --> tests/ui/raw_ident_namespace.rs:38:23
+ |
+38 | #[namespace = "org::r#box::implementation"]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/reference_to_reference.stderr b/tests/ui/reference_to_reference.stderr
index d4069c18..765e4427 100644
--- a/tests/ui/reference_to_reference.stderr
+++ b/tests/ui/reference_to_reference.stderr
@@ -1,11 +1,11 @@
error: C++ does not allow references to references
- --> $DIR/reference_to_reference.rs:5:23
+ --> tests/ui/reference_to_reference.rs:5:23
|
5 | fn repro_c(t: &&ThingC);
| ^^^^^^^^
error: C++ does not allow references to references
- --> $DIR/reference_to_reference.rs:9:23
+ --> tests/ui/reference_to_reference.rs:9:23
|
9 | fn repro_r(t: &&ThingR);
| ^^^^^^^^
diff --git a/tests/ui/reserved_lifetime.stderr b/tests/ui/reserved_lifetime.stderr
index 723572d9..e9582671 100644
--- a/tests/ui/reserved_lifetime.stderr
+++ b/tests/ui/reserved_lifetime.stderr
@@ -1,5 +1,5 @@
error[E0262]: invalid lifetime parameter name: `'static`
- --> $DIR/reserved_lifetime.rs:6:19
+ --> tests/ui/reserved_lifetime.rs:6:19
|
6 | fn logger<'static>() -> Pin<&'static Logger>;
| ^^^^^^^ 'static is a reserved lifetime name
diff --git a/tests/ui/reserved_name.stderr b/tests/ui/reserved_name.stderr
index 6684771a..7636f872 100644
--- a/tests/ui/reserved_name.stderr
+++ b/tests/ui/reserved_name.stderr
@@ -1,17 +1,17 @@
error: reserved name
- --> $DIR/reserved_name.rs:3:12
+ --> tests/ui/reserved_name.rs:3:12
|
3 | struct UniquePtr {
| ^^^^^^^^^
error: reserved name
- --> $DIR/reserved_name.rs:8:14
+ --> tests/ui/reserved_name.rs:8:14
|
8 | type Box;
| ^^^
error: reserved name
- --> $DIR/reserved_name.rs:12:14
+ --> tests/ui/reserved_name.rs:12:14
|
12 | type String;
| ^^^^^^
diff --git a/tests/ui/result_no_display.stderr b/tests/ui/result_no_display.stderr
index d0502f9b..44d4b31d 100644
--- a/tests/ui/result_no_display.stderr
+++ b/tests/ui/result_no_display.stderr
@@ -1,5 +1,5 @@
error[E0277]: `NonError` doesn't implement `std::fmt::Display`
- --> $DIR/result_no_display.rs:4:19
+ --> tests/ui/result_no_display.rs:4:19
|
4 | fn f() -> Result<()>;
| ^^^^^^^^^^ `NonError` cannot be formatted with the default formatter
diff --git a/tests/ui/root_namespace.stderr b/tests/ui/root_namespace.stderr
index a9c01a2e..b834d91a 100644
--- a/tests/ui/root_namespace.stderr
+++ b/tests/ui/root_namespace.stderr
@@ -1,5 +1,5 @@
error: expected expression, found `]`
- --> $DIR/root_namespace.rs:9:19
+ --> tests/ui/root_namespace.rs:9:19
|
9 | #[namespace = ]
| ^ expected expression
diff --git a/tests/ui/rust_pinned.stderr b/tests/ui/rust_pinned.stderr
index 8857681c..a0fc0338 100644
--- a/tests/ui/rust_pinned.stderr
+++ b/tests/ui/rust_pinned.stderr
@@ -1,17 +1,17 @@
error[E0277]: `PhantomPinned` cannot be unpinned
- --> $DIR/rust_pinned.rs:6:14
+ --> tests/ui/rust_pinned.rs:6:14
|
6 | type Pinned;
| ^^^^^^ within `Pinned`, the trait `Unpin` is not implemented for `PhantomPinned`
|
= note: consider using `Box::pin`
note: required because it appears within the type `Pinned`
- --> $DIR/rust_pinned.rs:10:12
+ --> tests/ui/rust_pinned.rs:10:12
|
10 | pub struct Pinned {
| ^^^^^^
note: required by a bound in `__AssertUnpin`
- --> $DIR/rust_pinned.rs:6:9
+ --> tests/ui/rust_pinned.rs:6:9
|
6 | type Pinned;
| ^^^^^^^^^^^^ required by this bound in `__AssertUnpin`
diff --git a/tests/ui/slice_of_type_alias.stderr b/tests/ui/slice_of_type_alias.stderr
index aff06f8d..9339da37 100644
--- a/tests/ui/slice_of_type_alias.stderr
+++ b/tests/ui/slice_of_type_alias.stderr
@@ -1,11 +1,16 @@
error[E0271]: type mismatch resolving `<ElementOpaque as ExternType>::Kind == Trivial`
- --> $DIR/slice_of_type_alias.rs:13:9
- |
-13 | type ElementOpaque = crate::ElementOpaque;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Trivial`, found enum `cxx::kind::Opaque`
- |
+ --> tests/ui/slice_of_type_alias.rs:13:14
+ |
+13 | type ElementOpaque = crate::ElementOpaque;
+ | ^^^^^^^^^^^^^ type mismatch resolving `<ElementOpaque as ExternType>::Kind == Trivial`
+ |
+note: expected this to be `Trivial`
+ --> tests/ui/slice_of_type_alias.rs:27:17
+ |
+27 | type Kind = cxx::kind::Opaque;
+ | ^^^^^^^^^^^^^^^^^
note: required by a bound in `verify_extern_kind`
- --> $DIR/extern_type.rs:186:41
- |
-186 | pub fn verify_extern_kind<T: ExternType<Kind = Kind>, Kind: self::Kind>() {}
- | ^^^^^^^^^^^ required by this bound in `verify_extern_kind`
+ --> src/extern_type.rs
+ |
+ | pub fn verify_extern_kind<T: ExternType<Kind = Kind>, Kind: self::Kind>() {}
+ | ^^^^^^^^^^^ required by this bound in `verify_extern_kind`
diff --git a/tests/ui/slice_unsupported.stderr b/tests/ui/slice_unsupported.stderr
index 2cbd26da..b781bfd4 100644
--- a/tests/ui/slice_unsupported.stderr
+++ b/tests/ui/slice_unsupported.stderr
@@ -1,11 +1,11 @@
error: unsupported &mut [T] element type: opaque C++ type is not supported yet
- --> $DIR/slice_unsupported.rs:6:17
+ --> tests/ui/slice_unsupported.rs:6:17
|
6 | fn f(_: &mut [Opaque]);
| ^^^^^^^^^^^^^
error: needs a cxx::ExternType impl in order to be used as a slice element in &mut [Opaque]
- --> $DIR/slice_unsupported.rs:4:9
+ --> tests/ui/slice_unsupported.rs:4:9
|
4 | type Opaque;
| ^^^^^^^^^^^
diff --git a/tests/ui/struct_cycle.stderr b/tests/ui/struct_cycle.stderr
index 49bcb5f6..9ee2d831 100644
--- a/tests/ui/struct_cycle.stderr
+++ b/tests/ui/struct_cycle.stderr
@@ -1,23 +1,23 @@
error: unsupported cyclic data structure
- --> $DIR/struct_cycle.rs:26:9
+ --> tests/ui/struct_cycle.rs:26:9
|
26 | node2: Node2,
| ^^^^^^^^^^^^
error: unsupported cyclic data structure
- --> $DIR/struct_cycle.rs:22:9
+ --> tests/ui/struct_cycle.rs:22:9
|
22 | node5: Node5,
| ^^^^^^^^^^^^
error: unsupported cyclic data structure
- --> $DIR/struct_cycle.rs:13:9
+ --> tests/ui/struct_cycle.rs:13:9
|
13 | node4: Node4,
| ^^^^^^^^^^^^
error: unsupported cyclic data structure
- --> $DIR/struct_cycle.rs:8:9
+ --> tests/ui/struct_cycle.rs:8:9
|
8 | node2: Node2,
| ^^^^^^^^^^^^
diff --git a/tests/ui/type_alias_rust.stderr b/tests/ui/type_alias_rust.stderr
index 1b08f67c..8cf9a56f 100644
--- a/tests/ui/type_alias_rust.stderr
+++ b/tests/ui/type_alias_rust.stderr
@@ -1,5 +1,5 @@
error: type alias in extern "Rust" block is not supported
- --> $DIR/type_alias_rust.rs:5:9
+ --> tests/ui/type_alias_rust.rs:5:9
|
5 | type Alias = crate::Type;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/unique_ptr_as_mut.stderr b/tests/ui/unique_ptr_as_mut.stderr
index a41f716a..a8248dbe 100644
--- a/tests/ui/unique_ptr_as_mut.stderr
+++ b/tests/ui/unique_ptr_as_mut.stderr
@@ -1,5 +1,5 @@
-error[E0596]: cannot borrow data in a dereference of `UniquePtr<ffi::Opaque>` as mutable
- --> $DIR/unique_ptr_as_mut.rs:22:31
+error[E0596]: cannot borrow data in dereference of `UniquePtr<ffi::Opaque>` as mutable
+ --> tests/ui/unique_ptr_as_mut.rs:22:31
|
22 | let _: &mut ffi::Opaque = &mut opaque;
| ^^^^^^^^^^^ cannot borrow as mutable
diff --git a/tests/ui/unique_ptr_to_opaque.stderr b/tests/ui/unique_ptr_to_opaque.stderr
index 28e45cf5..6f028f5a 100644
--- a/tests/ui/unique_ptr_to_opaque.stderr
+++ b/tests/ui/unique_ptr_to_opaque.stderr
@@ -1,13 +1,18 @@
error[E0271]: type mismatch resolving `<outside::C as ExternType>::Kind == Trivial`
- --> $DIR/unique_ptr_to_opaque.rs:22:5
+ --> tests/ui/unique_ptr_to_opaque.rs:22:25
|
22 | cxx::UniquePtr::new(outside::C { a: 4 });
- | ^^^^^^^^^^^^^^^^^^^ expected enum `Trivial`, found enum `cxx::kind::Opaque`
+ | ------------------- ^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<outside::C as ExternType>::Kind == Trivial`
+ | |
+ | required by a bound introduced by this call
|
-note: required by `UniquePtr::<T>::new`
- --> $DIR/unique_ptr.rs:38:5
+note: expected this to be `Trivial`
+ --> tests/ui/unique_ptr_to_opaque.rs:8:21
|
-38 | / pub fn new(value: T) -> Self
-39 | | where
-40 | | T: ExternType<Kind = Trivial>,
- | |______________________________________^
+8 | type Kind = cxx::kind::Opaque;
+ | ^^^^^^^^^^^^^^^^^
+note: required by a bound in `UniquePtr::<T>::new`
+ --> src/unique_ptr.rs
+ |
+ | T: ExternType<Kind = Trivial>,
+ | ^^^^^^^^^^^^^^ required by this bound in `UniquePtr::<T>::new`
diff --git a/tests/ui/unique_ptr_twice.stderr b/tests/ui/unique_ptr_twice.stderr
index ee26b646..b21791fb 100644
--- a/tests/ui/unique_ptr_twice.stderr
+++ b/tests/ui/unique_ptr_twice.stderr
@@ -1,8 +1,8 @@
-error[E0119]: conflicting implementations of trait `cxx::memory::UniquePtrTarget` for type `here::C`
- --> $DIR/unique_ptr_twice.rs:16:5
+error[E0119]: conflicting implementations of trait `UniquePtrTarget` for type `here::C`
+ --> tests/ui/unique_ptr_twice.rs:16:5
|
7 | impl UniquePtr<C> {}
- | ----------------- first implementation here
+ | ---------------- first implementation here
...
16 | impl UniquePtr<C> {}
- | ^^^^^^^^^^^^^^^^^ conflicting implementation for `here::C`
+ | ^^^^^^^^^^^^^^^^ conflicting implementation for `here::C`
diff --git a/tests/ui/unnamed_receiver.stderr b/tests/ui/unnamed_receiver.stderr
index e66d9e3c..d903b231 100644
--- a/tests/ui/unnamed_receiver.stderr
+++ b/tests/ui/unnamed_receiver.stderr
@@ -1,11 +1,11 @@
error: unnamed receiver type is only allowed if the surrounding extern block contains exactly one extern type; use `self: &mut TheType`
- --> $DIR/unnamed_receiver.rs:6:14
+ --> tests/ui/unnamed_receiver.rs:6:14
|
6 | fn f(&mut self);
| ^^^^^^^^^
error: unnamed receiver type is only allowed if the surrounding extern block contains exactly one extern type; use `self: &TheType`
- --> $DIR/unnamed_receiver.rs:10:20
+ --> tests/ui/unnamed_receiver.rs:10:20
|
10 | fn f(self: &Self);
| ^^^^^
diff --git a/tests/ui/unpin_impl.stderr b/tests/ui/unpin_impl.stderr
index 01ee19c1..18099bb6 100644
--- a/tests/ui/unpin_impl.stderr
+++ b/tests/ui/unpin_impl.stderr
@@ -1,8 +1,20 @@
-error[E0282]: type annotations needed for `fn()`
- --> $DIR/unpin_impl.rs:4:14
+error[E0282]: type annotations needed
+ --> tests/ui/unpin_impl.rs:1:1
|
1 | #[cxx::bridge]
- | -------------- consider giving this pattern the explicit type `fn()`, with the type parameters specified
-...
-4 | type Opaque;
- | ^^^^^^ cannot infer type
+ | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `__AmbiguousIfImpl`
+ |
+ = note: this error originates in the attribute macro `cxx::bridge` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0283]: type annotations needed
+ --> tests/ui/unpin_impl.rs:1:1
+ |
+1 | #[cxx::bridge]
+ | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `__AmbiguousIfImpl`
+ |
+note: multiple `impl`s satisfying `ffi::Opaque: __AmbiguousIfImpl<_>` found
+ --> tests/ui/unpin_impl.rs:1:1
+ |
+1 | #[cxx::bridge]
+ | ^^^^^^^^^^^^^^
+ = note: this error originates in the attribute macro `cxx::bridge` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/unrecognized_receiver.stderr b/tests/ui/unrecognized_receiver.stderr
index a44bec1a..bc645fec 100644
--- a/tests/ui/unrecognized_receiver.stderr
+++ b/tests/ui/unrecognized_receiver.stderr
@@ -1,5 +1,5 @@
error: unrecognized receiver type
- --> $DIR/unrecognized_receiver.rs:4:20
+ --> tests/ui/unrecognized_receiver.rs:4:20
|
4 | fn f(self: &Unrecognized);
| ^^^^^^^^^^^^^
diff --git a/tests/ui/unsupported_elided.stderr b/tests/ui/unsupported_elided.stderr
index 8e8a986b..6926b824 100644
--- a/tests/ui/unsupported_elided.stderr
+++ b/tests/ui/unsupported_elided.stderr
@@ -1,13 +1,17 @@
error[E0726]: implicit elided lifetime not allowed here
- --> $DIR/unsupported_elided.rs:6:14
+ --> tests/ui/unsupported_elided.rs:6:14
|
6 | type T;
- | ^- help: indicate the anonymous lifetime: `<'_>`
+ | ^ expected lifetime parameter
|
= note: assuming a `'static` lifetime...
+help: indicate the anonymous lifetime
+ |
+6 | type T<'_>;
+ | ++++
error[E0106]: missing lifetime specifier
- --> $DIR/unsupported_elided.rs:8:24
+ --> tests/ui/unsupported_elided.rs:8:24
|
8 | fn f(t: &T) -> &str;
| -- ^ expected named lifetime parameter
@@ -15,5 +19,5 @@ error[E0106]: missing lifetime specifier
= 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
help: consider introducing a named lifetime parameter
|
-8 | fn f<'a>(t: &'a T) -> &'a str;
- | ++++ ++ ++
+8 | fn f<'a>(t: &'a T<'a>) -> &'a str;
+ | ++++ ++ ++++ ++
diff --git a/tests/ui/vec_opaque.stderr b/tests/ui/vec_opaque.stderr
index 3f208fec..cd038e66 100644
--- a/tests/ui/vec_opaque.stderr
+++ b/tests/ui/vec_opaque.stderr
@@ -1,23 +1,23 @@
error: Rust Vec containing C++ type is not supported yet
- --> $DIR/vec_opaque.rs:15:19
+ --> tests/ui/vec_opaque.rs:15:19
|
15 | fn f() -> Vec<Job>;
| ^^^^^^^^
error: needs a cxx::ExternType impl in order to be used as a vector element in Vec<Job>
- --> $DIR/vec_opaque.rs:11:9
+ --> tests/ui/vec_opaque.rs:11:9
|
11 | type Job;
| ^^^^^^^^
error[E0271]: type mismatch resolving `<handle::Job as ExternType>::Kind == Trivial`
- --> $DIR/vec_opaque.rs:22:9
- |
-22 | type Job = crate::handle::Job;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Trivial`, found enum `cxx::kind::Opaque`
- |
+ --> tests/ui/vec_opaque.rs:22:14
+ |
+22 | type Job = crate::handle::Job;
+ | ^^^ expected enum `Trivial`, found enum `Opaque`
+ |
note: required by a bound in `verify_extern_kind`
- --> $DIR/extern_type.rs:186:41
- |
-186 | pub fn verify_extern_kind<T: ExternType<Kind = Kind>, Kind: self::Kind>() {}
- | ^^^^^^^^^^^ required by this bound in `verify_extern_kind`
+ --> src/extern_type.rs
+ |
+ | pub fn verify_extern_kind<T: ExternType<Kind = Kind>, Kind: self::Kind>() {}
+ | ^^^^^^^^^^^ required by this bound in `verify_extern_kind`
diff --git a/tests/ui/vector_autotraits.stderr b/tests/ui/vector_autotraits.stderr
index 52fd2a41..d8559d00 100644
--- a/tests/ui/vector_autotraits.stderr
+++ b/tests/ui/vector_autotraits.stderr
@@ -1,14 +1,14 @@
error[E0277]: `*const cxx::void` cannot be sent between threads safely
- --> $DIR/vector_autotraits.rs:20:5
+ --> tests/ui/vector_autotraits.rs:20:19
|
20 | assert_send::<CxxVector<ffi::NotThreadSafe>>();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const cxx::void` cannot be sent between threads safely
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const cxx::void` cannot be sent between threads safely
|
= help: within `CxxVector<NotThreadSafe>`, the trait `Send` is not implemented for `*const cxx::void`
= note: required because it appears within the type `[*const cxx::void; 0]`
= note: required because it appears within the type `cxx::private::Opaque`
note: required because it appears within the type `NotThreadSafe`
- --> $DIR/vector_autotraits.rs:7:14
+ --> tests/ui/vector_autotraits.rs:7:14
|
7 | type NotThreadSafe;
| ^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ note: required because it appears within the type `NotThreadSafe`
= note: required because it appears within the type `PhantomData<[NotThreadSafe]>`
= note: required because it appears within the type `CxxVector<NotThreadSafe>`
note: required by a bound in `assert_send`
- --> $DIR/vector_autotraits.rs:16:19
+ --> tests/ui/vector_autotraits.rs:16:19
|
16 | fn assert_send<T: Send>() {}
| ^^^^ required by this bound in `assert_send`
diff --git a/tests/ui/wrong_type_id.stderr b/tests/ui/wrong_type_id.stderr
index b66bb266..8cb78980 100644
--- a/tests/ui/wrong_type_id.stderr
+++ b/tests/ui/wrong_type_id.stderr
@@ -1,13 +1,13 @@
error[E0271]: type mismatch resolving `<StringPiece as ExternType>::Id == (f, o, l, l, y, (), B, y, t, e, R, a, n, g, e)`
- --> $DIR/wrong_type_id.rs:11:9
- |
-11 | type ByteRange = crate::here::StringPiece;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected a tuple with 15 elements, found one with 17 elements
- |
- = note: expected tuple `(f, o, l, l, y, (), B, y, t, e, R, a, n, g, e)`
- found tuple `(f, o, l, l, y, (), S, t, r, i, n, g, P, i, e, c, e)`
+ --> tests/ui/wrong_type_id.rs:11:14
+ |
+11 | type ByteRange = crate::here::StringPiece;
+ | ^^^^^^^^^ expected a tuple with 15 elements, found one with 17 elements
+ |
+ = note: expected tuple `(f, o, l, l, y, (), B, y, t, e, R, a, n, g, e)`
+ found tuple `(f, o, l, l, y, (), S, t, r, i, n, g, P, i, e, c, e)`
note: required by a bound in `verify_extern_type`
- --> $DIR/extern_type.rs:183:41
- |
-183 | pub fn verify_extern_type<T: ExternType<Id = Id>, Id>() {}
- | ^^^^^^^ required by this bound in `verify_extern_type`
+ --> src/extern_type.rs
+ |
+ | pub fn verify_extern_type<T: ExternType<Id = Id>, Id>() {}
+ | ^^^^^^^ required by this bound in `verify_extern_type`
diff --git a/third-party/.gitignore b/third-party/.gitignore
index 61ead866..b0509488 100644
--- a/third-party/.gitignore
+++ b/third-party/.gitignore
@@ -1 +1,2 @@
+/.cargo
/vendor
diff --git a/third-party/BUCK b/third-party/BUCK
index 2633da87..8036117e 100644
--- a/third-party/BUCK
+++ b/third-party/BUCK
@@ -1,110 +1,540 @@
-# To be generated by Facebook's `reindeer` tool once that is open source.
+# @generated by `reindeer buckify`
-load("//tools/buck:rust_library.bzl", "rust_library")
+load("//tools/buck:buildscript.bzl", "buildscript_args")
rust_library(
- name = "bitflags",
- srcs = glob(["vendor/bitflags-1.3.2/src/**"]),
+ name = "bitflags-1.3.2",
+ srcs = [
+ "vendor/bitflags-1.3.2/src/example_generated.rs",
+ "vendor/bitflags-1.3.2/src/lib.rs",
+ ],
+ crate = "bitflags",
+ crate_root = "vendor/bitflags-1.3.2/src/lib.rs",
+ edition = "2018",
+ features = ["default"],
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
)
-rust_library(
+alias(
name = "cc",
- srcs = glob(["vendor/cc-1.0.69/src/**"]),
+ actual = ":cc-1.0.77",
visibility = ["PUBLIC"],
)
rust_library(
+ name = "cc-1.0.77",
+ srcs = [
+ "vendor/cc-1.0.77/src/com.rs",
+ "vendor/cc-1.0.77/src/lib.rs",
+ "vendor/cc-1.0.77/src/registry.rs",
+ "vendor/cc-1.0.77/src/setup_config.rs",
+ "vendor/cc-1.0.77/src/vs_instances.rs",
+ "vendor/cc-1.0.77/src/winapi.rs",
+ "vendor/cc-1.0.77/src/windows_registry.rs",
+ ],
+ crate = "cc",
+ crate_root = "vendor/cc-1.0.77/src/lib.rs",
+ edition = "2018",
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
+)
+
+alias(
name = "clap",
- srcs = glob(["vendor/clap-2.33.3/src/**"]),
- edition = "2015",
+ actual = ":clap-4.0.29",
visibility = ["PUBLIC"],
+)
+
+rust_library(
+ name = "clap-4.0.29",
+ srcs = [
+ "vendor/clap-4.0.29/examples/demo.md",
+ "vendor/clap-4.0.29/examples/demo.rs",
+ "vendor/clap-4.0.29/src/_cookbook/cargo_example.rs",
+ "vendor/clap-4.0.29/src/_cookbook/cargo_example_derive.rs",
+ "vendor/clap-4.0.29/src/_cookbook/escaped_positional.rs",
+ "vendor/clap-4.0.29/src/_cookbook/escaped_positional_derive.rs",
+ "vendor/clap-4.0.29/src/_cookbook/find.rs",
+ "vendor/clap-4.0.29/src/_cookbook/git.rs",
+ "vendor/clap-4.0.29/src/_cookbook/git_derive.rs",
+ "vendor/clap-4.0.29/src/_cookbook/mod.rs",
+ "vendor/clap-4.0.29/src/_cookbook/multicall_busybox.rs",
+ "vendor/clap-4.0.29/src/_cookbook/multicall_hostname.rs",
+ "vendor/clap-4.0.29/src/_cookbook/pacman.rs",
+ "vendor/clap-4.0.29/src/_cookbook/repl.rs",
+ "vendor/clap-4.0.29/src/_cookbook/typed_derive.rs",
+ "vendor/clap-4.0.29/src/_derive/_tutorial.rs",
+ "vendor/clap-4.0.29/src/_derive/mod.rs",
+ "vendor/clap-4.0.29/src/_faq.rs",
+ "vendor/clap-4.0.29/src/_features.rs",
+ "vendor/clap-4.0.29/src/_tutorial.rs",
+ "vendor/clap-4.0.29/src/builder/action.rs",
+ "vendor/clap-4.0.29/src/builder/app_settings.rs",
+ "vendor/clap-4.0.29/src/builder/arg.rs",
+ "vendor/clap-4.0.29/src/builder/arg_group.rs",
+ "vendor/clap-4.0.29/src/builder/arg_predicate.rs",
+ "vendor/clap-4.0.29/src/builder/arg_settings.rs",
+ "vendor/clap-4.0.29/src/builder/command.rs",
+ "vendor/clap-4.0.29/src/builder/debug_asserts.rs",
+ "vendor/clap-4.0.29/src/builder/mod.rs",
+ "vendor/clap-4.0.29/src/builder/os_str.rs",
+ "vendor/clap-4.0.29/src/builder/possible_value.rs",
+ "vendor/clap-4.0.29/src/builder/range.rs",
+ "vendor/clap-4.0.29/src/builder/resettable.rs",
+ "vendor/clap-4.0.29/src/builder/str.rs",
+ "vendor/clap-4.0.29/src/builder/styled_str.rs",
+ "vendor/clap-4.0.29/src/builder/tests.rs",
+ "vendor/clap-4.0.29/src/builder/value_hint.rs",
+ "vendor/clap-4.0.29/src/builder/value_parser.rs",
+ "vendor/clap-4.0.29/src/derive.rs",
+ "vendor/clap-4.0.29/src/error/context.rs",
+ "vendor/clap-4.0.29/src/error/format.rs",
+ "vendor/clap-4.0.29/src/error/kind.rs",
+ "vendor/clap-4.0.29/src/error/mod.rs",
+ "vendor/clap-4.0.29/src/lib.rs",
+ "vendor/clap-4.0.29/src/macros.rs",
+ "vendor/clap-4.0.29/src/mkeymap.rs",
+ "vendor/clap-4.0.29/src/output/fmt.rs",
+ "vendor/clap-4.0.29/src/output/help.rs",
+ "vendor/clap-4.0.29/src/output/help_template.rs",
+ "vendor/clap-4.0.29/src/output/mod.rs",
+ "vendor/clap-4.0.29/src/output/textwrap/core.rs",
+ "vendor/clap-4.0.29/src/output/textwrap/mod.rs",
+ "vendor/clap-4.0.29/src/output/textwrap/word_separators.rs",
+ "vendor/clap-4.0.29/src/output/textwrap/wrap_algorithms.rs",
+ "vendor/clap-4.0.29/src/output/usage.rs",
+ "vendor/clap-4.0.29/src/parser/arg_matcher.rs",
+ "vendor/clap-4.0.29/src/parser/error.rs",
+ "vendor/clap-4.0.29/src/parser/features/mod.rs",
+ "vendor/clap-4.0.29/src/parser/features/suggestions.rs",
+ "vendor/clap-4.0.29/src/parser/matches/any_value.rs",
+ "vendor/clap-4.0.29/src/parser/matches/arg_matches.rs",
+ "vendor/clap-4.0.29/src/parser/matches/matched_arg.rs",
+ "vendor/clap-4.0.29/src/parser/matches/mod.rs",
+ "vendor/clap-4.0.29/src/parser/matches/value_source.rs",
+ "vendor/clap-4.0.29/src/parser/mod.rs",
+ "vendor/clap-4.0.29/src/parser/parser.rs",
+ "vendor/clap-4.0.29/src/parser/validator.rs",
+ "vendor/clap-4.0.29/src/util/color.rs",
+ "vendor/clap-4.0.29/src/util/flat_map.rs",
+ "vendor/clap-4.0.29/src/util/flat_set.rs",
+ "vendor/clap-4.0.29/src/util/graph.rs",
+ "vendor/clap-4.0.29/src/util/id.rs",
+ "vendor/clap-4.0.29/src/util/mod.rs",
+ "vendor/clap-4.0.29/src/util/str_to_bool.rs",
+ ],
+ crate = "clap",
+ crate_root = "vendor/clap-4.0.29/src/lib.rs",
+ edition = "2021",
+ features = [
+ "error-context",
+ "help",
+ "std",
+ "usage",
+ ],
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
deps = [
- ":bitflags",
- ":textwrap",
- ":unicode-width",
+ ":bitflags-1.3.2",
+ ":clap_lex-0.3.0",
],
)
rust_library(
+ name = "clap_lex-0.3.0",
+ srcs = ["vendor/clap_lex-0.3.0/src/lib.rs"],
+ crate = "clap_lex",
+ crate_root = "vendor/clap_lex-0.3.0/src/lib.rs",
+ edition = "2021",
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
+ deps = [":os_str_bytes-6.4.1"],
+)
+
+alias(
name = "codespan-reporting",
- srcs = glob(["vendor/codespan-reporting-0.11.1/src/**"]),
+ actual = ":codespan-reporting-0.11.1",
visibility = ["PUBLIC"],
+)
+
+rust_library(
+ name = "codespan-reporting-0.11.1",
+ srcs = [
+ "vendor/codespan-reporting-0.11.1/src/diagnostic.rs",
+ "vendor/codespan-reporting-0.11.1/src/files.rs",
+ "vendor/codespan-reporting-0.11.1/src/lib.rs",
+ "vendor/codespan-reporting-0.11.1/src/term.rs",
+ "vendor/codespan-reporting-0.11.1/src/term/config.rs",
+ "vendor/codespan-reporting-0.11.1/src/term/renderer.rs",
+ "vendor/codespan-reporting-0.11.1/src/term/views.rs",
+ ],
+ crate = "codespan_reporting",
+ crate_root = "vendor/codespan-reporting-0.11.1/src/lib.rs",
+ edition = "2018",
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
deps = [
- ":termcolor",
- ":unicode-width",
+ ":termcolor-1.1.3",
+ ":unicode-width-0.1.10",
],
)
-rust_library(
- name = "lazy_static",
- srcs = glob(["vendor/lazy_static-1.4.0/src/**"]),
+alias(
+ name = "once_cell",
+ actual = ":once_cell-1.16.0",
visibility = ["PUBLIC"],
)
rust_library(
+ name = "once_cell-1.16.0",
+ srcs = [
+ "vendor/once_cell-1.16.0/src/imp_cs.rs",
+ "vendor/once_cell-1.16.0/src/imp_pl.rs",
+ "vendor/once_cell-1.16.0/src/imp_std.rs",
+ "vendor/once_cell-1.16.0/src/lib.rs",
+ "vendor/once_cell-1.16.0/src/race.rs",
+ ],
+ crate = "once_cell",
+ crate_root = "vendor/once_cell-1.16.0/src/lib.rs",
+ edition = "2021",
+ features = [
+ "alloc",
+ "default",
+ "race",
+ "std",
+ ],
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
+)
+
+rust_library(
+ name = "os_str_bytes-6.4.1",
+ srcs = [
+ "vendor/os_str_bytes-6.4.1/src/common/mod.rs",
+ "vendor/os_str_bytes-6.4.1/src/common/raw.rs",
+ "vendor/os_str_bytes-6.4.1/src/iter.rs",
+ "vendor/os_str_bytes-6.4.1/src/lib.rs",
+ "vendor/os_str_bytes-6.4.1/src/pattern.rs",
+ "vendor/os_str_bytes-6.4.1/src/raw_str.rs",
+ "vendor/os_str_bytes-6.4.1/src/util.rs",
+ "vendor/os_str_bytes-6.4.1/src/wasm/mod.rs",
+ "vendor/os_str_bytes-6.4.1/src/wasm/raw.rs",
+ "vendor/os_str_bytes-6.4.1/src/windows/mod.rs",
+ "vendor/os_str_bytes-6.4.1/src/windows/raw.rs",
+ "vendor/os_str_bytes-6.4.1/src/windows/wtf8/code_points.rs",
+ "vendor/os_str_bytes-6.4.1/src/windows/wtf8/convert.rs",
+ "vendor/os_str_bytes-6.4.1/src/windows/wtf8/mod.rs",
+ "vendor/os_str_bytes-6.4.1/src/windows/wtf8/string.rs",
+ ],
+ crate = "os_str_bytes",
+ crate_root = "vendor/os_str_bytes-6.4.1/src/lib.rs",
+ edition = "2021",
+ features = ["raw_os_str"],
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
+)
+
+alias(
name = "proc-macro2",
- srcs = glob(["vendor/proc-macro2-1.0.28/src/**"]),
- build_script = "vendor/proc-macro2-1.0.28/build.rs",
+ actual = ":proc-macro2-1.0.47",
+ visibility = ["PUBLIC"],
+)
+
+rust_library(
+ name = "proc-macro2-1.0.47",
+ srcs = [
+ "vendor/proc-macro2-1.0.47/src/detection.rs",
+ "vendor/proc-macro2-1.0.47/src/fallback.rs",
+ "vendor/proc-macro2-1.0.47/src/lib.rs",
+ "vendor/proc-macro2-1.0.47/src/marker.rs",
+ "vendor/proc-macro2-1.0.47/src/parse.rs",
+ "vendor/proc-macro2-1.0.47/src/rcvec.rs",
+ "vendor/proc-macro2-1.0.47/src/wrapper.rs",
+ ],
+ crate = "proc_macro2",
+ crate_root = "vendor/proc-macro2-1.0.47/src/lib.rs",
+ edition = "2018",
features = [
+ "default",
"proc-macro",
"span-locations",
],
- visibility = ["PUBLIC"],
- deps = [":unicode-xid"],
+ rustc_flags = [
+ "--cap-lints=allow",
+ "@$(location :proc-macro2-1.0.47-build-script-build-args)",
+ ],
+ visibility = [],
+ deps = [":unicode-ident-1.0.5"],
)
-rust_library(
+rust_binary(
+ name = "proc-macro2-1.0.47-build-script-build",
+ srcs = ["vendor/proc-macro2-1.0.47/build.rs"],
+ crate = "build_script_build",
+ crate_root = "vendor/proc-macro2-1.0.47/build.rs",
+ edition = "2018",
+ features = [
+ "default",
+ "proc-macro",
+ "span-locations",
+ ],
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
+)
+
+buildscript_args(
+ name = "proc-macro2-1.0.47-build-script-build-args",
+ package_name = "proc-macro2",
+ buildscript_rule = ":proc-macro2-1.0.47-build-script-build",
+ cfgs = [],
+ features = [
+ "default",
+ "proc-macro",
+ "span-locations",
+ ],
+ outfile = "args.txt",
+ version = "1.0.47",
+)
+
+alias(
name = "quote",
- srcs = glob(["vendor/quote-1.0.9/src/**"]),
- features = ["proc-macro"],
+ actual = ":quote-1.0.21",
visibility = ["PUBLIC"],
- deps = [":proc-macro2"],
)
rust_library(
+ name = "quote-1.0.21",
+ srcs = [
+ "vendor/quote-1.0.21/src/ext.rs",
+ "vendor/quote-1.0.21/src/format.rs",
+ "vendor/quote-1.0.21/src/ident_fragment.rs",
+ "vendor/quote-1.0.21/src/lib.rs",
+ "vendor/quote-1.0.21/src/runtime.rs",
+ "vendor/quote-1.0.21/src/spanned.rs",
+ "vendor/quote-1.0.21/src/to_tokens.rs",
+ ],
+ crate = "quote",
+ crate_root = "vendor/quote-1.0.21/src/lib.rs",
+ edition = "2018",
+ features = [
+ "default",
+ "proc-macro",
+ ],
+ rustc_flags = [
+ "--cap-lints=allow",
+ "@$(location :quote-1.0.21-build-script-build-args)",
+ ],
+ visibility = [],
+ deps = [":proc-macro2-1.0.47"],
+)
+
+rust_binary(
+ name = "quote-1.0.21-build-script-build",
+ srcs = ["vendor/quote-1.0.21/build.rs"],
+ crate = "build_script_build",
+ crate_root = "vendor/quote-1.0.21/build.rs",
+ edition = "2018",
+ features = [
+ "default",
+ "proc-macro",
+ ],
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
+)
+
+buildscript_args(
+ name = "quote-1.0.21-build-script-build-args",
+ package_name = "quote",
+ buildscript_rule = ":quote-1.0.21-build-script-build",
+ cfgs = [],
+ features = [
+ "default",
+ "proc-macro",
+ ],
+ outfile = "args.txt",
+ version = "1.0.21",
+)
+
+alias(
name = "scratch",
- srcs = glob(["vendor/scratch-1.0.0/src/**"]),
- env = {"OUT_DIR": ""},
+ actual = ":scratch-1.0.2",
visibility = ["PUBLIC"],
)
rust_library(
+ name = "scratch-1.0.2",
+ srcs = ["vendor/scratch-1.0.2/src/lib.rs"],
+ crate = "scratch",
+ crate_root = "vendor/scratch-1.0.2/src/lib.rs",
+ edition = "2015",
+ env = {
+ "OUT_DIR": "generated",
+ },
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
+)
+
+alias(
name = "syn",
- srcs = glob(["vendor/syn-1.0.75/src/**"]),
- build_script = "vendor/syn-1.0.75/build.rs",
+ actual = ":syn-1.0.105",
+ visibility = ["PUBLIC"],
+)
+
+rust_library(
+ name = "syn-1.0.105",
+ srcs = [
+ "vendor/syn-1.0.105/src/attr.rs",
+ "vendor/syn-1.0.105/src/await.rs",
+ "vendor/syn-1.0.105/src/bigint.rs",
+ "vendor/syn-1.0.105/src/buffer.rs",
+ "vendor/syn-1.0.105/src/custom_keyword.rs",
+ "vendor/syn-1.0.105/src/custom_punctuation.rs",
+ "vendor/syn-1.0.105/src/data.rs",
+ "vendor/syn-1.0.105/src/derive.rs",
+ "vendor/syn-1.0.105/src/discouraged.rs",
+ "vendor/syn-1.0.105/src/drops.rs",
+ "vendor/syn-1.0.105/src/error.rs",
+ "vendor/syn-1.0.105/src/export.rs",
+ "vendor/syn-1.0.105/src/expr.rs",
+ "vendor/syn-1.0.105/src/ext.rs",
+ "vendor/syn-1.0.105/src/file.rs",
+ "vendor/syn-1.0.105/src/gen/clone.rs",
+ "vendor/syn-1.0.105/src/gen/debug.rs",
+ "vendor/syn-1.0.105/src/gen/eq.rs",
+ "vendor/syn-1.0.105/src/gen/fold.rs",
+ "vendor/syn-1.0.105/src/gen/hash.rs",
+ "vendor/syn-1.0.105/src/gen/visit.rs",
+ "vendor/syn-1.0.105/src/gen/visit_mut.rs",
+ "vendor/syn-1.0.105/src/gen_helper.rs",
+ "vendor/syn-1.0.105/src/generics.rs",
+ "vendor/syn-1.0.105/src/group.rs",
+ "vendor/syn-1.0.105/src/ident.rs",
+ "vendor/syn-1.0.105/src/item.rs",
+ "vendor/syn-1.0.105/src/lib.rs",
+ "vendor/syn-1.0.105/src/lifetime.rs",
+ "vendor/syn-1.0.105/src/lit.rs",
+ "vendor/syn-1.0.105/src/lookahead.rs",
+ "vendor/syn-1.0.105/src/mac.rs",
+ "vendor/syn-1.0.105/src/macros.rs",
+ "vendor/syn-1.0.105/src/op.rs",
+ "vendor/syn-1.0.105/src/parse.rs",
+ "vendor/syn-1.0.105/src/parse_macro_input.rs",
+ "vendor/syn-1.0.105/src/parse_quote.rs",
+ "vendor/syn-1.0.105/src/pat.rs",
+ "vendor/syn-1.0.105/src/path.rs",
+ "vendor/syn-1.0.105/src/print.rs",
+ "vendor/syn-1.0.105/src/punctuated.rs",
+ "vendor/syn-1.0.105/src/reserved.rs",
+ "vendor/syn-1.0.105/src/sealed.rs",
+ "vendor/syn-1.0.105/src/span.rs",
+ "vendor/syn-1.0.105/src/spanned.rs",
+ "vendor/syn-1.0.105/src/stmt.rs",
+ "vendor/syn-1.0.105/src/thread.rs",
+ "vendor/syn-1.0.105/src/token.rs",
+ "vendor/syn-1.0.105/src/tt.rs",
+ "vendor/syn-1.0.105/src/ty.rs",
+ "vendor/syn-1.0.105/src/verbatim.rs",
+ "vendor/syn-1.0.105/src/whitespace.rs",
+ ],
+ crate = "syn",
+ crate_root = "vendor/syn-1.0.105/src/lib.rs",
+ edition = "2018",
features = [
"clone-impls",
+ "default",
"derive",
"full",
"parsing",
"printing",
"proc-macro",
+ "quote",
],
- visibility = ["PUBLIC"],
+ rustc_flags = [
+ "--cap-lints=allow",
+ "@$(location :syn-1.0.105-build-script-build-args)",
+ ],
+ visibility = [],
deps = [
- ":proc-macro2",
- ":quote",
- ":unicode-xid",
+ ":proc-macro2-1.0.47",
+ ":quote-1.0.21",
+ ":unicode-ident-1.0.5",
],
)
-rust_library(
- name = "termcolor",
- srcs = glob(["vendor/termcolor-1.1.2/src/**"]),
+rust_binary(
+ name = "syn-1.0.105-build-script-build",
+ srcs = ["vendor/syn-1.0.105/build.rs"],
+ crate = "build_script_build",
+ crate_root = "vendor/syn-1.0.105/build.rs",
+ edition = "2018",
+ features = [
+ "clone-impls",
+ "default",
+ "derive",
+ "full",
+ "parsing",
+ "printing",
+ "proc-macro",
+ "quote",
+ ],
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
+)
+
+buildscript_args(
+ name = "syn-1.0.105-build-script-build-args",
+ package_name = "syn",
+ buildscript_rule = ":syn-1.0.105-build-script-build",
+ cfgs = [],
+ features = [
+ "clone-impls",
+ "default",
+ "derive",
+ "full",
+ "parsing",
+ "printing",
+ "proc-macro",
+ "quote",
+ ],
+ outfile = "args.txt",
+ version = "1.0.105",
)
rust_library(
- name = "textwrap",
- srcs = glob(["vendor/textwrap-0.11.0/src/**"]),
- deps = [":unicode-width"],
+ name = "termcolor-1.1.3",
+ srcs = ["vendor/termcolor-1.1.3/src/lib.rs"],
+ crate = "termcolor",
+ crate_root = "vendor/termcolor-1.1.3/src/lib.rs",
+ edition = "2018",
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
)
rust_library(
- name = "unicode-width",
- srcs = glob(["vendor/unicode-width-0.1.8/src/**"]),
+ name = "unicode-ident-1.0.5",
+ srcs = [
+ "vendor/unicode-ident-1.0.5/src/lib.rs",
+ "vendor/unicode-ident-1.0.5/src/tables.rs",
+ ],
+ crate = "unicode_ident",
+ crate_root = "vendor/unicode-ident-1.0.5/src/lib.rs",
+ edition = "2018",
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
)
rust_library(
- name = "unicode-xid",
- srcs = glob(["vendor/unicode-xid-0.2.2/src/**"]),
+ name = "unicode-width-0.1.10",
+ srcs = [
+ "vendor/unicode-width-0.1.10/src/lib.rs",
+ "vendor/unicode-width-0.1.10/src/tables.rs",
+ "vendor/unicode-width-0.1.10/src/tests.rs",
+ ],
+ crate = "unicode_width",
+ crate_root = "vendor/unicode-width-0.1.10/src/lib.rs",
+ edition = "2015",
+ features = ["default"],
+ rustc_flags = ["--cap-lints=allow"],
+ visibility = [],
)
diff --git a/third-party/BUILD b/third-party/BUILD
index 1760b707..1b599321 100644
--- a/third-party/BUILD
+++ b/third-party/BUILD
@@ -7,30 +7,48 @@ load(
rust_library(
name = "bitflags",
- srcs = glob(["vendor/bitflags-1.3.2/src/**"]),
+ srcs = glob(["vendor/bitflags-1.3.2/src/**/*.rs"]),
+ edition = "2018",
)
rust_library(
name = "cc",
- srcs = glob(["vendor/cc-1.0.69/src/**"]),
+ srcs = glob(["vendor/cc-1.0.77/src/**/*.rs"]),
+ edition = "2018",
visibility = ["//visibility:public"],
)
rust_library(
name = "clap",
- srcs = glob(["vendor/clap-2.33.3/src/**"]),
- edition = "2015",
+ srcs = glob(["vendor/clap-4.0.29/src/**/*.rs"]) + ["vendor/clap-4.0.29/examples/demo.rs"],
+ crate_features = [
+ "error-context",
+ "help",
+ "std",
+ "usage",
+ ],
+ data = ["vendor/clap-4.0.29/examples/demo.md"],
+ edition = "2021",
visibility = ["//visibility:public"],
deps = [
":bitflags",
- ":textwrap",
- ":unicode-width",
+ ":clap_lex",
+ ],
+)
+
+rust_library(
+ name = "clap_lex",
+ srcs = glob(["vendor/clap_lex-0.3.0/src/**/*.rs"]),
+ edition = "2021",
+ deps = [
+ ":os_str_bytes",
],
)
rust_library(
name = "codespan-reporting",
- srcs = glob(["vendor/codespan-reporting-0.11.1/src/**"]),
+ srcs = glob(["vendor/codespan-reporting-0.11.1/src/**/*.rs"]),
+ edition = "2018",
visibility = ["//visibility:public"],
deps = [
":termcolor",
@@ -39,101 +57,146 @@ rust_library(
)
rust_library(
- name = "lazy_static",
- srcs = glob(["vendor/lazy_static-1.4.0/src/**"]),
+ name = "once_cell",
+ srcs = glob(["vendor/once_cell-1.16.0/src/**/*.rs"]),
+ crate_features = [
+ "alloc",
+ "default",
+ "race",
+ "std",
+ ],
+ edition = "2021",
visibility = ["//visibility:public"],
)
rust_library(
+ name = "os_str_bytes",
+ srcs = glob(["vendor/os_str_bytes-6.4.1/src/**/*.rs"]),
+ crate_features = [
+ "raw_os_str",
+ ],
+ edition = "2021",
+)
+
+rust_library(
name = "proc-macro2",
- srcs = glob(["vendor/proc-macro2-1.0.28/src/**"]),
+ srcs = glob(["vendor/proc-macro2-1.0.47/src/**/*.rs"]),
crate_features = [
+ "default",
"proc-macro",
"span-locations",
],
+ edition = "2018",
visibility = ["//visibility:public"],
deps = [
":proc-macro2@build",
- ":unicode-xid",
+ ":unicode-ident",
],
)
cargo_build_script(
name = "proc-macro2@build",
- srcs = ["vendor/proc-macro2-1.0.28/build.rs"],
+ srcs = ["vendor/proc-macro2-1.0.47/build.rs"],
crate_features = [
+ "default",
"proc-macro",
"span-locations",
],
crate_name = "build",
+ edition = "2018",
)
rust_library(
name = "quote",
- srcs = glob(["vendor/quote-1.0.9/src/**"]),
- crate_features = ["proc-macro"],
+ srcs = glob(["vendor/quote-1.0.21/src/**/*.rs"]),
+ crate_features = [
+ "default",
+ "proc-macro",
+ ],
+ edition = "2018",
visibility = ["//visibility:public"],
- deps = [":proc-macro2"],
+ deps = [
+ ":proc-macro2",
+ ":quote@build",
+ ],
+)
+
+cargo_build_script(
+ name = "quote@build",
+ srcs = ["vendor/quote-1.0.21/build.rs"],
+ crate_features = [
+ "default",
+ "proc-macro",
+ ],
+ crate_name = "build",
+ edition = "2018",
)
rust_library(
name = "scratch",
- srcs = glob(["vendor/scratch-1.0.0/src/**"]),
+ srcs = glob(["vendor/scratch-1.0.2/src/**/*.rs"]),
+ edition = "2015",
rustc_env = {"OUT_DIR": ""},
visibility = ["//visibility:public"],
)
rust_library(
name = "syn",
- srcs = glob(["vendor/syn-1.0.75/src/**"]),
+ srcs = glob(["vendor/syn-1.0.105/src/**/*.rs"]),
crate_features = [
"clone-impls",
+ "default",
"derive",
"full",
"parsing",
"printing",
"proc-macro",
+ "quote",
],
+ edition = "2018",
visibility = ["//visibility:public"],
deps = [
":proc-macro2",
":quote",
":syn@build",
- ":unicode-xid",
+ ":unicode-ident",
],
)
cargo_build_script(
name = "syn@build",
- srcs = ["vendor/syn-1.0.75/build.rs"],
+ srcs = ["vendor/syn-1.0.105/build.rs"],
crate_features = [
"clone-impls",
+ "default",
"derive",
"full",
"parsing",
"printing",
"proc-macro",
+ "quote",
],
crate_name = "build",
+ edition = "2018",
)
rust_library(
name = "termcolor",
- srcs = glob(["vendor/termcolor-1.1.2/src/**"]),
+ srcs = glob(["vendor/termcolor-1.1.3/src/**/*.rs"]),
+ edition = "2018",
)
rust_library(
- name = "textwrap",
- srcs = glob(["vendor/textwrap-0.11.0/src/**"]),
- deps = [":unicode-width"],
+ name = "unicode-ident",
+ srcs = glob(["vendor/unicode-ident-1.0.5/src/**/*.rs"]),
+ edition = "2018",
)
rust_library(
name = "unicode-width",
- srcs = glob(["vendor/unicode-width-0.1.8/src/**"]),
-)
-
-rust_library(
- name = "unicode-xid",
- srcs = glob(["vendor/unicode-xid-0.2.2/src/**"]),
+ srcs = glob(["vendor/unicode-width-0.1.10/src/**/*.rs"]),
+ crate_features = [
+ "default",
+ ],
+ edition = "2015",
)
diff --git a/third-party/Cargo.lock b/third-party/Cargo.lock
index 0a3d543d..1c054218 100644
--- a/third-party/Cargo.lock
+++ b/third-party/Cargo.lock
@@ -3,38 +3,6 @@
version = 3
[[package]]
-name = "adler"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
-
-[[package]]
-name = "ansi_term"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
-dependencies = [
- "winapi",
-]
-
-[[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-dependencies = [
- "hermit-abi",
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "autocfg"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
-
-[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -42,41 +10,27 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cc"
-version = "1.0.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
-dependencies = [
- "jobserver",
-]
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
+version = "1.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
[[package]]
-name = "clang-ast"
-version = "0.1.6"
+name = "clap"
+version = "4.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eed6681036a96f9855a75b08a9f14199e212017508a967d1d1e868f575f7d8e9"
+checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d"
dependencies = [
- "serde",
+ "bitflags",
+ "clap_lex",
]
[[package]]
-name = "clap"
-version = "2.33.3"
+name = "clap_lex"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
+checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
dependencies = [
- "ansi_term",
- "atty",
- "bitflags",
- "strsim",
- "textwrap",
- "unicode-width",
- "vec_map",
+ "os_str_bytes",
]
[[package]]
@@ -90,340 +44,86 @@ dependencies = [
]
[[package]]
-name = "crc32fast"
-version = "1.2.1"
+name = "once_cell"
+version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "cxx"
-version = "1.0.54"
-dependencies = [
- "cc",
- "cxx-build",
- "cxx-gen",
- "cxx-test-suite",
- "cxxbridge-flags",
- "cxxbridge-macro",
- "link-cplusplus",
- "rustversion",
- "trybuild",
-]
-
-[[package]]
-name = "cxx-build"
-version = "1.0.54"
-dependencies = [
- "cc",
- "codespan-reporting",
- "cxx-gen",
- "lazy_static",
- "pkg-config",
- "proc-macro2",
- "quote",
- "scratch",
- "syn",
-]
+checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
[[package]]
-name = "cxx-gen"
-version = "0.7.54"
-dependencies = [
- "cc",
- "codespan-reporting",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "cxx-test-suite"
-version = "0.0.0"
-dependencies = [
- "cxx",
- "cxx-build",
- "cxxbridge-flags",
-]
-
-[[package]]
-name = "cxxbridge-cmd"
-version = "1.0.54"
-dependencies = [
- "clap",
- "codespan-reporting",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "cxxbridge-flags"
-version = "1.0.54"
-
-[[package]]
-name = "cxxbridge-macro"
-version = "1.0.54"
-dependencies = [
- "clang-ast",
- "cxx",
- "flate2",
- "memmap",
- "proc-macro2",
- "quote",
- "serde",
- "serde_json",
- "syn",
-]
-
-[[package]]
-name = "demo"
-version = "0.0.0"
-dependencies = [
- "cxx",
- "cxx-build",
-]
-
-[[package]]
-name = "dissimilar"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc4b29f4b9bb94bf267d57269fd0706d343a160937108e9619fe380645428abb"
-
-[[package]]
-name = "flate2"
-version = "1.0.20"
+name = "os_str_bytes"
+version = "6.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
-dependencies = [
- "cfg-if",
- "crc32fast",
- "libc",
- "miniz_oxide",
-]
-
-[[package]]
-name = "glob"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "itoa"
-version = "0.4.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
-
-[[package]]
-name = "jobserver"
-version = "0.1.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
-[[package]]
-name = "libc"
-version = "0.2.101"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21"
-
-[[package]]
-name = "link-cplusplus"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f1becd27d473556dc610b8afa1636ef90747b574a84553bc11e82371d5ef2d1"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "memmap"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
-dependencies = [
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.4.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
-dependencies = [
- "adler",
- "autocfg",
-]
-
-[[package]]
-name = "pkg-config"
-version = "0.3.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
+checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
[[package]]
name = "proc-macro2"
-version = "1.0.28"
+version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
dependencies = [
- "unicode-xid",
+ "unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.9"
+version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
]
[[package]]
-name = "rustversion"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
-
-[[package]]
-name = "ryu"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
-
-[[package]]
name = "scratch"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e114536316b51a5aa7a0e59fc49661fd263c5507dd08bd28de052e57626ce69"
-
-[[package]]
-name = "serde"
-version = "1.0.129"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.129"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e57ae87ad533d9a56427558b516d0adac283614e347abf85b0dc0cbbf0a249f3"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.66"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
-dependencies = [
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "strsim"
-version = "0.8.0"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
+checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
[[package]]
name = "syn"
-version = "1.0.75"
+version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7"
+checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
dependencies = [
"proc-macro2",
"quote",
- "unicode-xid",
+ "unicode-ident",
]
[[package]]
name = "termcolor"
-version = "1.1.2"
+version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]]
-name = "textwrap"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
-dependencies = [
- "unicode-width",
-]
-
-[[package]]
-name = "toml"
-version = "0.5.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
+name = "third-party"
+version = "0.0.0"
dependencies = [
- "serde",
+ "cc",
+ "clap",
+ "codespan-reporting",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "scratch",
+ "syn",
]
[[package]]
-name = "trybuild"
-version = "1.0.45"
+name = "unicode-ident"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bdaf2a1d317f3d58b44b31c7f6436b9b9acafe7bddfeace50897c2b804d7792"
-dependencies = [
- "dissimilar",
- "glob",
- "lazy_static",
- "serde",
- "serde_json",
- "termcolor",
- "toml",
-]
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
name = "unicode-width"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
-
-[[package]]
-name = "vec_map"
-version = "0.8.2"
+version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
+checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "winapi"
diff --git a/third-party/Cargo.toml b/third-party/Cargo.toml
new file mode 100644
index 00000000..84657de5
--- /dev/null
+++ b/third-party/Cargo.toml
@@ -0,0 +1,18 @@
+[workspace]
+[package]
+name = "third-party"
+version = "0.0.0"
+publish = false
+
+[lib]
+path = "/dev/null"
+
+[dependencies]
+cc = "1.0.49"
+clap = { version = "4", default-features = false, features = ["error-context", "help", "std", "usage"] }
+codespan-reporting = "0.11.1"
+once_cell = "1.9"
+proc-macro2 = { version = "1.0.39", features = ["span-locations"] }
+quote = "1.0.4"
+scratch = "1"
+syn = { version = "1.0.95", features = ["full"] }
diff --git a/third-party/fixups/cc/fixups.toml b/third-party/fixups/cc/fixups.toml
new file mode 100644
index 00000000..e148831c
--- /dev/null
+++ b/third-party/fixups/cc/fixups.toml
@@ -0,0 +1 @@
+omit_targets = ["gcc-shim"]
diff --git a/third-party/fixups/clap/fixups.toml b/third-party/fixups/clap/fixups.toml
new file mode 100644
index 00000000..36ad30f5
--- /dev/null
+++ b/third-party/fixups/clap/fixups.toml
@@ -0,0 +1,2 @@
+extra_srcs = ["examples/demo.md", "examples/demo.rs"]
+omit_targets = ["stdio-fixture"]
diff --git a/third-party/fixups/proc-macro2/fixups.toml b/third-party/fixups/proc-macro2/fixups.toml
new file mode 100644
index 00000000..5e026f75
--- /dev/null
+++ b/third-party/fixups/proc-macro2/fixups.toml
@@ -0,0 +1,2 @@
+[[buildscript]]
+[buildscript.rustc_flags]
diff --git a/third-party/fixups/quote/fixups.toml b/third-party/fixups/quote/fixups.toml
new file mode 100644
index 00000000..5e026f75
--- /dev/null
+++ b/third-party/fixups/quote/fixups.toml
@@ -0,0 +1,2 @@
+[[buildscript]]
+[buildscript.rustc_flags]
diff --git a/third-party/fixups/scratch/fixups.toml b/third-party/fixups/scratch/fixups.toml
new file mode 100644
index 00000000..72f4bdd0
--- /dev/null
+++ b/third-party/fixups/scratch/fixups.toml
@@ -0,0 +1,4 @@
+buildscript = []
+
+[env]
+OUT_DIR = "generated"
diff --git a/third-party/fixups/syn/fixups.toml b/third-party/fixups/syn/fixups.toml
new file mode 100644
index 00000000..5e026f75
--- /dev/null
+++ b/third-party/fixups/syn/fixups.toml
@@ -0,0 +1,2 @@
+[[buildscript]]
+[buildscript.rustc_flags]
diff --git a/third-party/reindeer.toml b/third-party/reindeer.toml
new file mode 100644
index 00000000..eb65857c
--- /dev/null
+++ b/third-party/reindeer.toml
@@ -0,0 +1,13 @@
+precise_srcs = true
+rustc_flags = ["--cap-lints=allow"]
+
+[cargo]
+versioned_dirs = true
+
+[buck]
+generated_file_header = """
+# \u0040generated by `reindeer buckify`
+"""
+buckfile_imports = """
+load("//tools/buck:buildscript.bzl", "buildscript_args")
+"""
diff --git a/tools/bazel/third_party.bzl b/tools/bazel/third_party.bzl
index 7f51c466..5b2ec3fe 100644
--- a/tools/bazel/third_party.bzl
+++ b/tools/bazel/third_party.bzl
@@ -1,5 +1,5 @@
load("@rules_rust//cargo:cargo_build_script.bzl", "cargo_build_script")
-load("@rules_rust//rust:rust.bzl", "rust_binary", "rust_library")
+load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library")
load("@third-party//:vendor.bzl", "vendored")
def third_party_glob(include):
diff --git a/tools/bazel/vendor.bzl b/tools/bazel/vendor.bzl
index e51adb7b..0f199145 100644
--- a/tools/bazel/vendor.bzl
+++ b/tools/bazel/vendor.bzl
@@ -2,7 +2,9 @@
of a crate in the current workspace.
"""
-load("@rules_rust//rust:repositories.bzl", "DEFAULT_RUST_VERSION", "load_arbitrary_tool")
+load("@rules_rust//rust:defs.bzl", "rust_common")
+load("@rules_rust//rust:repositories.bzl", "load_arbitrary_tool")
+load("@rules_rust//rust/platform:triple.bzl", "get_host_triple")
def _impl(repository_ctx):
# Link cxx repository into @third-party.
@@ -10,21 +12,11 @@ def _impl(repository_ctx):
workspace = lockfile.dirname.dirname
repository_ctx.symlink(workspace, "workspace")
- # Copy third-party/Cargo.lock since those are the crate versions that the
- # BUILD file is written against.
- vendor_lockfile = repository_ctx.path("workspace/third-party/Cargo.lock")
- root_lockfile = repository_ctx.path("workspace/Cargo.lock")
- _copy_file(repository_ctx, src = vendor_lockfile, dst = root_lockfile)
-
# Figure out which version of cargo to use.
if repository_ctx.attr.target_triple:
target_triple = repository_ctx.attr.target_triple
- elif "mac" in repository_ctx.os.name:
- target_triple = "x86_64-apple-darwin"
- elif "windows" in repository_ctx.os.name:
- target_triple = "x86_64-pc-windows-msvc"
else:
- target_triple = "x86_64-unknown-linux-gnu"
+ target_triple = get_host_triple(repository_ctx).str
# Download cargo.
load_arbitrary_tool(
@@ -36,20 +28,16 @@ def _impl(repository_ctx):
target_triple = target_triple,
)
- cmd = ["{}/bin/cargo".format(repository_ctx.path(".")), "vendor", "--versioned-dirs", "third-party/vendor"]
+ cmd = ["{}/bin/cargo".format(repository_ctx.path(".")), "vendor", "--versioned-dirs"]
result = repository_ctx.execute(
cmd,
quiet = True,
- working_directory = "workspace",
+ working_directory = "workspace/third-party",
)
_log_cargo_vendor(repository_ctx, result)
if result.return_code != 0:
fail("failed to execute `{}`".format(" ".join(cmd)))
- # Copy lockfile back to third-party/Cargo.lock to reflect any modification
- # performed by Cargo.
- _copy_file(repository_ctx, src = root_lockfile, dst = vendor_lockfile)
-
# Produce a token for third_party_glob to depend on so that the necessary
# sequencing is visible to Bazel.
repository_ctx.file("BUILD", executable = False)
@@ -77,7 +65,6 @@ vendor = repository_rule(
attrs = {
"cargo_version": attr.string(
doc = "The version of cargo to use",
- default = DEFAULT_RUST_VERSION,
),
"cargo_iso_date": attr.string(
doc = "The date of the tool (or None, if the version is a specific version)",
diff --git a/tools/buck/buildscript.bzl b/tools/buck/buildscript.bzl
new file mode 100644
index 00000000..bbcf1060
--- /dev/null
+++ b/tools/buck/buildscript.bzl
@@ -0,0 +1,13 @@
+def buildscript_args(
+ name,
+ package_name,
+ buildscript_rule,
+ cfgs,
+ features,
+ outfile,
+ version):
+ native.genrule(
+ name = name,
+ out = outfile,
+ cmd = "env RUSTC=rustc TARGET= $(exe %s) | sed -n s/^cargo:rustc-cfg=/--cfg=/p > ${OUT}" % buildscript_rule,
+ )
diff --git a/tools/buck/genrule.bzl b/tools/buck/genrule.bzl
deleted file mode 100644
index b5364b7f..00000000
--- a/tools/buck/genrule.bzl
+++ /dev/null
@@ -1,8 +0,0 @@
-def genrule(cmd, **kwargs):
- # Resolve a distracting inconsistency between Buck and Bazel.
- # Bazel creates the directory for your output file, while Buck expects the
- # cmd to create it.
- #
- # TODO: send this as a PR to Buck, because Bazel's behavior here is better.
- cmd = "mkdir -p `dirname ${OUT}`; " + cmd
- native.genrule(cmd = cmd, **kwargs)
diff --git a/tools/buck/prelude b/tools/buck/prelude
new file mode 160000
+Subproject bed5249482b20f591d9d231663b23f318b6c10b
diff --git a/tools/buck/rust_cxx_bridge.bzl b/tools/buck/rust_cxx_bridge.bzl
index 4acc7c66..49e38fce 100644
--- a/tools/buck/rust_cxx_bridge.bzl
+++ b/tools/buck/rust_cxx_bridge.bzl
@@ -1,19 +1,17 @@
-load("//tools/buck:genrule.bzl", "genrule")
-
def rust_cxx_bridge(name, src, deps = []):
- genrule(
+ native.genrule(
name = "%s/header" % name,
out = src + ".h",
cmd = "cp $(location :%s/generated)/generated.h ${OUT}" % name,
)
- genrule(
+ native.genrule(
name = "%s/source" % name,
out = src + ".cc",
cmd = "cp $(location :%s/generated)/generated.cc ${OUT}" % name,
)
- genrule(
+ native.genrule(
name = "%s/generated" % name,
srcs = [src],
out = ".",
@@ -21,14 +19,14 @@ def rust_cxx_bridge(name, src, deps = []):
type = "cxxbridge",
)
- cxx_library(
+ native.cxx_library(
name = name,
srcs = [":%s/source" % name],
preferred_linkage = "static",
- deps = deps + [":%s/include" % name],
+ exported_deps = deps + [":%s/include" % name],
)
- cxx_library(
+ native.cxx_library(
name = "%s/include" % name,
exported_headers = [":%s/header" % name],
)
diff --git a/tools/buck/rust_library.bzl b/tools/buck/rust_library.bzl
deleted file mode 100644
index 67ec2ac7..00000000
--- a/tools/buck/rust_library.bzl
+++ /dev/null
@@ -1,34 +0,0 @@
-load("//tools/buck:genrule.bzl", "genrule")
-
-def rust_library(
- name,
- srcs,
- features = [],
- rustc_flags = [],
- build_script = None,
- **kwargs):
- if build_script:
- rust_binary(
- name = "%s@build" % name,
- srcs = srcs + [build_script],
- crate = "build",
- crate_root = build_script,
- features = features,
- rustc_flags = rustc_flags,
- )
-
- genrule(
- name = "%s@cfg" % name,
- out = "output",
- cmd = "env RUSTC=rustc TARGET= $(exe :%s@build) | sed -n s/^cargo:rustc-cfg=/--cfg=/p > ${OUT}" % name,
- )
-
- rustc_flags = rustc_flags + ["@$(location :%s@cfg)" % name]
-
- native.rust_library(
- name = name,
- srcs = srcs,
- features = features,
- rustc_flags = rustc_flags,
- **kwargs
- )
diff --git a/tools/buck/toolchains/BUCK b/tools/buck/toolchains/BUCK
new file mode 100644
index 00000000..87ee8933
--- /dev/null
+++ b/tools/buck/toolchains/BUCK
@@ -0,0 +1,21 @@
+load("@prelude//toolchains:cxx.bzl", "system_cxx_toolchain")
+load("@prelude//toolchains:python.bzl", "system_python_bootstrap_toolchain")
+load("@prelude//toolchains:rust.bzl", "system_rust_toolchain")
+
+system_cxx_toolchain(
+ name = "cxx",
+ visibility = ["PUBLIC"],
+)
+
+system_python_bootstrap_toolchain(
+ name = "python_bootstrap",
+ visibility = ["PUBLIC"],
+)
+
+system_rust_toolchain(
+ name = "rust",
+ default_edition = None,
+ rustc_flags = ["-Clink-arg=-fuse-ld=lld"],
+ rustdoc_flags = ["-Zunstable-options"], # doc builds use unstable '--extern-html-root-url'
+ visibility = ["PUBLIC"],
+)