diff options
author | Matthew Maurer <mmaurer@google.com> | 2024-03-19 22:41:55 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2024-03-19 22:41:55 +0000 |
commit | 35bd72fbb68e5f4feccc59d17af7fb350974a3dc (patch) | |
tree | a559c2c5f783d4cbd605578eee27269d1e3c533b /gen | |
parent | 6bdb9aa5e8afca684f73b8b30a162f3064e183a6 (diff) | |
parent | 15cbbff88df7a8191d88c7aebefc7b508bd4de69 (diff) | |
download | cxx-35bd72fbb68e5f4feccc59d17af7fb350974a3dc.tar.gz |
Original change: https://android-review.googlesource.com/c/platform/external/rust/cxx/+/3003022
Change-Id: Ifb8c5cfdcc08f30aeff8426e3d7f276a1e11716a
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'gen')
-rw-r--r-- | gen/build/Cargo.toml | 19 | ||||
-rw-r--r-- | gen/build/src/deps.rs | 8 | ||||
-rw-r--r-- | gen/build/src/intern.rs | 6 | ||||
-rw-r--r-- | gen/build/src/lib.rs | 26 | ||||
-rw-r--r-- | gen/build/src/out.rs | 229 | ||||
-rw-r--r-- | gen/build/src/paths.rs | 23 | ||||
-rw-r--r-- | gen/build/src/vec.rs | 6 | ||||
-rw-r--r-- | gen/cmd/Android.bp | 2 | ||||
-rw-r--r-- | gen/cmd/Cargo.toml | 14 | ||||
-rw-r--r-- | gen/cmd/src/app.rs | 4 | ||||
-rw-r--r-- | gen/cmd/src/cfg.rs | 8 | ||||
-rw-r--r-- | gen/cmd/src/main.rs | 8 | ||||
-rw-r--r-- | gen/lib/Android.bp | 2 | ||||
-rw-r--r-- | gen/lib/Cargo.toml | 14 | ||||
-rw-r--r-- | gen/lib/src/error.rs | 41 | ||||
-rw-r--r-- | gen/lib/src/lib.rs | 9 | ||||
-rw-r--r-- | gen/lib/tests/test.rs | 2 | ||||
-rw-r--r-- | gen/src/block.rs | 6 | ||||
-rw-r--r-- | gen/src/builtin.rs | 4 | ||||
-rw-r--r-- | gen/src/cfg.rs | 4 | ||||
-rw-r--r-- | gen/src/check.rs | 2 | ||||
-rw-r--r-- | gen/src/error.rs | 2 | ||||
-rw-r--r-- | gen/src/file.rs | 2 | ||||
-rw-r--r-- | gen/src/fs.rs | 2 | ||||
-rw-r--r-- | gen/src/include.rs | 8 | ||||
-rw-r--r-- | gen/src/mod.rs | 1 | ||||
-rw-r--r-- | gen/src/names.rs | 2 | ||||
-rw-r--r-- | gen/src/namespace.rs | 2 | ||||
-rw-r--r-- | gen/src/nested.rs | 11 | ||||
-rw-r--r-- | gen/src/out.rs | 26 | ||||
-rw-r--r-- | gen/src/write.rs | 44 |
31 files changed, 402 insertions, 135 deletions
diff --git a/gen/build/Cargo.toml b/gen/build/Cargo.toml index 9b74255b..ee20e2b7 100644 --- a/gen/build/Cargo.toml +++ b/gen/build/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "cxx-build" -version = "1.0.93" +version = "1.0.119" 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." documentation = "https://docs.rs/cxx-build" -edition = "2018" +edition = "2021" exclude = ["build.rs"] homepage = "https://cxx.rs" keywords = ["ffi", "build-dependencies"] @@ -19,21 +19,22 @@ parallel = ["cc/parallel"] experimental-async-fn = [] [dependencies] -cc = "1.0.49" +cc = "1.0.83" 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 = "2.0.1", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] } +once_cell = "1.18" +proc-macro2 = { version = "1.0.74", default-features = false, features = ["span-locations"] } +quote = { version = "1.0.35", default-features = false } +scratch = "1.0.5" +syn = { version = "2.0.46", default-features = false, features = ["clone-impls", "full", "parsing", "printing"] } [dev-dependencies] cxx = { version = "1.0", path = "../.." } cxx-gen = { version = "0.7", path = "../lib" } -pkg-config = "0.3" +pkg-config = "0.3.27" [lib] doc-scrape-examples = false [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = ["--generate-link-to-definition"] diff --git a/gen/build/src/deps.rs b/gen/build/src/deps.rs index fb80072c..36f2066a 100644 --- a/gen/build/src/deps.rs +++ b/gen/build/src/deps.rs @@ -4,19 +4,19 @@ use std::ffi::OsString; use std::path::PathBuf; #[derive(Default)] -pub struct Crate { +pub(crate) struct Crate { pub include_prefix: Option<PathBuf>, pub links: Option<OsString>, pub header_dirs: Vec<HeaderDir>, } -pub struct HeaderDir { +pub(crate) struct HeaderDir { pub exported: bool, pub path: PathBuf, } impl Crate { - pub fn print_to_cargo(&self) { + pub(crate) fn print_to_cargo(&self) { if let Some(include_prefix) = &self.include_prefix { println!( "cargo:CXXBRIDGE_PREFIX={}", @@ -38,7 +38,7 @@ impl Crate { } } -pub fn direct_dependencies() -> Vec<Crate> { +pub(crate) fn direct_dependencies() -> Vec<Crate> { let mut crates: BTreeMap<String, Crate> = BTreeMap::new(); let mut exported_header_dirs: BTreeMap<String, Vec<(usize, PathBuf)>> = BTreeMap::new(); diff --git a/gen/build/src/intern.rs b/gen/build/src/intern.rs index c8b57d89..753e3f31 100644 --- a/gen/build/src/intern.rs +++ b/gen/build/src/intern.rs @@ -3,15 +3,15 @@ use once_cell::sync::OnceCell; use std::sync::{Mutex, PoisonError}; #[derive(Copy, Clone, Default)] -pub struct InternedString(&'static str); +pub(crate) struct InternedString(&'static str); impl InternedString { - pub fn str(self) -> &'static str { + pub(crate) fn str(self) -> &'static str { self.0 } } -pub fn intern(s: &str) -> InternedString { +pub(crate) fn intern(s: &str) -> InternedString { static INTERN: OnceCell<Mutex<Set<&'static str>>> = OnceCell::new(); let mut set = INTERN diff --git a/gen/build/src/lib.rs b/gen/build/src/lib.rs index b6b843a6..4fcb9459 100644 --- a/gen/build/src/lib.rs +++ b/gen/build/src/lib.rs @@ -45,17 +45,17 @@ //! $ cxxbridge src/main.rs > path/to/mybridge.cc //! ``` -#![doc(html_root_url = "https://docs.rs/cxx-build/1.0.93")] +#![doc(html_root_url = "https://docs.rs/cxx-build/1.0.119")] #![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::into_iter_without_iter, clippy::items_after_statements, clippy::match_bool, clippy::match_on_vec_items, @@ -65,7 +65,6 @@ clippy::needless_pass_by_value, clippy::new_without_default, clippy::nonminimal_bool, - clippy::option_if_let_else, clippy::or_fun_call, clippy::redundant_else, clippy::shadow_unrelated, @@ -73,12 +72,13 @@ clippy::similar_names, clippy::single_match_else, clippy::struct_excessive_bools, + clippy::struct_field_names, clippy::too_many_arguments, clippy::too_many_lines, clippy::toplevel_ref_arg, + clippy::unconditional_recursion, // clippy bug: https://github.com/rust-lang/rust-clippy/issues/12133 + clippy::uninlined_format_args, clippy::upper_case_acronyms, - // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6983 - clippy::wrong_self_convention )] mod cargo; @@ -369,7 +369,7 @@ fn make_crate_dir(prj: &Project) -> PathBuf { let crate_dir = prj.out_dir.join("cxxbridge").join("crate"); let ref link = crate_dir.join(&prj.include_prefix); let ref manifest_dir = prj.manifest_dir; - if out::symlink_dir(manifest_dir, link).is_err() && cfg!(not(unix)) { + if out::relative_symlink_dir(manifest_dir, link).is_err() && cfg!(not(unix)) { let cachedir_tag = "\ Signature: 8a477f597d28d172789f06886806bc55\n\ # This file is a cache directory tag created by cxx.\n\ @@ -386,11 +386,11 @@ fn make_include_dir(prj: &Project) -> Result<PathBuf> { let cxx_h = include_dir.join("rust").join("cxx.h"); let ref shared_cxx_h = prj.shared_dir.join("rust").join("cxx.h"); if let Some(ref original) = env::var_os("DEP_CXXBRIDGE1_HEADER") { - out::symlink_file(original, cxx_h)?; - out::symlink_file(original, shared_cxx_h)?; + out::absolute_symlink_file(original, cxx_h)?; + out::absolute_symlink_file(original, shared_cxx_h)?; } else { out::write(shared_cxx_h, gen::include::HEADER.as_bytes())?; - out::symlink_file(shared_cxx_h, cxx_h)?; + out::relative_symlink_file(shared_cxx_h, cxx_h)?; } Ok(include_dir) } @@ -414,7 +414,7 @@ fn generate_bridge(prj: &Project, build: &mut Build, rust_source_file: &Path) -> out::write(header_path, &generated.header)?; let ref link_path = include_dir.join(rel_path); - let _ = out::symlink_file(header_path, link_path); + let _ = out::relative_symlink_file(header_path, link_path); let ref rel_path_cc = rel_path.with_appended_extension(".cc"); let ref implementation_path = sources_dir.join(rel_path_cc); @@ -423,8 +423,8 @@ fn generate_bridge(prj: &Project, build: &mut Build, rust_source_file: &Path) -> let shared_h = prj.shared_dir.join(&prj.include_prefix).join(rel_path_h); let shared_cc = prj.shared_dir.join(&prj.include_prefix).join(rel_path_cc); - let _ = out::symlink_file(header_path, shared_h); - let _ = out::symlink_file(implementation_path, shared_cc); + let _ = out::relative_symlink_file(header_path, shared_h); + let _ = out::relative_symlink_file(implementation_path, shared_cc); Ok(()) } @@ -455,7 +455,7 @@ fn best_effort_copy_headers(src: &Path, dst: &Path, max_depth: usize) { Ok(file_type) if file_type.is_file() => { let src = entry.path(); match src.extension().and_then(OsStr::to_str) { - Some("h") | Some("hh") | Some("hpp") => {} + Some("h" | "hh" | "hpp") => {} _ => continue, } if !dst_created && fs::create_dir_all(dst).is_err() { diff --git a/gen/build/src/out.rs b/gen/build/src/out.rs index a52aab25..0095666f 100644 --- a/gen/build/src/out.rs +++ b/gen/build/src/out.rs @@ -1,8 +1,8 @@ use crate::error::{Error, Result}; use crate::gen::fs; use crate::paths; -use std::io; -use std::path::Path; +use std::path::{Component, Path, PathBuf}; +use std::{env, io}; pub(crate) fn write(path: impl AsRef<Path>, content: &[u8]) -> Result<()> { let path = path.as_ref(); @@ -29,19 +29,61 @@ pub(crate) fn write(path: impl AsRef<Path>, content: &[u8]) -> Result<()> { } } -pub(crate) fn symlink_file(original: impl AsRef<Path>, link: impl AsRef<Path>) -> Result<()> { +pub(crate) fn relative_symlink_file( + original: impl AsRef<Path>, + link: impl AsRef<Path>, +) -> Result<()> { let original = original.as_ref(); let link = link.as_ref(); - let mut create_dir_error = None; + let parent_directory_error = prepare_parent_directory_for_symlink(link).err(); + let relativized = best_effort_relativize_symlink(original, link); + + symlink_file(&relativized, original, link, parent_directory_error) +} + +pub(crate) fn absolute_symlink_file( + original: impl AsRef<Path>, + link: impl AsRef<Path>, +) -> Result<()> { + let original = original.as_ref(); + let link = link.as_ref(); + + let parent_directory_error = prepare_parent_directory_for_symlink(link).err(); + + symlink_file(original, original, link, parent_directory_error) +} + +pub(crate) fn relative_symlink_dir( + original: impl AsRef<Path>, + link: impl AsRef<Path>, +) -> Result<()> { + let original = original.as_ref(); + let link = link.as_ref(); + + let parent_directory_error = prepare_parent_directory_for_symlink(link).err(); + let relativized = best_effort_relativize_symlink(original, link); + + symlink_dir(&relativized, link, parent_directory_error) +} + +fn prepare_parent_directory_for_symlink(link: &Path) -> fs::Result<()> { if fs::exists(link) { best_effort_remove(link); + Ok(()) } else { let parent = link.parent().unwrap(); - create_dir_error = fs::create_dir_all(parent).err(); + fs::create_dir_all(parent) } +} - match paths::symlink_or_copy(original, link) { +fn symlink_file( + path_for_symlink: &Path, + path_for_copy: &Path, + link: &Path, + parent_directory_error: Option<fs::Error>, +) -> Result<()> { + match paths::symlink_or_copy(path_for_symlink, path_for_copy, link) { // As long as symlink_or_copy succeeded, ignore any create_dir_all error. Ok(()) => Ok(()), Err(err) => { @@ -57,29 +99,22 @@ pub(crate) fn symlink_file(original: impl AsRef<Path>, link: impl AsRef<Path>) - } else { // If create_dir_all and symlink_or_copy both failed, prefer the // first error. - Err(Error::Fs(create_dir_error.unwrap_or(err))) + Err(Error::Fs(parent_directory_error.unwrap_or(err))) } } } } -pub(crate) fn symlink_dir(original: impl AsRef<Path>, link: impl AsRef<Path>) -> Result<()> { - let original = original.as_ref(); - let link = link.as_ref(); - - let mut create_dir_error = None; - if fs::exists(link) { - best_effort_remove(link); - } else { - let parent = link.parent().unwrap(); - create_dir_error = fs::create_dir_all(parent).err(); - } - - match fs::symlink_dir(original, link) { +fn symlink_dir( + path_for_symlink: &Path, + link: &Path, + parent_directory_error: Option<fs::Error>, +) -> Result<()> { + match fs::symlink_dir(path_for_symlink, link) { // As long as symlink_dir succeeded, ignore any create_dir_all error. Ok(()) => Ok(()), // If create_dir_all and symlink_dir both failed, prefer the first error. - Err(err) => Err(Error::Fs(create_dir_error.unwrap_or(err))), + Err(err) => Err(Error::Fs(parent_directory_error.unwrap_or(err))), } } @@ -117,3 +152,155 @@ fn best_effort_remove(path: &Path) { } } } + +fn best_effort_relativize_symlink(original: impl AsRef<Path>, link: impl AsRef<Path>) -> PathBuf { + let original = original.as_ref(); + let link = link.as_ref(); + + let relative_path = match abstractly_relativize_symlink(original, link) { + Some(relative_path) => relative_path, + None => return original.to_path_buf(), + }; + + // Sometimes "a/b/../c" refers to a different canonical location than "a/c". + // This can happen if 'b' is a symlink. The '..' canonicalizes to the parent + // directory of the symlink's target, not back to 'a'. In cxx-build's case + // someone could be using `--target-dir` with a location containing such + // symlinks. + if let Ok(original_canonical) = original.canonicalize() { + if let Ok(relative_canonical) = link.parent().unwrap().join(&relative_path).canonicalize() { + if original_canonical == relative_canonical { + return relative_path; + } + } + } + + original.to_path_buf() +} + +fn abstractly_relativize_symlink( + original: impl AsRef<Path>, + link: impl AsRef<Path>, +) -> Option<PathBuf> { + let original = original.as_ref(); + let link = link.as_ref(); + + // Relativization only makes sense if there is a semantically meaningful + // base directory shared between the two paths. + // + // For example /Volumes/code/library/src/lib.rs + // and /Volumes/code/library/target/path/to/something.a + // have a meaningful shared base of /Volumes/code/library. The target and + // source directory only likely ever get relocated as one unit. + // + // On the other hand, /Volumes/code/library/src/lib.rs + // and /Volumes/shared_target + // do not, since upon moving library to a different location it should + // continue referring to the original location of that shared Cargo target + // directory. + let likely_no_semantic_prefix = env::var_os("CARGO_TARGET_DIR").is_some(); + + if likely_no_semantic_prefix + || original.is_relative() + || link.is_relative() + || path_contains_intermediate_components(original) + || path_contains_intermediate_components(link) + { + return None; + } + + let (common_prefix, rest_of_original, rest_of_link) = split_after_common_prefix(original, link); + + if common_prefix == Path::new("") { + return None; + } + + let mut rest_of_link = rest_of_link.components(); + rest_of_link + .next_back() + .expect("original can't be a subdirectory of link"); + + let mut path_to_common_prefix = PathBuf::new(); + while rest_of_link.next_back().is_some() { + path_to_common_prefix.push(Component::ParentDir); + } + + Some(path_to_common_prefix.join(rest_of_original)) +} + +fn path_contains_intermediate_components(path: impl AsRef<Path>) -> bool { + path.as_ref() + .components() + .any(|component| component == Component::ParentDir) +} + +fn split_after_common_prefix<'first, 'second>( + first: &'first Path, + second: &'second Path, +) -> (&'first Path, &'first Path, &'second Path) { + let entire_first = first; + let mut first = first.components(); + let mut second = second.components(); + loop { + let rest_of_first = first.as_path(); + let rest_of_second = second.as_path(); + match (first.next(), second.next()) { + (Some(first_component), Some(second_component)) + if first_component == second_component => {} + _ => { + let mut common_prefix = entire_first; + for _ in rest_of_first.components().rev() { + if let Some(parent) = common_prefix.parent() { + common_prefix = parent; + } else { + common_prefix = Path::new(""); + break; + } + } + return (common_prefix, rest_of_first, rest_of_second); + } + } + } +} + +#[cfg(test)] +mod tests { + use crate::out::abstractly_relativize_symlink; + use std::path::Path; + + #[cfg(not(windows))] + #[test] + fn test_relativize_symlink_unix() { + assert_eq!( + abstractly_relativize_symlink("/foo/bar/baz", "/foo/spam/eggs").as_deref(), + Some(Path::new("../bar/baz")), + ); + assert_eq!( + abstractly_relativize_symlink("/foo/bar/../baz", "/foo/spam/eggs"), + None, + ); + assert_eq!( + abstractly_relativize_symlink("/foo/bar/baz", "/foo/spam/./eggs").as_deref(), + Some(Path::new("../bar/baz")), + ); + } + + #[cfg(windows)] + #[test] + fn test_relativize_symlink_windows() { + use std::path::PathBuf; + + let windows_target = PathBuf::from_iter(["c:\\", "windows", "foo"]); + let windows_link = PathBuf::from_iter(["c:\\", "users", "link"]); + let windows_different_volume_link = PathBuf::from_iter(["d:\\", "users", "link"]); + + assert_eq!( + abstractly_relativize_symlink(&windows_target, windows_link).as_deref(), + Some(Path::new("..\\windows\\foo")), + ); + assert_eq!( + abstractly_relativize_symlink(&windows_target, windows_different_volume_link), + None, + ); + } +} diff --git a/gen/build/src/paths.rs b/gen/build/src/paths.rs index c514a570..53445dee 100644 --- a/gen/build/src/paths.rs +++ b/gen/build/src/paths.rs @@ -40,28 +40,37 @@ impl PathExt for Path { } #[cfg(unix)] -pub(crate) use self::fs::symlink_file as symlink_or_copy; +pub(crate) fn symlink_or_copy( + path_for_symlink: impl AsRef<Path>, + _path_for_copy: impl AsRef<Path>, + link: impl AsRef<Path>, +) -> fs::Result<()> { + fs::symlink_file(path_for_symlink, link) +} #[cfg(windows)] pub(crate) fn symlink_or_copy( - original: impl AsRef<Path>, + path_for_symlink: impl AsRef<Path>, + path_for_copy: impl AsRef<Path>, link: impl AsRef<Path>, ) -> fs::Result<()> { // Pre-Windows 10, symlinks require admin privileges. Since Windows 10, they // require Developer Mode. If it fails, fall back to copying the file. - let original = original.as_ref(); + let path_for_symlink = path_for_symlink.as_ref(); let link = link.as_ref(); - if fs::symlink_file(original, link).is_err() { - fs::copy(original, link)?; + if fs::symlink_file(path_for_symlink, link).is_err() { + let path_for_copy = path_for_copy.as_ref(); + fs::copy(path_for_copy, link)?; } Ok(()) } #[cfg(not(any(unix, windows)))] pub(crate) fn symlink_or_copy( - original: impl AsRef<Path>, + _path_for_symlink: impl AsRef<Path>, + path_for_copy: impl AsRef<Path>, copy: impl AsRef<Path>, ) -> fs::Result<()> { - fs::copy(original, copy)?; + fs::copy(path_for_copy, copy)?; Ok(()) } diff --git a/gen/build/src/vec.rs b/gen/build/src/vec.rs index ac9235ec..ccc98955 100644 --- a/gen/build/src/vec.rs +++ b/gen/build/src/vec.rs @@ -1,7 +1,7 @@ use crate::intern::{self, InternedString}; use std::path::Path; -pub trait InternedVec<T> +pub(crate) trait InternedVec<T> where T: ?Sized, { @@ -17,14 +17,14 @@ where } } -pub fn intern<T>(elements: &[&T]) -> Vec<InternedString> +pub(crate) fn intern<T>(elements: &[&T]) -> Vec<InternedString> where T: ?Sized + Element, { elements.iter().copied().map(Element::intern).collect() } -pub trait Element { +pub(crate) trait Element { fn intern(&self) -> InternedString; fn unintern(_: InternedString) -> &'static Self; } diff --git a/gen/cmd/Android.bp b/gen/cmd/Android.bp index 688e9968..b0d6ad47 100644 --- a/gen/cmd/Android.bp +++ b/gen/cmd/Android.bp @@ -17,7 +17,7 @@ rust_binary_host { cargo_env_compat: true, cargo_pkg_version: "1.0.93", srcs: ["src/main.rs"], - edition: "2018", + edition: "2021", rustlibs: [ "libclap", "libcodespan_reporting", diff --git a/gen/cmd/Cargo.toml b/gen/cmd/Cargo.toml index 0026a531..fef5b8c3 100644 --- a/gen/cmd/Cargo.toml +++ b/gen/cmd/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "cxxbridge-cmd" -version = "1.0.93" +version = "1.0.119" authors = ["David Tolnay <dtolnay@gmail.com>"] categories = ["development-tools::build-utils", "development-tools::ffi"] description = "C++ code generator for integrating `cxx` crate into a non-Cargo build." -edition = "2018" +edition = "2021" exclude = ["build.rs"] homepage = "https://cxx.rs" keywords = ["ffi"] @@ -21,11 +21,11 @@ path = "src/main.rs" experimental-async-fn = [] [dependencies] -clap = { version = "4", default-features = false, features = ["error-context", "help", "std", "suggestions", "usage"] } -codespan-reporting = "0.11" -proc-macro2 = { version = "1.0.39", default-features = false, features = ["span-locations"] } -quote = { version = "1.0", default-features = false } -syn = { version = "2.0.1", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] } +clap = { version = "4.3.11", default-features = false, features = ["error-context", "help", "std", "suggestions", "usage"] } +codespan-reporting = "0.11.1" +proc-macro2 = { version = "1.0.74", default-features = false, features = ["span-locations"] } +quote = { version = "1.0.35", default-features = false } +syn = { version = "2.0.46", default-features = false, features = ["clone-impls", "full", "parsing", "printing"] } [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 bfad8562..645b05d5 100644 --- a/gen/cmd/src/app.rs +++ b/gen/cmd/src/app.rs @@ -84,7 +84,7 @@ pub(super) fn from_args() -> Opt { } } else { Include { - path: include.to_owned(), + path: include.clone(), kind: IncludeKind::Quoted, } } @@ -122,7 +122,7 @@ pub(super) fn from_args() -> Opt { fn arg_input() -> Arg { Arg::new(INPUT) .help("Input Rust source file containing #[cxx::bridge].") - .required_unless_present_any(&[HEADER, HELP]) + .required_unless_present_any([HEADER, HELP]) .value_parser(ValueParser::path_buf()) } diff --git a/gen/cmd/src/cfg.rs b/gen/cmd/src/cfg.rs index 29f0b9bc..92b954cd 100644 --- a/gen/cmd/src/cfg.rs +++ b/gen/cmd/src/cfg.rs @@ -5,7 +5,7 @@ use syn::parse::ParseStream; use syn::{Ident, LitBool, LitStr, Token}; #[derive(Ord, PartialOrd, Eq, PartialEq)] -pub enum CfgValue { +pub(crate) enum CfgValue { Bool(bool), Str(String), } @@ -15,12 +15,12 @@ impl CfgValue { const TRUE: Self = CfgValue::Bool(true); } -pub struct FlagsCfgEvaluator { +pub(crate) struct FlagsCfgEvaluator { map: Map<String, Set<CfgValue>>, } impl FlagsCfgEvaluator { - pub fn new(map: Map<String, Set<CfgValue>>) -> Self { + pub(crate) fn new(map: Map<String, Set<CfgValue>>) -> Self { FlagsCfgEvaluator { map } } } @@ -73,7 +73,7 @@ impl Debug for CfgValue { } } -pub fn parse(input: ParseStream) -> syn::Result<(String, CfgValue)> { +pub(crate) fn parse(input: ParseStream) -> syn::Result<(String, CfgValue)> { let ident: Ident = input.parse()?; let name = ident.to_string(); if input.is_empty() { diff --git a/gen/cmd/src/main.rs b/gen/cmd/src/main.rs index 4d5edfd1..227a3637 100644 --- a/gen/cmd/src/main.rs +++ b/gen/cmd/src/main.rs @@ -6,8 +6,10 @@ clippy::enum_glob_use, clippy::if_same_then_else, clippy::inherent_to_string, + clippy::into_iter_without_iter, clippy::items_after_statements, clippy::large_enum_variant, + clippy::map_clone, clippy::match_bool, clippy::match_on_vec_items, clippy::match_same_arms, @@ -15,18 +17,16 @@ clippy::needless_pass_by_value, clippy::new_without_default, clippy::nonminimal_bool, - clippy::option_if_let_else, clippy::or_fun_call, clippy::redundant_else, clippy::shadow_unrelated, clippy::similar_names, clippy::single_match_else, clippy::struct_excessive_bools, + clippy::struct_field_names, clippy::too_many_arguments, clippy::too_many_lines, - clippy::toplevel_ref_arg, - // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6983 - clippy::wrong_self_convention + clippy::toplevel_ref_arg )] mod app; diff --git a/gen/lib/Android.bp b/gen/lib/Android.bp index 6c8728bd..bcafaa53 100644 --- a/gen/lib/Android.bp +++ b/gen/lib/Android.bp @@ -7,7 +7,7 @@ rust_library_host { cargo_env_compat: true, cargo_pkg_version: "0.7.93", srcs: ["src/lib.rs"], - edition: "2018", + edition: "2021", rustlibs: [ "libcodespan_reporting", "libproc_macro2", diff --git a/gen/lib/Cargo.toml b/gen/lib/Cargo.toml index b4f45b6b..2e400ffb 100644 --- a/gen/lib/Cargo.toml +++ b/gen/lib/Cargo.toml @@ -1,10 +1,11 @@ [package] name = "cxx-gen" -version = "0.7.93" +version = "0.7.119" authors = ["Adrian Taylor <adetaylor@chromium.org>"] categories = ["development-tools::ffi"] description = "C++ code generator for integrating `cxx` crate into higher level tools." -edition = "2018" +documentation = "https://docs.rs/cxx-gen" +edition = "2021" exclude = ["build.rs"] keywords = ["ffi"] license = "MIT OR Apache-2.0" @@ -12,13 +13,14 @@ repository = "https://github.com/dtolnay/cxx" rust-version = "1.60" [dependencies] -codespan-reporting = "0.11" -proc-macro2 = { version = "1.0.39", default-features = false, features = ["span-locations"] } -quote = { version = "1.0", default-features = false } -syn = { version = "2.0.1", default-features = false, features = ["parsing", "printing", "clone-impls", "full"] } +codespan-reporting = "0.11.1" +proc-macro2 = { version = "1.0.74", default-features = false, features = ["span-locations"] } +quote = { version = "1.0.35", default-features = false } +syn = { version = "2.0.46", default-features = false, features = ["clone-impls", "full", "parsing", "printing"] } [lib] doc-scrape-examples = false [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = ["--generate-link-to-definition"] diff --git a/gen/lib/src/error.rs b/gen/lib/src/error.rs index bb53a7fc..79a27bd9 100644 --- a/gen/lib/src/error.rs +++ b/gen/lib/src/error.rs @@ -3,12 +3,23 @@ use std::error::Error as StdError; use std::fmt::{self, Debug, Display}; +use std::iter; #[allow(missing_docs)] pub struct Error { pub(crate) err: crate::gen::Error, } +impl Error { + /// Returns the span of the error, if available. + pub fn span(&self) -> Option<proc_macro2::Span> { + match &self.err { + crate::gen::Error::Syn(err) => Some(err.span()), + _ => None, + } + } +} + impl From<crate::gen::Error> for Error { fn from(err: crate::gen::Error) -> Self { Error { err } @@ -32,3 +43,33 @@ impl StdError for Error { self.err.source() } } + +impl IntoIterator for Error { + type Item = Error; + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + match self.err { + crate::gen::Error::Syn(err) => IntoIter::Syn(err.into_iter()), + _ => IntoIter::Other(iter::once(self)), + } + } +} + +pub enum IntoIter { + Syn(<syn::Error as IntoIterator>::IntoIter), + Other(iter::Once<Error>), +} + +impl Iterator for IntoIter { + type Item = Error; + + fn next(&mut self) -> Option<Self::Item> { + match self { + IntoIter::Syn(iter) => iter + .next() + .map(|syn_err| Error::from(crate::gen::Error::Syn(syn_err))), + IntoIter::Other(iter) => iter.next(), + } + } +} diff --git a/gen/lib/src/lib.rs b/gen/lib/src/lib.rs index 36680b95..12658603 100644 --- a/gen/lib/src/lib.rs +++ b/gen/lib/src/lib.rs @@ -7,7 +7,7 @@ //! [dtolnay/cxx#235]: https://github.com/dtolnay/cxx/issues/235 //! [https://github.com/google/autocxx]: https://github.com/google/autocxx -#![doc(html_root_url = "https://docs.rs/cxx-gen/0.7.93")] +#![doc(html_root_url = "https://docs.rs/cxx-gen/0.7.119")] #![deny(missing_docs)] #![allow(dead_code)] #![allow( @@ -17,27 +17,28 @@ clippy::enum_glob_use, clippy::if_same_then_else, clippy::inherent_to_string, + clippy::into_iter_without_iter, clippy::items_after_statements, clippy::match_bool, clippy::match_on_vec_items, clippy::match_same_arms, clippy::missing_errors_doc, clippy::module_name_repetitions, + clippy::must_use_candidate, clippy::needless_pass_by_value, clippy::new_without_default, clippy::nonminimal_bool, - clippy::option_if_let_else, clippy::or_fun_call, clippy::redundant_else, clippy::shadow_unrelated, clippy::similar_names, clippy::single_match_else, clippy::struct_excessive_bools, + clippy::struct_field_names, clippy::too_many_arguments, clippy::too_many_lines, clippy::toplevel_ref_arg, - // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6983 - clippy::wrong_self_convention + clippy::uninlined_format_args )] mod error; diff --git a/gen/lib/tests/test.rs b/gen/lib/tests/test.rs index d035b522..478daeec 100644 --- a/gen/lib/tests/test.rs +++ b/gen/lib/tests/test.rs @@ -24,5 +24,5 @@ fn test_positive() { fn test_negative() { let rs = quote! {}; let opt = Opt::default(); - assert!(cxx_gen::generate_header_and_cc(rs, &opt).is_err()) + assert!(cxx_gen::generate_header_and_cc(rs, &opt).is_err()); } diff --git a/gen/src/block.rs b/gen/src/block.rs index 96a9a6ee..4e6e6d2b 100644 --- a/gen/src/block.rs +++ b/gen/src/block.rs @@ -1,7 +1,7 @@ use proc_macro2::Ident; #[derive(Copy, Clone, PartialEq, Debug)] -pub enum Block<'a> { +pub(crate) enum Block<'a> { AnonymousNamespace, Namespace(&'static str), UserDefinedNamespace(&'a Ident), @@ -10,7 +10,7 @@ pub enum Block<'a> { } impl<'a> Block<'a> { - pub fn write_begin(self, out: &mut String) { + pub(crate) fn write_begin(self, out: &mut String) { if let Block::InlineNamespace(_) = self { out.push_str("inline "); } @@ -18,7 +18,7 @@ impl<'a> Block<'a> { out.push_str(" {\n"); } - pub fn write_end(self, out: &mut String) { + pub(crate) fn write_end(self, out: &mut String) { out.push_str("} // "); self.write_common(out); out.push('\n'); diff --git a/gen/src/builtin.rs b/gen/src/builtin.rs index 277c64f8..d38473af 100644 --- a/gen/src/builtin.rs +++ b/gen/src/builtin.rs @@ -3,7 +3,7 @@ use crate::gen::ifndef; use crate::gen::out::{Content, OutFile}; #[derive(Default, PartialEq)] -pub struct Builtins<'a> { +pub(crate) struct Builtins<'a> { pub panic: bool, pub rust_string: bool, pub rust_str: bool, @@ -36,7 +36,7 @@ pub struct Builtins<'a> { } impl<'a> Builtins<'a> { - pub fn new() -> Self { + pub(crate) fn new() -> Self { Builtins::default() } } diff --git a/gen/src/cfg.rs b/gen/src/cfg.rs index da589085..adab6e5c 100644 --- a/gen/src/cfg.rs +++ b/gen/src/cfg.rs @@ -4,7 +4,7 @@ use crate::syntax::report::Errors; use crate::syntax::Api; use quote::quote; use std::collections::BTreeSet as Set; -use syn::Error; +use syn::{Error, LitStr}; pub(super) struct UnsupportedCfgEvaluator; @@ -61,7 +61,7 @@ fn try_eval(cfg_evaluator: &dyn CfgEvaluator, expr: &CfgExpr) -> Result<bool, Ve CfgExpr::Unconditional => Ok(true), CfgExpr::Eq(ident, string) => { let key = ident.to_string(); - let value = string.as_ref().map(|string| string.value()); + let value = string.as_ref().map(LitStr::value); match cfg_evaluator.eval(&key, value.as_deref()) { CfgResult::True => Ok(true), CfgResult::False => Ok(false), diff --git a/gen/src/check.rs b/gen/src/check.rs index 15add20a..4b373205 100644 --- a/gen/src/check.rs +++ b/gen/src/check.rs @@ -16,7 +16,7 @@ fn check_dot_includes(cx: &mut Errors, apis: &[Api]) { for api in apis { if let Api::Include(include) = api { let first_component = Path::new(&include.path).components().next(); - if let Some(Component::CurDir) | Some(Component::ParentDir) = first_component { + if let Some(Component::CurDir | Component::ParentDir) = first_component { let begin = quote_spanned!(include.begin_span=> .); let end = quote_spanned!(include.end_span=> .); let span = quote!(#begin #end); diff --git a/gen/src/error.rs b/gen/src/error.rs index 3672e26e..fc42c5c1 100644 --- a/gen/src/error.rs +++ b/gen/src/error.rs @@ -40,7 +40,7 @@ impl StdError for Error { Error::Fs(err) => err.source(), Error::Utf8(_, err) => Some(err), Error::Syn(err) => err.source(), - _ => None, + Error::NoBridgeMod => None, } } } diff --git a/gen/src/file.rs b/gen/src/file.rs index 4e4259ef..d55021aa 100644 --- a/gen/src/file.rs +++ b/gen/src/file.rs @@ -4,7 +4,7 @@ use syn::parse::discouraged::Speculative; use syn::parse::{Error, Parse, ParseStream, Result}; use syn::{braced, Attribute, Ident, Item, Meta, Token, Visibility}; -pub struct File { +pub(crate) struct File { pub modules: Vec<Module>, } diff --git a/gen/src/fs.rs b/gen/src/fs.rs index 7bc3bbcb..a96b551f 100644 --- a/gen/src/fs.rs +++ b/gen/src/fs.rs @@ -14,7 +14,7 @@ pub(crate) struct Error { } impl Error { - pub fn kind(&self) -> io::ErrorKind { + pub(crate) fn kind(&self) -> io::ErrorKind { match &self.source { Some(io_error) => io_error.kind(), None => io::ErrorKind::Other, diff --git a/gen/src/include.rs b/gen/src/include.rs index 62c92320..3b137c7e 100644 --- a/gen/src/include.rs +++ b/gen/src/include.rs @@ -19,7 +19,7 @@ pub struct Include { } #[derive(Default, PartialEq)] -pub struct Includes<'a> { +pub(crate) struct Includes<'a> { pub custom: Vec<Include>, pub algorithm: bool, pub array: bool, @@ -44,15 +44,15 @@ pub struct Includes<'a> { } impl<'a> Includes<'a> { - pub fn new() -> Self { + pub(crate) fn new() -> Self { Includes::default() } - pub fn insert(&mut self, include: impl Into<Include>) { + pub(crate) fn insert(&mut self, include: impl Into<Include>) { self.custom.push(include.into()); } - pub fn has_cxx_header(&self) -> bool { + pub(crate) fn has_cxx_header(&self) -> bool { self.custom .iter() .any(|header| header.path == "rust/cxx.h" || header.path == "rust\\cxx.h") diff --git a/gen/src/mod.rs b/gen/src/mod.rs index f24846a7..7e8ff287 100644 --- a/gen/src/mod.rs +++ b/gen/src/mod.rs @@ -124,7 +124,6 @@ fn generate_from_string(source: &str, opt: &Opt) -> Result<GeneratedCode> { let shebang_end = source.find('\n').unwrap_or(source.len()); source = &source[shebang_end..]; } - proc_macro2::fallback::force(); let syntax: File = syn::parse_str(source)?; generate(syntax, opt) } diff --git a/gen/src/names.rs b/gen/src/names.rs index 834424bb..620aaa85 100644 --- a/gen/src/names.rs +++ b/gen/src/names.rs @@ -1,7 +1,7 @@ use crate::syntax::Pair; impl Pair { - pub fn to_fully_qualified(&self) -> String { + pub(crate) fn to_fully_qualified(&self) -> String { let mut fully_qualified = String::new(); for segment in &self.namespace { fully_qualified += "::"; diff --git a/gen/src/namespace.rs b/gen/src/namespace.rs index b79c38f9..424e9d8e 100644 --- a/gen/src/namespace.rs +++ b/gen/src/namespace.rs @@ -2,7 +2,7 @@ use crate::syntax::namespace::Namespace; use crate::syntax::Api; impl Api { - pub fn namespace(&self) -> &Namespace { + pub(crate) fn namespace(&self) -> &Namespace { match self { Api::CxxFunction(efn) | Api::RustFunction(efn) => &efn.name.namespace, Api::CxxType(ety) | Api::RustType(ety) => &ety.name.namespace, diff --git a/gen/src/nested.rs b/gen/src/nested.rs index 32cc5f15..7b326664 100644 --- a/gen/src/nested.rs +++ b/gen/src/nested.rs @@ -2,21 +2,23 @@ use crate::syntax::map::UnorderedMap as Map; use crate::syntax::Api; use proc_macro2::Ident; -pub struct NamespaceEntries<'a> { +pub(crate) struct NamespaceEntries<'a> { direct: Vec<&'a Api>, nested: Vec<(&'a Ident, NamespaceEntries<'a>)>, } impl<'a> NamespaceEntries<'a> { - pub fn new(apis: Vec<&'a Api>) -> Self { + pub(crate) fn new(apis: Vec<&'a Api>) -> Self { sort_by_inner_namespace(apis, 0) } - pub fn direct_content(&self) -> &[&'a Api] { + pub(crate) fn direct_content(&self) -> &[&'a Api] { &self.direct } - pub fn nested_content(&self) -> impl Iterator<Item = (&'a Ident, &NamespaceEntries<'a>)> { + pub(crate) fn nested_content( + &self, + ) -> impl Iterator<Item = (&'a Ident, &NamespaceEntries<'a>)> { self.nested.iter().map(|(k, entries)| (*k, entries)) } } @@ -56,7 +58,6 @@ mod tests { use crate::syntax::namespace::Namespace; use crate::syntax::{Api, Doc, ExternType, ForeignName, Lang, Lifetimes, Pair}; use proc_macro2::{Ident, Span}; - use std::iter::FromIterator; use syn::punctuated::Punctuated; use syn::Token; diff --git a/gen/src/out.rs b/gen/src/out.rs index 3b4d7392..1cce3635 100644 --- a/gen/src/out.rs +++ b/gen/src/out.rs @@ -17,7 +17,7 @@ pub(crate) struct OutFile<'a> { } #[derive(Default)] -pub struct Content<'a> { +pub(crate) struct Content<'a> { bytes: String, namespace: &'a Namespace, blocks: Vec<BlockBoundary<'a>>, @@ -32,7 +32,7 @@ enum BlockBoundary<'a> { } impl<'a> OutFile<'a> { - pub fn new(header: bool, opt: &'a Opt, types: &'a Types) -> Self { + pub(crate) fn new(header: bool, opt: &'a Opt, types: &'a Types) -> Self { OutFile { header, opt, @@ -44,28 +44,28 @@ impl<'a> OutFile<'a> { } // Write a blank line if the preceding section had any contents. - pub fn next_section(&mut self) { + pub(crate) fn next_section(&mut self) { self.content.get_mut().next_section(); } - pub fn begin_block(&mut self, block: Block<'a>) { + pub(crate) fn begin_block(&mut self, block: Block<'a>) { self.content.get_mut().begin_block(block); } - pub fn end_block(&mut self, block: Block<'a>) { + pub(crate) fn end_block(&mut self, block: Block<'a>) { self.content.get_mut().end_block(block); } - pub fn set_namespace(&mut self, namespace: &'a Namespace) { + pub(crate) fn set_namespace(&mut self, namespace: &'a Namespace) { self.content.get_mut().set_namespace(namespace); } - pub fn write_fmt(&self, args: Arguments) { + pub(crate) fn write_fmt(&self, args: Arguments) { let content = &mut *self.content.borrow_mut(); Write::write_fmt(content, args).unwrap(); } - pub fn content(&mut self) -> Vec<u8> { + pub(crate) fn content(&mut self) -> Vec<u8> { self.flush(); let include = &self.include.content.bytes; let builtin = &self.builtin.content.bytes; @@ -112,19 +112,19 @@ impl<'a> Content<'a> { Content::default() } - pub fn next_section(&mut self) { + pub(crate) fn next_section(&mut self) { self.section_pending = true; } - pub fn begin_block(&mut self, block: Block<'a>) { + pub(crate) fn begin_block(&mut self, block: Block<'a>) { self.push_block_boundary(BlockBoundary::Begin(block)); } - pub fn end_block(&mut self, block: Block<'a>) { + pub(crate) fn end_block(&mut self, block: Block<'a>) { self.push_block_boundary(BlockBoundary::End(block)); } - pub fn set_namespace(&mut self, namespace: &'a Namespace) { + pub(crate) fn set_namespace(&mut self, namespace: &'a Namespace) { for name in self.namespace.iter().rev() { self.end_block(Block::UserDefinedNamespace(name)); } @@ -134,7 +134,7 @@ impl<'a> Content<'a> { self.namespace = namespace; } - pub fn write_fmt(&mut self, args: Arguments) { + pub(crate) fn write_fmt(&mut self, args: Arguments) { Write::write_fmt(self, args).unwrap(); } diff --git a/gen/src/write.rs b/gen/src/write.rs index 6f535ccb..89037e16 100644 --- a/gen/src/write.rs +++ b/gen/src/write.rs @@ -85,10 +85,10 @@ fn write_data_structures<'a>(out: &mut OutFile<'a>, apis: &'a [Api]) { match api { Api::Struct(strct) if !structs_written.contains(&strct.name.rust) => { for next in &mut toposorted_structs { - if !out.types.cxx.contains(&strct.name.rust) { + if !out.types.cxx.contains(&next.name.rust) { out.next_section(); let methods = methods_for_type - .get(&strct.name.rust) + .get(&next.name.rust) .map(Vec::as_slice) .unwrap_or_default(); write_struct(out, next, methods); @@ -129,7 +129,7 @@ fn write_data_structures<'a>(out: &mut OutFile<'a>, apis: &'a [Api]) { for api in apis { if let Api::TypeAlias(ety) = api { if let Some(reasons) = out.types.required_trivial.get(&ety.name.rust) { - check_trivial_extern_type(out, ety, reasons) + check_trivial_extern_type(out, ety, reasons); } } } @@ -205,13 +205,12 @@ fn pick_includes_and_builtins(out: &mut OutFile, apis: &[Api]) { for ty in out.types { match ty { Type::Ident(ident) => match Atom::from(&ident.rust) { - Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(I8) | Some(I16) | Some(I32) - | Some(I64) => out.include.cstdint = true, + Some(U8 | U16 | U32 | U64 | I8 | I16 | I32 | I64) => out.include.cstdint = true, Some(Usize) => out.include.cstddef = true, Some(Isize) => out.builtin.rust_isize = true, Some(CxxString) => out.include.string = true, Some(RustString) => out.builtin.rust_string = true, - Some(Bool) | Some(Char) | Some(F32) | Some(F64) | None => {} + Some(Bool | Char | F32 | F64) | None => {} }, Type::RustBox(_) => out.builtin.rust_box = true, Type::RustVec(_) => out.builtin.rust_vec = true, @@ -848,7 +847,7 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) { match &efn.ret { Some(Type::RustBox(_)) => write!(out, ".into_raw()"), Some(Type::UniquePtr(_)) => write!(out, ".release()"), - Some(Type::Str(_)) | Some(Type::SliceRef(_)) if !indirect_return => write!(out, ")"), + Some(Type::Str(_) | Type::SliceRef(_)) if !indirect_return => write!(out, ")"), _ => {} } if indirect_return { @@ -1182,7 +1181,7 @@ fn write_indirect_return_type_space(out: &mut OutFile, ty: &Type) { fn write_extern_return_type_space(out: &mut OutFile, ty: &Option<Type>) { match ty { - Some(Type::RustBox(ty)) | Some(Type::UniquePtr(ty)) => { + Some(Type::RustBox(ty) | Type::UniquePtr(ty)) => { write_type_space(out, &ty.inner); write!(out, "*"); } @@ -1193,7 +1192,7 @@ fn write_extern_return_type_space(out: &mut OutFile, ty: &Option<Type>) { } write!(out, "*"); } - Some(Type::Str(_)) | Some(Type::SliceRef(_)) => { + Some(Type::Str(_) | Type::SliceRef(_)) => { out.builtin.repr_fat = true; write!(out, "::rust::repr::Fat "); } @@ -1672,6 +1671,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, @@ -1680,6 +1680,7 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) { ); writeln!(out, " ::new (ptr) ::std::unique_ptr<{}>();", inner); writeln!(out, "}}"); + if can_construct_from_value { out.builtin.maybe_uninit = true; begin_function_definition(out); @@ -1697,6 +1698,7 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) { writeln!(out, " return uninit;"); writeln!(out, "}}"); } + begin_function_definition(out); writeln!( out, @@ -1705,6 +1707,7 @@ 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, @@ -1713,6 +1716,7 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) { ); writeln!(out, " return ptr.get();"); writeln!(out, "}}"); + begin_function_definition(out); writeln!( out, @@ -1721,6 +1725,7 @@ fn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) { ); writeln!(out, " return ptr.release();"); writeln!(out, "}}"); + begin_function_definition(out); writeln!( out, @@ -1765,6 +1770,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, @@ -1773,6 +1779,7 @@ fn write_shared_ptr(out: &mut OutFile, key: NamedImplKey) { ); writeln!(out, " ::new (ptr) ::std::shared_ptr<{}>();", inner); writeln!(out, "}}"); + if can_construct_from_value { out.builtin.maybe_uninit = true; begin_function_definition(out); @@ -1790,6 +1797,7 @@ fn write_shared_ptr(out: &mut OutFile, key: NamedImplKey) { writeln!(out, " return uninit;"); writeln!(out, "}}"); } + begin_function_definition(out); writeln!( out, @@ -1798,6 +1806,7 @@ fn write_shared_ptr(out: &mut OutFile, key: NamedImplKey) { ); writeln!(out, " ::new (ptr) ::std::shared_ptr<{}>(self);", inner); writeln!(out, "}}"); + begin_function_definition(out); writeln!( out, @@ -1806,6 +1815,7 @@ fn write_shared_ptr(out: &mut OutFile, key: NamedImplKey) { ); writeln!(out, " return self.get();"); writeln!(out, "}}"); + begin_function_definition(out); writeln!( out, @@ -1834,6 +1844,8 @@ fn write_weak_ptr(out: &mut OutFile, key: NamedImplKey) { "static_assert(alignof(::std::weak_ptr<{}>) == alignof(void *), \"\");", inner, ); + + begin_function_definition(out); writeln!( out, "void cxxbridge1$weak_ptr${}$null(::std::weak_ptr<{}> *ptr) noexcept {{", @@ -1841,6 +1853,7 @@ 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, @@ -1849,6 +1862,7 @@ fn write_weak_ptr(out: &mut OutFile, key: NamedImplKey) { ); writeln!(out, " ::new (ptr) ::std::weak_ptr<{}>(self);", inner); writeln!(out, "}}"); + begin_function_definition(out); writeln!( out, @@ -1857,6 +1871,7 @@ fn write_weak_ptr(out: &mut OutFile, key: NamedImplKey) { ); writeln!(out, " ::new (weak) ::std::weak_ptr<{}>(shared);", inner); writeln!(out, "}}"); + begin_function_definition(out); writeln!( out, @@ -1869,6 +1884,7 @@ fn write_weak_ptr(out: &mut OutFile, key: NamedImplKey) { inner, ); writeln!(out, "}}"); + begin_function_definition(out); writeln!( out, @@ -1888,6 +1904,16 @@ fn write_cxx_vector(out: &mut OutFile, key: NamedImplKey) { out.include.utility = true; out.builtin.destroy = true; + begin_function_definition(out); + writeln!( + out, + "::std::vector<{}> *cxxbridge1$std$vector${}$new() noexcept {{", + inner, instance, + ); + writeln!(out, " return new ::std::vector<{}>();", inner); + writeln!(out, "}}"); + + begin_function_definition(out); writeln!( out, "::std::size_t cxxbridge1$std$vector${}$size(::std::vector<{}> const &s) noexcept {{", |