diff --git a/rs_bindings_from_cc/BUILD b/rs_bindings_from_cc/BUILD index 3c1ee9cc9..5d15e6190 100644 --- a/rs_bindings_from_cc/BUILD +++ b/rs_bindings_from_cc/BUILD @@ -51,6 +51,7 @@ deps_for_bindings( "//support:forward_declare", "//support:oops", "//support:bridge_rust", + "//support:cref", "//support/rs_std:dyn_callable_rs", "//support/rs_std:lossy_formatter", # Required for `Copy` trait assertions added to the generated Rust diff --git a/rs_bindings_from_cc/generate_bindings/database/rs_snippet.rs b/rs_bindings_from_cc/generate_bindings/database/rs_snippet.rs index c9a6c3a33..e7d6b05a7 100644 --- a/rs_bindings_from_cc/generate_bindings/database/rs_snippet.rs +++ b/rs_bindings_from_cc/generate_bindings/database/rs_snippet.rs @@ -463,6 +463,7 @@ pub enum RsTypeKind { referent: Rc, mutability: Mutability, lifetime: Lifetime, + is_cref: bool, }, RvalueReference { referent: Rc, @@ -1260,7 +1261,10 @@ impl RsTypeKind { "`self` has no lifetime. Use lifetime annotations to create bindings for this function." ) } - RsTypeKind::Reference { referent, lifetime, mutability } => { + RsTypeKind::Reference { referent, lifetime, mutability, is_cref } => { + if *is_cref { + bail!("Internal error (crubit.rs-bug): `self` should not be CRef/CMut."); + }; let mut_ = mutability.format_for_reference(); let lifetime = lifetime.format_for_reference(); if mutability == &Mutability::Mut && !referent.is_unpin() { @@ -1469,12 +1473,20 @@ impl RsTypeKind { quote! {* #mutability #pointee_ } } } - RsTypeKind::Reference { referent, mutability, lifetime } => { + RsTypeKind::Reference { referent, mutability, lifetime, is_cref } => { let mut_ = mutability.format_for_reference(); let lifetime = lifetime.format_for_reference(); let referent_ = referent.to_token_stream_replacing_by_self(db, self_record); - let mut tokens = quote! {& #lifetime #mut_ #referent_}; + let mut tokens = if *is_cref { + match mutability { + Mutability::Mut => quote! {cref::CMut<#lifetime, #referent_> }, + Mutability::Const => quote! { cref::CRef<#lifetime, #referent_> }, + } + } else { + quote! {& #lifetime #mut_ #referent_ } + }; if mutability == &Mutability::Mut && !referent.is_unpin() { + // TODO(zarko): Is Pin right for cref here? tokens = quote! {::core::pin::Pin< #tokens >}; } tokens @@ -1747,12 +1759,20 @@ impl RsTypeKind { quote! {* #mutability #pointee_tokens } } } - RsTypeKind::Reference { referent, mutability, lifetime } => { - let mut_ = mutability.format_for_reference(); + RsTypeKind::Reference { referent, mutability, lifetime, is_cref } => { let lifetime = lifetime.format_for_reference(); let referent_tokens = referent.to_token_stream(db); - let mut tokens = quote! {& #lifetime #mut_ #referent_tokens}; + let mut tokens = if *is_cref { + match mutability { + Mutability::Mut => quote! {cref::CMut<#lifetime, #referent_tokens> }, + Mutability::Const => quote! { cref::CRef<#lifetime, #referent_tokens> }, + } + } else { + let mut_ = mutability.format_for_reference(); + quote! {& #lifetime #mut_ #referent_tokens} + }; if mutability == &Mutability::Mut && !referent.is_unpin() { + // TODO(zarko): Is this the right thing for CRef? tokens = quote! { ::core::pin::Pin< #tokens > }; } tokens @@ -2119,6 +2139,7 @@ mod tests { referent, mutability: Mutability::Const, lifetime: Lifetime::new("_"), + is_cref: false, }; assert_rs_matches!(reference.to_token_stream(EmptyDatabase), quote! {&::T}); } @@ -2177,6 +2198,7 @@ mod tests { referent: Rc::new(int.clone()), mutability: Mutability::Const, lifetime: Lifetime::new("_"), + is_cref: false, }; for func_ptr in [ RsTypeKind::FuncPtr { diff --git a/rs_bindings_from_cc/generate_bindings/generate_function.rs b/rs_bindings_from_cc/generate_bindings/generate_function.rs index 5dbbf45e1..4e11a8e72 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_function.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_function.rs @@ -1054,6 +1054,8 @@ fn adjust_param_types_for_trait_impl( referent: Rc::new(param_type.clone()), mutability: Mutability::Const, lifetime: Lifetime::new("_"), + // This is a parameter type, so we don't want to lower to CRef. + is_cref: false, }; (quote! {&mut }, quote! {.clone()}) }) diff --git a/rs_bindings_from_cc/generate_bindings/generate_function_test.rs b/rs_bindings_from_cc/generate_bindings/generate_function_test.rs index ef3b3399f..268dd6f57 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_function_test.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_function_test.rs @@ -1980,7 +1980,7 @@ fn test_simple_explicit_lifetime() -> Result<()> { rs_api, quote! { #[inline(always)] - pub fn Add<'a>(x: &'a mut ::ffi_11::c_int) -> &'a mut ::ffi_11::c_int { + pub fn Add<'a>(x: &'a mut ::ffi_11::c_int) -> cref::CMut<'a, ::ffi_11::c_int> { unsafe { crate::detail::__rust_thunk___Z3AddRi(x) } } } @@ -1993,7 +1993,7 @@ fn test_simple_explicit_lifetime() -> Result<()> { use super::*; unsafe extern "C" { #[link_name = "_Z3AddRi"] - pub(crate) unsafe fn __rust_thunk___Z3AddRi<'a>(x: &'a mut ::ffi_11::c_int) -> &'a mut ::ffi_11::c_int; + pub(crate) unsafe fn __rust_thunk___Z3AddRi<'a>(x: &'a mut ::ffi_11::c_int) -> cref::CMut<'a, ::ffi_11::c_int>; } } } diff --git a/rs_bindings_from_cc/generate_bindings/lifetime_defaults_transform.rs b/rs_bindings_from_cc/generate_bindings/lifetime_defaults_transform.rs index be692dd3d..79f7875dc 100644 --- a/rs_bindings_from_cc/generate_bindings/lifetime_defaults_transform.rs +++ b/rs_bindings_from_cc/generate_bindings/lifetime_defaults_transform.rs @@ -41,7 +41,7 @@ fn lifetime_arity(db: &BindingsGenerator, ty: &CcType) -> Result { } } -fn record_lifetime_arity(db: &BindingsGenerator, rc: &Record) -> Result { +fn record_lifetime_arity(_db: &BindingsGenerator, rc: &Record) -> Result { // TODO(zarko): Handle the effects of [[lifetimebound]] et al on arity. Ok(rc.lifetime_inputs.len()) } @@ -333,6 +333,7 @@ impl<'a, 'db> LifetimeDefaults<'a, 'db> { /// assigned. fn add_lifetime_to_output_type( &mut self, + use_crefs: bool, lifetime_hint: &Vec>, new_bindings: &mut Vec>, ty: &CcType, @@ -374,15 +375,22 @@ impl<'a, 'db> LifetimeDefaults<'a, 'db> { .get_or_push_new_binding(l, |name| new_bindings.push(name.clone())) }) .collect(); + // TODO(zarko): Recurse on pty.pointee_type. + new_ty.variant = + CcTypeVariant::Pointer(PointerType { is_cref: use_crefs, ..pty.clone() }); return Ok(new_ty); } // If there is no viable inferred lifetime, we need to downgrade this to a raw // pointer. We can at least mark it non-null. (An argument could be made about // doing this later on provided we have a fuller treatement of safe/unsafe types // selected by the presence of lifetime inputs.) - let kind = - if lifetime_hint.is_empty() { PointerTypeKind::NonNull } else { pty.kind }; + let (kind, is_cref) = if lifetime_hint.is_empty() { + (PointerTypeKind::NonNull, false) + } else { + (pty.kind, use_crefs && pty.kind == PointerTypeKind::LValueRef) + }; let pointee_type = self.add_lifetime_to_output_type( + use_crefs, lifetime_hint, new_bindings, &pty.pointee_type, @@ -390,6 +398,7 @@ impl<'a, 'db> LifetimeDefaults<'a, 'db> { new_ty.variant = CcTypeVariant::Pointer(PointerType { pointee_type: pointee_type.into(), kind, + is_cref, ..pty.clone() }); new_ty.explicit_lifetimes = lifetime_hint.clone(); @@ -498,6 +507,7 @@ impl<'a, 'db> LifetimeDefaults<'a, 'db> { let mut this_state = LifetimeState::Unseen; let mut had_this = false; new_func.lifetime_inputs.clear(); + let is_operator = matches!(func.cc_name, ir::UnqualifiedIdentifier::Operator(_)); // Note that we generate a new LifetimeDefaults per Item that we're importing, so we don't // need to pop these bindings. (We *do* need to worry about unbinding names for internal // binders, like function types.) @@ -530,6 +540,7 @@ impl<'a, 'db> LifetimeDefaults<'a, 'db> { _ => self.get_lifetime_for_state(&this_state), }; new_func.return_type = self.add_lifetime_to_output_type( + !is_operator, &lifetime, &mut new_func.lifetime_inputs, &new_func.return_type, diff --git a/rs_bindings_from_cc/generate_bindings/rs_type_kind.rs b/rs_bindings_from_cc/generate_bindings/rs_type_kind.rs index cbcef5bb6..0370a762f 100644 --- a/rs_bindings_from_cc/generate_bindings/rs_type_kind.rs +++ b/rs_bindings_from_cc/generate_bindings/rs_type_kind.rs @@ -77,9 +77,12 @@ pub fn rs_type_kind_with_lifetime_elision( } }; Ok(match pointer.kind { - PointerTypeKind::LValueRef => { - RsTypeKind::Reference { referent: pointee, mutability, lifetime } - } + PointerTypeKind::LValueRef => RsTypeKind::Reference { + referent: pointee, + mutability, + lifetime, + is_cref: pointer.is_cref, + }, PointerTypeKind::RValueRef => { RsTypeKind::RvalueReference { referent: pointee, mutability, lifetime } } diff --git a/rs_bindings_from_cc/test/assume_lifetimes/BUILD b/rs_bindings_from_cc/test/assume_lifetimes/BUILD index fb0e45f24..ca66c4fdf 100644 --- a/rs_bindings_from_cc/test/assume_lifetimes/BUILD +++ b/rs_bindings_from_cc/test/assume_lifetimes/BUILD @@ -38,6 +38,7 @@ crubit_rust_test( ":free_function", ], deps = [ + "//support:cref", "@crate_index//:googletest", ], ) @@ -67,6 +68,7 @@ crubit_rust_test( ":member_function", ], deps = [ + "//support:cref", "@crate_index//:googletest", ], ) @@ -102,6 +104,38 @@ crubit_rust_test( ], ) +crubit_test_cc_library( + name = "crefs", + srcs = ["crefs.cc"], + hdrs = ["crefs.h"], + aspect_hints = [ + "//features:experimental", + ], + deps = [ + ":test_annotations", + ], +) + +golden_test( + name = "crefs_golden_test", + basename = "crefs", + cc_library = "crefs", + golden_cc = "crefs_api_impl.cc", + golden_rs = "crefs_rs_api.rs", +) + +crubit_rust_test( + name = "crefs_test", + srcs = ["crefs_test.rs"], + cc_deps = [ + ":crefs", + ], + deps = [ + "//support:cref", + "@crate_index//:googletest", + ], +) + crubit_test_cc_library( name = "string_view", srcs = ["string_view.cc"], diff --git a/rs_bindings_from_cc/test/assume_lifetimes/crefs.cc b/rs_bindings_from_cc/test/assume_lifetimes/crefs.cc new file mode 100644 index 000000000..768588412 --- /dev/null +++ b/rs_bindings_from_cc/test/assume_lifetimes/crefs.cc @@ -0,0 +1,8 @@ +// Part of the Crubit project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "rs_bindings_from_cc/test/assume_lifetimes/crefs.h" + +int& id_cmut(int& x) { return x; } +const int& id_cref(const int& x) { return x; } diff --git a/rs_bindings_from_cc/test/assume_lifetimes/crefs.h b/rs_bindings_from_cc/test/assume_lifetimes/crefs.h new file mode 100644 index 000000000..d45b1a8f1 --- /dev/null +++ b/rs_bindings_from_cc/test/assume_lifetimes/crefs.h @@ -0,0 +1,11 @@ +// Part of the Crubit project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_ASSUME_LIFETIMES_CREF_H_ +#define THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_ASSUME_LIFETIMES_CREF_H_ + +int& id_cmut(int& x); +const int& id_cref(const int& x); + +#endif // THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_ASSUME_LIFETIMES_CREF_H_ diff --git a/rs_bindings_from_cc/test/assume_lifetimes/crefs_api_impl.cc b/rs_bindings_from_cc/test/assume_lifetimes/crefs_api_impl.cc new file mode 100644 index 000000000..03380675b --- /dev/null +++ b/rs_bindings_from_cc/test/assume_lifetimes/crefs_api_impl.cc @@ -0,0 +1,24 @@ +// Part of the Crubit project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// Automatically @generated Rust bindings for the following C++ target: +// //rs_bindings_from_cc/test/assume_lifetimes:crefs +// Features: assume_lifetimes, assume_this_lifetimes, callables, check_default_initialized, experimental, fmt, supported, types, unsafe_view, wrapper + +#include "support/internal/cxx20_backports.h" +#include "support/internal/offsetof.h" + +#include + +// Public headers of the C++ library being wrapped. +#include "rs_bindings_from_cc/test/assume_lifetimes/crefs.h" + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wthread-safety-analysis" + +static_assert((int& (*)(int&)) & ::id_cmut); + +static_assert((int const& (*)(int const&)) & ::id_cref); + +#pragma clang diagnostic pop diff --git a/rs_bindings_from_cc/test/assume_lifetimes/crefs_rs_api.rs b/rs_bindings_from_cc/test/assume_lifetimes/crefs_rs_api.rs new file mode 100644 index 000000000..631fd8d9f --- /dev/null +++ b/rs_bindings_from_cc/test/assume_lifetimes/crefs_rs_api.rs @@ -0,0 +1,42 @@ +// Part of the Crubit project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// Automatically @generated Rust bindings for the following C++ target: +// //rs_bindings_from_cc/test/assume_lifetimes:crefs +// Features: assume_lifetimes, assume_this_lifetimes, callables, check_default_initialized, experimental, fmt, supported, types, unsafe_view, wrapper + +#![rustfmt::skip] +#![feature(custom_inner_attributes)] +#![allow(stable_features)] +#![allow(improper_ctypes)] +#![allow(nonstandard_style)] +#![allow(unused)] +#![deny(warnings)] + +/// Generated from: rs_bindings_from_cc/test/assume_lifetimes/crefs.h;l=8 +#[inline(always)] +pub fn id_cmut<'x>(x: &'x mut ::ffi_11::c_int) -> cref::CMut<'x, ::ffi_11::c_int> { + unsafe { crate::detail::__rust_thunk___Z7id_cmutRi(x) } +} + +/// Generated from: rs_bindings_from_cc/test/assume_lifetimes/crefs.h;l=9 +#[inline(always)] +pub fn id_cref<'x>(x: &'x ::ffi_11::c_int) -> cref::CRef<'x, ::ffi_11::c_int> { + unsafe { crate::detail::__rust_thunk___Z7id_crefRKi(x) } +} + +mod detail { + #[allow(unused_imports)] + use super::*; + unsafe extern "C" { + #[link_name = "_Z7id_cmutRi"] + pub(crate) unsafe fn __rust_thunk___Z7id_cmutRi<'x>( + x: &'x mut ::ffi_11::c_int, + ) -> cref::CMut<'x, ::ffi_11::c_int>; + #[link_name = "_Z7id_crefRKi"] + pub(crate) unsafe fn __rust_thunk___Z7id_crefRKi<'x>( + x: &'x ::ffi_11::c_int, + ) -> cref::CRef<'x, ::ffi_11::c_int>; + } +} diff --git a/rs_bindings_from_cc/test/assume_lifetimes/crefs_test.rs b/rs_bindings_from_cc/test/assume_lifetimes/crefs_test.rs new file mode 100644 index 000000000..f829ec509 --- /dev/null +++ b/rs_bindings_from_cc/test/assume_lifetimes/crefs_test.rs @@ -0,0 +1,15 @@ +// Part of the Crubit project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +use cref::*; +use googletest::prelude::*; + +#[gtest] +fn int_test() { + let x = 1; + let _xref: CRef<'_, i32> = crefs::id_cref(&x); + + let mut y = 2; + let _ymut: CMut<'_, i32> = crefs::id_cmut(&mut y); +} diff --git a/rs_bindings_from_cc/test/assume_lifetimes/free_function_rs_api.rs b/rs_bindings_from_cc/test/assume_lifetimes/free_function_rs_api.rs index caeea03c2..ff97af50e 100644 --- a/rs_bindings_from_cc/test/assume_lifetimes/free_function_rs_api.rs +++ b/rs_bindings_from_cc/test/assume_lifetimes/free_function_rs_api.rs @@ -16,7 +16,7 @@ /// Generated from: rs_bindings_from_cc/test/assume_lifetimes/free_function.h;l=8 #[inline(always)] -pub fn increment_int_ref<'a>(a: &'a mut ::ffi_11::c_int) -> &'a mut ::ffi_11::c_int { +pub fn increment_int_ref<'a>(a: &'a mut ::ffi_11::c_int) -> cref::CMut<'a, ::ffi_11::c_int> { unsafe { crate::detail::__rust_thunk___Z17increment_int_refRi(a) } } @@ -27,6 +27,6 @@ mod detail { #[link_name = "_Z17increment_int_refRi"] pub(crate) unsafe fn __rust_thunk___Z17increment_int_refRi<'a>( a: &'a mut ::ffi_11::c_int, - ) -> &'a mut ::ffi_11::c_int; + ) -> cref::CMut<'a, ::ffi_11::c_int>; } } diff --git a/rs_bindings_from_cc/test/assume_lifetimes/free_function_test.rs b/rs_bindings_from_cc/test/assume_lifetimes/free_function_test.rs index 16bda2e6b..181a5a8d0 100644 --- a/rs_bindings_from_cc/test/assume_lifetimes/free_function_test.rs +++ b/rs_bindings_from_cc/test/assume_lifetimes/free_function_test.rs @@ -2,12 +2,15 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +use cref::*; use googletest::prelude::*; #[gtest] fn increment_int_ref_test() { let mut x = 1; let y = free_function::increment_int_ref(&mut x); - expect_eq!(*y, 2); + unsafe { + expect_eq!(*CMut::as_ptr(y), 2); + } expect_eq!(x, 2); } diff --git a/rs_bindings_from_cc/test/assume_lifetimes/member_function_rs_api.rs b/rs_bindings_from_cc/test/assume_lifetimes/member_function_rs_api.rs index d493d4b66..154e54d9f 100644 --- a/rs_bindings_from_cc/test/assume_lifetimes/member_function_rs_api.rs +++ b/rs_bindings_from_cc/test/assume_lifetimes/member_function_rs_api.rs @@ -30,12 +30,12 @@ unsafe impl ::cxx::ExternType for S { impl S { /// Generated from: rs_bindings_from_cc/test/assume_lifetimes/member_function.h;l=9 #[inline(always)] - pub fn int_accessor<'__this>(&'__this self) -> &'__this ::ffi_11::c_int { + pub fn int_accessor<'__this>(&'__this self) -> cref::CRef<'__this, ::ffi_11::c_int> { unsafe { crate::detail::__rust_thunk___ZNK1S12int_accessorEv(self) } } /// Generated from: rs_bindings_from_cc/test/assume_lifetimes/member_function.h;l=10 #[inline(always)] - pub fn me<'__this>(&'__this mut self) -> &'__this mut crate::S { + pub fn me<'__this>(&'__this mut self) -> cref::CMut<'__this, crate::S> { unsafe { crate::detail::__rust_thunk___ZN1S2meEv(self) } } } @@ -59,10 +59,10 @@ mod detail { pub(crate) unsafe fn __rust_thunk___ZN1SC1Ev(__this: *mut ::core::ffi::c_void); pub(crate) unsafe fn __rust_thunk___ZNK1S12int_accessorEv<'__this>( __this: &'__this crate::S, - ) -> &'__this ::ffi_11::c_int; + ) -> cref::CRef<'__this, ::ffi_11::c_int>; pub(crate) unsafe fn __rust_thunk___ZN1S2meEv<'__this>( __this: &'__this mut crate::S, - ) -> &'__this mut crate::S; + ) -> cref::CMut<'__this, crate::S>; } } diff --git a/rs_bindings_from_cc/test/assume_lifetimes/member_function_test.rs b/rs_bindings_from_cc/test/assume_lifetimes/member_function_test.rs index 1344553ce..3848a99b5 100644 --- a/rs_bindings_from_cc/test/assume_lifetimes/member_function_test.rs +++ b/rs_bindings_from_cc/test/assume_lifetimes/member_function_test.rs @@ -2,19 +2,24 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +use cref::*; use googletest::prelude::*; #[gtest] fn my_test() { let s = member_function::S::default(); let int_field = s.int_accessor(); - assert_eq!(*int_field, 42); + unsafe { + assert_eq!(*CRef::as_ptr(int_field), 42); + } } #[gtest] fn self_reference_test() { let mut s = member_function::S::default(); - let s_ref: &mut member_function::S = member_function::S::me(&mut s); - let int_field = s_ref.int_accessor(); - assert_eq!(*int_field, 42); + let s_ref: CMut<'_, member_function::S> = member_function::S::me(&mut s); + unsafe { + let int_field = (*CMut::as_ptr(s_ref)).int_accessor(); + assert_eq!(*CRef::as_ptr(int_field), 42); + } } diff --git a/rs_bindings_from_cc/test/templates/definition_in_cc/BUILD b/rs_bindings_from_cc/test/templates/definition_in_cc/BUILD index fff7d77d4..3048c508a 100644 --- a/rs_bindings_from_cc/test/templates/definition_in_cc/BUILD +++ b/rs_bindings_from_cc/test/templates/definition_in_cc/BUILD @@ -17,6 +17,7 @@ crubit_rust_test( srcs = ["test.rs"], cc_deps = [":definition_in_cc"], deps = [ + "//support:cref", "@crate_index//:googletest", ], ) diff --git a/rs_bindings_from_cc/test/templates/definition_in_cc/test.rs b/rs_bindings_from_cc/test/templates/definition_in_cc/test.rs index 75ee365bc..d6a85ffb9 100644 --- a/rs_bindings_from_cc/test/templates/definition_in_cc/test.rs +++ b/rs_bindings_from_cc/test/templates/definition_in_cc/test.rs @@ -2,10 +2,13 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +use cref::*; use googletest::prelude::*; #[gtest] fn test_member_function_of_class_template_defined_in_cc_file() { let s = definition_in_cc::MyTypeAlias::Create(123); - assert_eq!(123, *s.value()); + unsafe { + assert_eq!(123, *CRef::as_ptr(s.value())); + } } diff --git a/rs_bindings_from_cc/test/templates/extern_definition/BUILD b/rs_bindings_from_cc/test/templates/extern_definition/BUILD index fe575f62e..de75e570e 100644 --- a/rs_bindings_from_cc/test/templates/extern_definition/BUILD +++ b/rs_bindings_from_cc/test/templates/extern_definition/BUILD @@ -26,6 +26,7 @@ crubit_rust_test( ":extern_definition", ], deps = [ + "//support:cref", "@crate_index//:googletest", ], ) diff --git a/rs_bindings_from_cc/test/templates/extern_definition/test.rs b/rs_bindings_from_cc/test/templates/extern_definition/test.rs index 7f2d86c0a..cbb3758df 100644 --- a/rs_bindings_from_cc/test/templates/extern_definition/test.rs +++ b/rs_bindings_from_cc/test/templates/extern_definition/test.rs @@ -3,10 +3,13 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception use actual_instantiation::*; +use cref::*; use googletest::prelude::*; #[gtest] fn test_member_function_of_class_template_defined_in_cc_file() { let s = actual_instantiation_ns::MyTypeAlias::Create(123); - assert_eq!(123, *s.value()); + unsafe { + assert_eq!(123, *CRef::as_ptr(s.value())); + } } diff --git a/rs_bindings_from_cc/test/templates/func_return_and_param_types/BUILD b/rs_bindings_from_cc/test/templates/func_return_and_param_types/BUILD index bf4549ffa..045a2d48d 100644 --- a/rs_bindings_from_cc/test/templates/func_return_and_param_types/BUILD +++ b/rs_bindings_from_cc/test/templates/func_return_and_param_types/BUILD @@ -17,6 +17,7 @@ crubit_rust_test( srcs = ["test.rs"], cc_deps = [":func_return_and_param_types"], deps = [ + "//support:cref", "@crate_index//:googletest", ], ) diff --git a/rs_bindings_from_cc/test/templates/func_return_and_param_types/test.rs b/rs_bindings_from_cc/test/templates/func_return_and_param_types/test.rs index 2a32ae9e6..6466e953f 100644 --- a/rs_bindings_from_cc/test/templates/func_return_and_param_types/test.rs +++ b/rs_bindings_from_cc/test/templates/func_return_and_param_types/test.rs @@ -2,6 +2,7 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +use cref::*; use func_return_and_param_types::*; use googletest::prelude::*; @@ -15,7 +16,9 @@ fn test_template_instantiation_in_return_value_and_parameter_type() { // Class template instantiation used as a function return type. let s = CreateInstanceOfMyTemplate(123); - assert_eq!(123, *s.value()); + unsafe { + assert_eq!(123, *CRef::as_ptr(s.value())); + } // Const-ref to class template instantiation used as a function parameter type. let d = DoubleInstanceOfMyTemplate(&s); diff --git a/rs_bindings_from_cc/test/templates/no_instantiation_in_template_target/BUILD b/rs_bindings_from_cc/test/templates/no_instantiation_in_template_target/BUILD index 65fff8354..2df70318b 100644 --- a/rs_bindings_from_cc/test/templates/no_instantiation_in_template_target/BUILD +++ b/rs_bindings_from_cc/test/templates/no_instantiation_in_template_target/BUILD @@ -27,6 +27,7 @@ crubit_rust_test( ":type_alias_in_different_target", ], deps = [ + "//support:cref", "@crate_index//:googletest", ], ) diff --git a/rs_bindings_from_cc/test/templates/no_instantiation_in_template_target/test.rs b/rs_bindings_from_cc/test/templates/no_instantiation_in_template_target/test.rs index 9e75917f2..394cdfcf4 100644 --- a/rs_bindings_from_cc/test/templates/no_instantiation_in_template_target/test.rs +++ b/rs_bindings_from_cc/test/templates/no_instantiation_in_template_target/test.rs @@ -2,10 +2,13 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +use cref::*; use googletest::prelude::*; #[gtest] fn test_alias_to_template_without_instantiation_in_different_target() { let s = type_alias_in_different_target::TypeAliasInDifferentTarget::Create(321); - assert_eq!(321, *s.value()); + unsafe { + assert_eq!(321, *CRef::as_ptr(s.value())); + } } diff --git a/rs_bindings_from_cc/test/templates/out_of_line_definition/BUILD b/rs_bindings_from_cc/test/templates/out_of_line_definition/BUILD index 68f9acd1e..f7610de57 100644 --- a/rs_bindings_from_cc/test/templates/out_of_line_definition/BUILD +++ b/rs_bindings_from_cc/test/templates/out_of_line_definition/BUILD @@ -16,6 +16,7 @@ crubit_rust_test( srcs = ["test.rs"], cc_deps = [":out_of_line_definition"], deps = [ + "//support:cref", "@crate_index//:googletest", ], ) diff --git a/rs_bindings_from_cc/test/templates/out_of_line_definition/test.rs b/rs_bindings_from_cc/test/templates/out_of_line_definition/test.rs index 87dee46f7..1e8ff4eef 100644 --- a/rs_bindings_from_cc/test/templates/out_of_line_definition/test.rs +++ b/rs_bindings_from_cc/test/templates/out_of_line_definition/test.rs @@ -2,10 +2,13 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +use cref::*; use googletest::prelude::*; #[gtest] fn test_member_function_of_class_template_defined_out_of_line_in_h_file() { let s = out_of_line_definition::MyTypeAlias::Create(123); - assert_eq!(123, *s.value()); + unsafe { + assert_eq!(123, *CRef::as_ptr(s.value())); + } } diff --git a/rs_bindings_from_cc/test/templates/struct_fields/BUILD b/rs_bindings_from_cc/test/templates/struct_fields/BUILD index 4a715a68a..57d8ea234 100644 --- a/rs_bindings_from_cc/test/templates/struct_fields/BUILD +++ b/rs_bindings_from_cc/test/templates/struct_fields/BUILD @@ -16,6 +16,7 @@ crubit_rust_test( srcs = ["test.rs"], cc_deps = [":struct_fields"], deps = [ + "//support:cref", "@crate_index//:googletest", ], ) diff --git a/rs_bindings_from_cc/test/templates/struct_fields/test.rs b/rs_bindings_from_cc/test/templates/struct_fields/test.rs index 7cab16a9c..30783c9d7 100644 --- a/rs_bindings_from_cc/test/templates/struct_fields/test.rs +++ b/rs_bindings_from_cc/test/templates/struct_fields/test.rs @@ -2,6 +2,7 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +use cref::*; use googletest::prelude::*; use struct_fields::*; @@ -15,5 +16,7 @@ fn test_template_instantiation_in_return_value_and_parameter_type() { // Class template instantiation used as a type of a public field. let s = MyStruct { public_field: 123.into() }; - assert_eq!(123, *s.public_field.value()); + unsafe { + assert_eq!(123, *CRef::as_ptr(s.public_field.value())); + } } diff --git a/rs_bindings_from_cc/test/templates/type_alias/BUILD b/rs_bindings_from_cc/test/templates/type_alias/BUILD index 5c1d69c71..cc3c5039c 100644 --- a/rs_bindings_from_cc/test/templates/type_alias/BUILD +++ b/rs_bindings_from_cc/test/templates/type_alias/BUILD @@ -38,6 +38,7 @@ crubit_rust_test( ":type_alias_in_different_target", ], deps = [ + "//support:cref", "//support:forward_declare", "@crate_index//:googletest", ], diff --git a/rs_bindings_from_cc/test/templates/type_alias/type_alias_rs_api.rs b/rs_bindings_from_cc/test/templates/type_alias/type_alias_rs_api.rs index cd35747cc..a176bf574 100644 --- a/rs_bindings_from_cc/test/templates/type_alias/type_alias_rs_api.rs +++ b/rs_bindings_from_cc/test/templates/type_alias/type_alias_rs_api.rs @@ -52,7 +52,7 @@ impl __CcTemplateInst10MyTemplateIiE { } /// Generated from: rs_bindings_from_cc/test/templates/type_alias/type_alias.h;l=19 #[inline(always)] - pub fn value<'__this>(&'__this self) -> &'__this ::ffi_11::c_int { + pub fn value<'__this>(&'__this self) -> cref::CRef<'__this, ::ffi_11::c_int> { unsafe { crate::detail::__rust_thunk___ZNK10MyTemplateIiE5valueEv__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2ftemplates_2ftype_5falias_3atype_5falias(self) } @@ -86,7 +86,7 @@ mod detail { '__this, >( __this: &'__this crate::__CcTemplateInst10MyTemplateIiE, - ) -> &'__this ::ffi_11::c_int; + ) -> cref::CRef<'__this, ::ffi_11::c_int>; } } diff --git a/rs_bindings_from_cc/test/templates/type_alias/type_alias_test.rs b/rs_bindings_from_cc/test/templates/type_alias/type_alias_test.rs index a99e5f025..8ccd83cbd 100644 --- a/rs_bindings_from_cc/test/templates/type_alias/type_alias_test.rs +++ b/rs_bindings_from_cc/test/templates/type_alias/type_alias_test.rs @@ -2,29 +2,38 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +use cref::*; use forward_declare::CppCast; use googletest::prelude::*; #[gtest] fn test_alias_to_template_instantiation() { let s = type_alias::MyTypeAlias::Create(123); - assert_eq!(123, *s.value()); + unsafe { + assert_eq!(123, *CRef::as_ptr(s.value())); + } } #[gtest] fn test_aliases_in_same_target_are_compatible() { let s: type_alias::MyTypeAlias = type_alias::MyTypeAlias::Create(456); let s2: type_alias::OtherTypeAliasInSameTarget = s; - assert_eq!(456, *s2.value()); + unsafe { + assert_eq!(456, *CRef::as_ptr(s2.value())); + } } #[gtest] fn test_alias_in_different_target_than_template() { let s = type_alias_in_different_target::TypeAliasInDifferentTarget::Create(789); - assert_eq!(789, *s.value()); + unsafe { + assert_eq!(789, *CRef::as_ptr(s.value())); + } // Template instantiation from `type_alias_in_different_target` can be cast // (i.e. transmuted) into identical instantiation from `type_alias` crate. let s2: type_alias::MyTypeAlias = s.cpp_cast(); - assert_eq!(789, *s2.value()); + unsafe { + assert_eq!(789, *CRef::as_ptr(s2.value())); + } } diff --git a/rs_bindings_from_cc/test/types/BUILD b/rs_bindings_from_cc/test/types/BUILD index 5ba540563..fee5e02cf 100644 --- a/rs_bindings_from_cc/test/types/BUILD +++ b/rs_bindings_from_cc/test/types/BUILD @@ -41,6 +41,7 @@ crubit_rust_test( ], proc_macro_deps = ["//common:item_exists"], deps = [ + "//support:cref", "//support/ffi_11", "@crate_index//:googletest", ], diff --git a/rs_bindings_from_cc/test/types/types_test.rs b/rs_bindings_from_cc/test/types/types_test.rs index f12206cb0..c0190e909 100644 --- a/rs_bindings_from_cc/test/types/types_test.rs +++ b/rs_bindings_from_cc/test/types/types_test.rs @@ -6,6 +6,7 @@ use core::cell::Cell; use core::ffi::c_void; +use cref::*; use googletest::prelude::*; trait ParameterIs

{} @@ -227,8 +228,8 @@ struct_field_type_is!( function_return_type_is!(types_inferred_lifetimes, IntP => *mut i32, ConstIntP => *const i32, - IntRef => &mut i32, - ConstIntRef => &i32, + IntRef => CMut<'_, i32>, + ConstIntRef => CRef<'_, i32>, VoidP => *mut c_void, ConstVoidP => *const c_void, // TODO: b/436971180 - Why is this a pointer? @@ -236,8 +237,8 @@ function_return_type_is!(types_inferred_lifetimes, StructPtr => *mut types_inferred_lifetimes::ExampleStruct, ConstStructPtr => *const types_inferred_lifetimes::ExampleStruct, - StructRef => &mut types_inferred_lifetimes::ExampleStruct, - ConstStructRef => &types_inferred_lifetimes::ExampleStruct, + StructRef => CMut<'_, types_inferred_lifetimes::ExampleStruct>, + ConstStructRef => CRef<'_, types_inferred_lifetimes::ExampleStruct>, ); function_parameter_type_is!(types_inferred_lifetimes,