diff --git a/cc_bindings_from_rs/cc_bindings_from_rs.rs b/cc_bindings_from_rs/cc_bindings_from_rs.rs index 364b34a4e..74501953d 100644 --- a/cc_bindings_from_rs/cc_bindings_from_rs.rs +++ b/cc_bindings_from_rs/cc_bindings_from_rs.rs @@ -32,7 +32,7 @@ use std::rc::Rc; use cmdline::Cmdline; use code_gen_utils::CcInclude; use error_report::{ErrorReport, ErrorReporting, FatalErrors, ReportFatalError}; -use generate_bindings::{Database, IncludeGuard}; +use generate_bindings::{BindingsGenerator, IncludeGuard}; use kythe_metadata::cc_embed_provenance_map; use run_compiler::run_compiler; use token_stream_printer::{ @@ -58,7 +58,7 @@ fn new_db<'tcx>( tcx: TyCtxt<'tcx>, errors: Rc, fatal_errors: Rc, -) -> Database<'tcx> { +) -> BindingsGenerator<'tcx> { let mut crate_name_to_include_paths = , Vec>>::new(); for (crate_name, include_path) in &cmdline.crate_headers { let paths = crate_name_to_include_paths.entry(crate_name.as_str().into()).or_default(); diff --git a/cc_bindings_from_rs/generate_bindings/database/db.rs b/cc_bindings_from_rs/generate_bindings/database/db.rs index 3f94c8781..9d848c7dc 100644 --- a/cc_bindings_from_rs/generate_bindings/database/db.rs +++ b/cc_bindings_from_rs/generate_bindings/database/db.rs @@ -24,7 +24,7 @@ use std::collections::HashMap; use std::rc::Rc; memoized::query_group! { - pub trait BindingsGenerator<'tcx> { + pub struct BindingsGenerator<'tcx> { #[input] /// Compilation context for the crate that the bindings should be generated /// for. @@ -282,5 +282,4 @@ memoized::query_group! { /// Implementation: cc_bindings_from_rs/generate_bindings/generate_struct_and_union.rs?q=function:local_from_trait_impls_by_argument fn from_trait_impls_by_argument(&self, crate_num: CrateNum) -> Rc, Vec>>; } - pub struct Database; } diff --git a/cc_bindings_from_rs/generate_bindings/database/fully_qualified_name.rs b/cc_bindings_from_rs/generate_bindings/database/fully_qualified_name.rs index 3a0a9145e..3c3ac2a47 100644 --- a/cc_bindings_from_rs/generate_bindings/database/fully_qualified_name.rs +++ b/cc_bindings_from_rs/generate_bindings/database/fully_qualified_name.rs @@ -64,7 +64,7 @@ pub struct FullyQualifiedName { } fn format_ns_path_for_cc( - db: &dyn BindingsGenerator<'_>, + db: &BindingsGenerator<'_>, ns: &NamespaceQualifier, ) -> Result { let idents = @@ -73,7 +73,7 @@ fn format_ns_path_for_cc( } impl FullyQualifiedName { - pub fn format_for_cc(&self, db: &dyn BindingsGenerator<'_>) -> Result { + pub fn format_for_cc(&self, db: &BindingsGenerator<'_>) -> Result { if let Some(path) = self.unqualified.cpp_type { let path = format_cc_type_name(path.as_str())?; return Ok(path); diff --git a/cc_bindings_from_rs/generate_bindings/database/lib.rs b/cc_bindings_from_rs/generate_bindings/database/lib.rs index d2534dfe8..fba2ec6d9 100644 --- a/cc_bindings_from_rs/generate_bindings/database/lib.rs +++ b/cc_bindings_from_rs/generate_bindings/database/lib.rs @@ -12,7 +12,7 @@ mod adt_core_bindings; pub use adt_core_bindings::{AdtCoreBindings, NoMoveOrAssign}; pub mod cpp_type; mod db; -pub use db::{BindingsGenerator, Database}; +pub use db::BindingsGenerator; mod fine_grained_feature; pub use fine_grained_feature::FineGrainedFeature; mod fully_qualified_name; diff --git a/cc_bindings_from_rs/generate_bindings/format_type.rs b/cc_bindings_from_rs/generate_bindings/format_type.rs index 634639582..c39faa0b0 100644 --- a/cc_bindings_from_rs/generate_bindings/format_type.rs +++ b/cc_bindings_from_rs/generate_bindings/format_type.rs @@ -35,10 +35,7 @@ use rustc_span::symbol::Symbol; use std::rc::Rc; /// Implementation of `BindingsGenerator::format_top_level_ns_for_crate`. -pub fn format_top_level_ns_for_crate( - db: &dyn BindingsGenerator<'_>, - krate: CrateNum, -) -> Rc<[Symbol]> { +pub fn format_top_level_ns_for_crate(db: &BindingsGenerator<'_>, krate: CrateNum) -> Rc<[Symbol]> { let mut crate_name = if krate == db.source_crate_num() { "self".to_string() } else { @@ -55,12 +52,12 @@ pub fn format_top_level_ns_for_crate( } } -pub fn format_cc_ident_symbol(db: &dyn BindingsGenerator, ident: Symbol) -> Result { +pub fn format_cc_ident_symbol(db: &BindingsGenerator, ident: Symbol) -> Result { format_cc_ident(db, ident.as_str()) } /// Implementation of `BindingsGenerator::format_cc_ident`. -pub fn format_cc_ident(db: &dyn BindingsGenerator, ident: &str) -> Result { +pub fn format_cc_ident(db: &BindingsGenerator, ident: &str) -> Result { // TODO(b/254104998): Check whether the crate where the identifier is defined is // enabled for the feature. Right now if the dep enables the feature but the // current crate doesn't, we will escape the identifier in the dep but @@ -74,7 +71,7 @@ pub fn format_cc_ident(db: &dyn BindingsGenerator, ident: &str) -> Result } pub fn format_pointer_or_reference_ty_for_cc<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, pointee: SugaredTy<'tcx>, mutability: Mutability, pointer_sigil: TokenStream, @@ -93,7 +90,7 @@ pub fn format_pointer_or_reference_ty_for_cc<'tcx>( } pub fn format_slice_pointer_for_cc<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, slice_ty: SugaredTy<'tcx>, mutability: rustc_middle::mir::Mutability, ) -> Result { @@ -119,12 +116,12 @@ pub fn format_slice_pointer_for_cc<'tcx>( } /// Returns a CcSnippet referencing `rs_std::StrRef` and its include path. -pub fn format_str_ref_for_cc(db: &dyn BindingsGenerator<'_>) -> CcSnippet { +pub fn format_str_ref_for_cc(db: &BindingsGenerator<'_>) -> CcSnippet { CcSnippet::with_include(quote! { rs_std::StrRef }, db.support_header("rs_std/str_ref.h")) } pub fn format_transparent_pointee_or_reference_for_cc<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, referent_ty: Ty<'tcx>, mutability: rustc_middle::mir::Mutability, pointer_sigil: TokenStream, @@ -146,7 +143,7 @@ pub fn format_transparent_pointee_or_reference_for_cc<'tcx>( /// Implementation of `BindingsGenerator::format_ty_for_cc`. pub fn format_ty_for_cc<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, ty: SugaredTy<'tcx>, location: TypeLocation, ) -> Result { @@ -543,7 +540,7 @@ fn treat_ref_as_ptr<'tcx>( /// Returns the C++ return type. pub fn format_ret_ty_for_cc<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, sig_mid: &ty::FnSig<'tcx>, ) -> Result { let output_ty = SugaredTy::fn_output(sig_mid); @@ -589,7 +586,7 @@ pub struct CcParamTy { /// Returns the C++ parameter types. pub fn format_param_types_for_cc<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, sig_mid: &ty::FnSig<'tcx>, has_self_param: bool, ) -> Result> { @@ -614,7 +611,7 @@ pub fn format_param_types_for_cc<'tcx>( } fn try_ty_as_maybe_uninit<'tcx>( - db: &dyn BindingsGenerator<'_>, + db: &BindingsGenerator<'_>, ty: &Ty<'tcx>, ) -> Option> { if let ty::TyKind::Adt(adt, substs) = ty.kind() { @@ -627,7 +624,7 @@ fn try_ty_as_maybe_uninit<'tcx>( /// Format a supported `repr(transparent)` pointee type pub fn format_transparent_pointee<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, ty: &Ty<'tcx>, ) -> Result { let Some(generic_arg) = try_ty_as_maybe_uninit(db, ty) else { @@ -642,7 +639,7 @@ fn has_non_lifetime_substs(substs: &[ty::GenericArg]) -> bool { } fn format_fn_ptr_for_rs<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, binder_with_fn_sig_tys: ty::Binder>>, fn_header: ty::FnHeader>, ) -> Result { @@ -698,10 +695,7 @@ fn format_fn_ptr_for_rs<'tcx>( /// than just `SomeStruct`. // // TODO(b/259724276): This function's results should be memoized. -pub fn format_ty_for_rs<'tcx>( - db: &dyn BindingsGenerator<'tcx>, - ty: Ty<'tcx>, -) -> Result { +pub fn format_ty_for_rs<'tcx>(db: &BindingsGenerator<'tcx>, ty: Ty<'tcx>) -> Result { Ok(match ty.kind() { ty::TyKind::Bool | ty::TyKind::Float(_) @@ -806,7 +800,7 @@ pub fn format_ty_for_rs<'tcx>( } pub fn format_region_as_cc_lifetime<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, region: &ty::Region<'tcx>, prereqs: &mut CcPrerequisites, ) -> TokenStream { @@ -885,10 +879,7 @@ fn layout_pointer_like(from: &Layout, data_layout: &TargetDataLayout) -> bool { } /// Returns an error if `ty` is not pointer-like. -pub fn ensure_ty_is_pointer_like<'tcx>( - db: &dyn BindingsGenerator<'tcx>, - ty: Ty<'tcx>, -) -> Result<()> { +pub fn ensure_ty_is_pointer_like<'tcx>(db: &BindingsGenerator<'tcx>, ty: Ty<'tcx>) -> Result<()> { if let ty::TyKind::Adt(adt, _) = ty.kind() { if !adt.repr().transparent() { bail!("Can't convert {ty} to a C++ pointer as it's not `repr(transparent)`"); @@ -908,7 +899,7 @@ pub fn ensure_ty_is_pointer_like<'tcx>( } pub fn crubit_abi_type_from_ty<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, ty: Ty<'tcx>, ) -> Result { Ok(CrubitAbiTypeWithCcPrereqs::from(match ty.kind() { @@ -1027,7 +1018,7 @@ pub enum BridgedBuiltin { impl BridgedBuiltin { /// Determines if an AdtDef is for a Result or Option or neither. - pub fn new(db: &dyn BindingsGenerator<'_>, adt: AdtDef<'_>) -> Option { + pub fn new(db: &BindingsGenerator<'_>, adt: AdtDef<'_>) -> Option { let variant = adt.variants().iter().next()?; match db.tcx().lang_items().from_def_id(variant.def_id) { @@ -1042,7 +1033,7 @@ impl BridgedBuiltin { /// Returns an error is `crubit_abi_type_from_ty` fails for any of the generic args. pub fn crubit_abi_type<'tcx>( self, - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, substs: &[GenericArg<'tcx>], ) -> Result { match self { @@ -1081,7 +1072,7 @@ impl BridgedBuiltin { /// Returns a CrubitAbiType for a manually annotated composable bridged ADT. /// May return an error is `crubit_abi_type_from_ty` fails for any of the generic args. fn crubit_abi_type_from_bridged_adt<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, abi_rust: Symbol, abi_cpp: Symbol, substs: &[GenericArg<'tcx>], @@ -1115,7 +1106,7 @@ fn crubit_abi_type_from_bridged_adt<'tcx>( /// Returns None if the type is not manually annotated as bridged. /// Returns an error if getting the bridging attributes fails. fn is_manually_annotated_bridged_adt<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, ty: Ty<'tcx>, ) -> Result> { // We take a `Ty` instead of adt + substs directly so we can use `Ty` in error messages. @@ -1198,7 +1189,7 @@ fn is_manually_annotated_bridged_adt<'tcx>( /// is configured. An error is returned if the type is a pointer or reference or /// the attribute could not be parsed or is in an invalid state. pub fn is_bridged_type<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, ty: Ty<'tcx>, ) -> Result> { match ty.kind() { diff --git a/cc_bindings_from_rs/generate_bindings/generate_function.rs b/cc_bindings_from_rs/generate_bindings/generate_function.rs index b6d239602..f4e37ad2b 100644 --- a/cc_bindings_from_rs/generate_bindings/generate_function.rs +++ b/cc_bindings_from_rs/generate_bindings/generate_function.rs @@ -61,7 +61,7 @@ impl FunctionKind { } fn thunk_name( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, def_id: DefId, export_name: Option, needs_thunk: bool, @@ -129,7 +129,7 @@ fn ident_for_each(prefix: &str, n: usize) -> Vec { /// Returns a `TokenStream` containing an expression that evaluates to the /// C-ABI-compatible version of the type. fn cc_param_to_c_abi<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, cc_ident: Ident, ty: SugaredTy<'tcx>, post_analysis_typing_env: ty::TypingEnv<'tcx>, @@ -243,7 +243,7 @@ struct ReturnConversion { } fn format_ty_for_cc_amending_prereqs<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, ty: SugaredTy<'tcx>, prereqs: &mut CcPrerequisites, ) -> Result { @@ -254,7 +254,7 @@ fn format_ty_for_cc_amending_prereqs<'tcx>( } fn cc_return_value_from_c_abi<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, ident: Ident, ty: SugaredTy<'tcx>, prereqs: &mut CcPrerequisites, @@ -477,7 +477,7 @@ struct RefsToCheckForAliasing<'a, 'tcx> { /// C++ does not have this requirement, so we insert checks in the generated bindings to ensure that /// this requirement is not violated. fn refs_to_check_for_aliasing<'tcx, 'a>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, params: &'a [Param<'tcx>], ) -> Option> { let tcx = db.tcx(); @@ -543,7 +543,7 @@ impl ThunkSelfParameter { /// Generates the wrapping code to call a thunk and return its result. /// This can be checking parameter invariants or creating a slot to pass as an output pointer. pub(crate) fn generate_thunk_call<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, def_id: DefId, thunk_name: Ident, rs_return_type: SugaredTy<'tcx>, @@ -656,7 +656,7 @@ pub(crate) fn generate_thunk_call<'tcx>( } /// Implementation of `BindingsGenerator::generate_function`. -pub fn generate_function(db: &dyn BindingsGenerator<'_>, def_id: DefId) -> Result { +pub fn generate_function(db: &BindingsGenerator<'_>, def_id: DefId) -> Result { let tcx = db.tcx(); ensure!( !tcx.generics_of(def_id).requires_monomorphization(tcx), diff --git a/cc_bindings_from_rs/generate_bindings/generate_function_thunk.rs b/cc_bindings_from_rs/generate_bindings/generate_function_thunk.rs index e19a49047..12f42713f 100644 --- a/cc_bindings_from_rs/generate_bindings/generate_function_thunk.rs +++ b/cc_bindings_from_rs/generate_bindings/generate_function_thunk.rs @@ -80,7 +80,7 @@ fn array_c_abi_c_type<'tcx>(tcx: ty::TyCtxt<'tcx>, inner_ty: ty::Ty<'tcx>) -> Re /// Formats a C++ declaration of a C-ABI-compatible-function wrapper around a Rust function. pub fn generate_thunk_decl<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, sig_mid: &ty::FnSig<'tcx>, thunk_name: &Ident, has_self_param: bool, @@ -180,7 +180,7 @@ pub fn generate_thunk_decl<'tcx>( /// Expects an exising local of type `cpp_type` named `local_name` and shadows it /// with a local of type `ty` named `local_name`. fn convert_bridged_type_from_c_abi_to_rust<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, ty: ty::Ty<'tcx>, bridged_type: &BridgedType, local_name: &Ident, @@ -234,7 +234,7 @@ fn convert_bridged_type_from_c_abi_to_rust<'tcx>( /// Converts a local named `local_name` from its C ABI-compatible type /// `*const [*const core::ffi::c_void; ]` to a tuple of Rust types. fn convert_tuple_from_c_abi_to_rust<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, tuple_tys: &[ty::Ty<'tcx>], local_name: &Ident, extern_c_decls: &mut BTreeSet, @@ -263,7 +263,7 @@ fn convert_tuple_from_c_abi_to_rust<'tcx>( /// Returns code to convert a local named `local_name` from its C ABI-compatible type to its Rust /// type. fn convert_value_from_c_abi_to_rust<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, ty: ty::Ty<'tcx>, local_name: &Ident, extern_c_decls: &mut BTreeSet, @@ -290,7 +290,7 @@ fn convert_value_from_c_abi_to_rust<'tcx>( } fn c_abi_for_param_type<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, ty: ty::Ty<'tcx>, ) -> Result { let tcx = db.tcx(); @@ -378,7 +378,7 @@ fn add_extern_c_decl( /// Writes a Rust value out into the memory pointed to a `*mut c_void` pointed to by `c_ptr`. fn write_rs_value_to_c_abi_ptr<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, rs_value: &Ident, c_ptr: &Ident, rs_type: ty::Ty<'tcx>, @@ -496,7 +496,7 @@ where /// - `<::crate_name::some_module::SomeStruct as /// ::core::default::Default>::default` pub fn generate_thunk_impl<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, fn_def_id: DefId, sig: &ty::FnSig<'tcx>, thunk_name: &str, @@ -628,7 +628,7 @@ pub struct TraitThunks { } pub fn generate_trait_thunks<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, trait_id: DefId, // We do not support other generic args, yet. type_args: &[Ty<'tcx>], diff --git a/cc_bindings_from_rs/generate_bindings/generate_struct_and_union.rs b/cc_bindings_from_rs/generate_bindings/generate_struct_and_union.rs index d6e35bfe6..55085afeb 100644 --- a/cc_bindings_from_rs/generate_bindings/generate_struct_and_union.rs +++ b/cc_bindings_from_rs/generate_bindings/generate_struct_and_union.rs @@ -74,7 +74,7 @@ pub fn cpp_enum_rust_underlying_type(tcx: TyCtxt, def_id: DefId) -> Result { /// Returns the C++ underlying type of the `cpp_enum` struct specified by the given def id. pub(crate) fn cpp_enum_cpp_underlying_type( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, def_id: DefId, ) -> Result { let tcx = db.tcx(); @@ -183,7 +183,7 @@ pub fn scalar_value_to_string(tcx: TyCtxt, scalar: Scalar, kind: TyKind) -> Resu /// }; /// ``` fn generate_cpp_enum<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, core: Rc>, ) -> ApiSnippets { let tcx = db.tcx(); @@ -286,7 +286,7 @@ fn is_supported_associated_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool } pub(crate) fn generate_associated_item<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, assoc_item: &ty::AssocItem, member_function_names: &mut HashSet, ) -> Option { @@ -352,7 +352,7 @@ fn erase_regions<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { } pub fn from_trait_impls_by_argument<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, crate_num: CrateNum, ) -> Rc, Vec>> { let tcx = db.tcx(); @@ -391,7 +391,7 @@ pub fn from_trait_impls_by_argument<'tcx>( } fn generate_into_impls<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, core: &AdtCoreBindings<'tcx>, ) -> ApiSnippets { let tcx = db.tcx(); @@ -527,7 +527,7 @@ fn generate_into_impls<'tcx>( /// `generate_adt_core` returns success we have committed to emitting C++ /// bindings for the ADT. pub fn generate_adt<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, core: Rc>, ) -> ApiSnippets { let tcx = db.tcx(); @@ -727,7 +727,7 @@ pub fn generate_adt<'tcx>( /// Implementation of `BindingsGenerator::adt_needs_bindings`. pub fn adt_needs_bindings<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, def_id: DefId, ) -> Result>> { let tcx = db.tcx(); @@ -761,7 +761,7 @@ pub fn adt_needs_bindings<'tcx>( /// Implementation of `BindingsGenerator::generate_adt_core`. pub fn generate_adt_core<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, def_id: DefId, ) -> Result>> { let tcx = db.tcx(); @@ -873,7 +873,7 @@ fn anonymous_field_ident(index: usize) -> Ident { } fn generate_tuple_struct_ctor<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, core: Rc>, ) -> Option { let tcx = db.tcx(); @@ -970,7 +970,7 @@ fn generate_tuple_struct_ctor<'tcx>( /// Returns the body of the C++ struct that represents the given ADT. fn generate_fields<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, core: &AdtCoreBindings<'tcx>, member_function_names: &HashSet, ) -> ApiSnippets { @@ -1693,7 +1693,7 @@ fn generate_fields<'tcx>( /// Generates the `(UnsafeRelocateTag, T&&)` constructor for the given ADT. fn generate_relocating_ctor<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, core: Rc>, ) -> ApiSnippets { let adt_cc_name = &core.cc_short_name; diff --git a/cc_bindings_from_rs/generate_bindings/lib.rs b/cc_bindings_from_rs/generate_bindings/lib.rs index 6e498434c..88cd8cffc 100644 --- a/cc_bindings_from_rs/generate_bindings/lib.rs +++ b/cc_bindings_from_rs/generate_bindings/lib.rs @@ -39,10 +39,10 @@ use arc_anyhow::{Context, Error, Result}; use code_gen_utils::{format_cc_includes, CcConstQualifier, CcInclude, NamespaceQualifier}; use database::code_snippet::{ApiSnippets, CcPrerequisites, CcSnippet, ExternCDecl, RsSnippet}; use database::{ - AdtCoreBindings, BindingsGenerator, ExportedPath, FineGrainedFeature, FullyQualifiedName, - NoMoveOrAssign, PublicPaths, SugaredTy, TypeLocation, UnqualifiedName, + AdtCoreBindings, ExportedPath, FineGrainedFeature, FullyQualifiedName, NoMoveOrAssign, + PublicPaths, SugaredTy, TypeLocation, UnqualifiedName, }; -pub use database::{Database, IncludeGuard}; +pub use database::{BindingsGenerator, IncludeGuard}; use error_report::{anyhow, bail, ErrorReporting, ReportFatalError}; use itertools::Itertools; use proc_macro2::TokenStream; @@ -66,7 +66,7 @@ use std::iter::once; use std::rc::Rc; /// Implementation of `BindingsGenerator::support_header`. -fn support_header<'tcx>(db: &dyn BindingsGenerator<'tcx>, suffix: &'tcx str) -> CcInclude { +fn support_header<'tcx>(db: &BindingsGenerator<'tcx>, suffix: &'tcx str) -> CcInclude { CcInclude::support_lib_header(db.crubit_support_path_format(), suffix.into()) } @@ -75,7 +75,7 @@ pub struct BindingsTokens { pub cc_api_impl: TokenStream, } -fn add_include_guard(db: &dyn BindingsGenerator<'_>, cc_api: TokenStream) -> Result { +fn add_include_guard(db: &BindingsGenerator<'_>, cc_api: TokenStream) -> Result { let metadata_block = if db.kythe_annotations() { quote! { __HASH_TOKEN__ ifdef KYTHE_IS_RUNNING __NEWLINE__ @@ -112,13 +112,13 @@ fn add_include_guard(db: &dyn BindingsGenerator<'_>, cc_api: TokenStream) -> Res /// Wrap `repr_attrs` for use as a database function. fn repr_attrs_from_db( - db: &dyn BindingsGenerator<'_>, + db: &BindingsGenerator<'_>, def_id: DefId, ) -> Rc<[rustc_hir::attrs::ReprAttr]> { repr_attrs(db.tcx(), def_id) } -fn source_crate_num(db: &dyn BindingsGenerator<'_>) -> CrateNum { +fn source_crate_num(db: &BindingsGenerator<'_>) -> CrateNum { // This is a temporary workaround while migrating to the rmeta interface. Our old implementation // breaks with some rmeta files, notably proto files, due to crate renaming behavior. But our // new implementation relies on assuming our source is the placeholder file provided by @@ -188,8 +188,8 @@ pub fn new_database<'db>( fatal_errors: Rc, no_thunk_name_mangling: bool, h_out_include_guard: IncludeGuard, -) -> Database<'db> { - Database::new( +) -> BindingsGenerator<'db> { + BindingsGenerator::new( tcx, source_crate_name, crubit_support_path_format, @@ -229,7 +229,7 @@ pub fn new_database<'db>( ) } -pub fn generate_bindings(db: &Database) -> Result { +pub fn generate_bindings(db: &BindingsGenerator) -> Result { let tcx = db.tcx(); let top_comment = { @@ -301,7 +301,7 @@ pub fn generate_bindings(db: &Database) -> Result { } fn crate_features( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, krate: CrateNum, ) -> flagset::FlagSet { let crate_features = db.crate_name_to_features(); @@ -314,7 +314,7 @@ fn crate_features( } fn check_feature_enabled_on_self_and_all_deps( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, feature: FineGrainedFeature, ) -> bool { for (_, crate_features) in db.crate_name_to_features().iter() { @@ -326,7 +326,7 @@ fn check_feature_enabled_on_self_and_all_deps( } fn format_with_cc_body( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, ns: &NamespaceQualifier, mut tokens: TokenStream, attributes: Vec, @@ -362,7 +362,7 @@ fn format_with_cc_body( /// Implementation of `BindingsGenerator::public_paths_by_def_id`. fn public_paths_by_def_id( - db: &dyn BindingsGenerator<'_>, + db: &BindingsGenerator<'_>, crate_num: CrateNum, ) -> HashMap { /// This is retooled logic from rustc's `visible_parent_map` function. Except where that only @@ -489,7 +489,7 @@ fn module_children(tcx: TyCtxt<'_>, parent: DefId) -> &[ModChild] { } } -fn resolve_if_use(db: &dyn BindingsGenerator<'_>, def_id: DefId) -> Option { +fn resolve_if_use(db: &BindingsGenerator<'_>, def_id: DefId) -> Option { let tcx = db.tcx(); let DefKind::Use = tcx.def_kind(def_id) else { return None; @@ -505,10 +505,7 @@ fn resolve_if_use(db: &dyn BindingsGenerator<'_>, def_id: DefId) -> Option, - def_id: DefId, -) -> Option { +fn symbol_unqualified_name(db: &BindingsGenerator<'_>, def_id: DefId) -> Option { let tcx = db.tcx(); let item_name = db .public_paths_by_def_id(def_id.krate) @@ -533,10 +530,7 @@ fn symbol_unqualified_name( } /// Implementation of `BindingsGenerator::symbol_canonical_name`. -fn symbol_canonical_name( - db: &dyn BindingsGenerator<'_>, - def_id: DefId, -) -> Option { +fn symbol_canonical_name(db: &BindingsGenerator<'_>, def_id: DefId) -> Option { let tcx = db.tcx(); // TODO: b/433286909 - We shouldn't pass DefKind::Use to this method and instead should keep what our use @@ -615,7 +609,7 @@ fn symbol_canonical_name( /// Checks whether a definition matches a specific qualified name by matching it's definition path /// against `name`. Name must include the crate in it's path. -fn matches_qualified_name(db: &dyn BindingsGenerator<'_>, item_did: DefId, name: &[&str]) -> bool { +fn matches_qualified_name(db: &BindingsGenerator<'_>, item_did: DefId, name: &[&str]) -> bool { let tcx = db.tcx(); let path = tcx.def_path(item_did); if path.data.len() + 1 != name.len() { @@ -717,7 +711,7 @@ fn generate_deprecated_tag(tcx: TyCtxt, def_id: DefId) -> Option { } fn generate_using( - db: &dyn BindingsGenerator<'_>, + db: &BindingsGenerator<'_>, using_name: &Symbol, def_id: DefId, ) -> Result { @@ -761,7 +755,7 @@ fn generate_using( } } -fn generate_const(db: &dyn BindingsGenerator<'_>, def_id: DefId) -> Result { +fn generate_const(db: &BindingsGenerator<'_>, def_id: DefId) -> Result { let tcx = db.tcx(); // TODO: b/457843120 - Remove this workaround once we can properly support float constants. let unsupported_consts = [ @@ -827,7 +821,7 @@ fn generate_const(db: &dyn BindingsGenerator<'_>, def_id: DefId) -> Result) -> Rc<[DefId]> { +fn supported_traits(db: &BindingsGenerator<'_>) -> Rc<[DefId]> { let tcx = db.tcx(); let traits = tcx .visible_traits() @@ -857,10 +851,7 @@ fn supported_traits(db: &dyn BindingsGenerator<'_>) -> Rc<[DefId]> { Rc::from(traits) } -fn generate_trait( - db: &dyn BindingsGenerator<'_>, - trait_id: DefId, -) -> arc_anyhow::Result { +fn generate_trait(db: &BindingsGenerator<'_>, trait_id: DefId) -> arc_anyhow::Result { if !db.supported_traits().contains(&trait_id) { bail!("Trait is not yet supported") } @@ -886,7 +877,7 @@ fn generate_trait( } fn generate_type_alias( - db: &dyn BindingsGenerator<'_>, + db: &BindingsGenerator<'_>, def_id: DefId, using_name: &str, ) -> Result { @@ -897,7 +888,7 @@ fn generate_type_alias( } fn create_type_alias<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, def_id: DefId, alias_name: &str, alias_type: SugaredTy<'tcx>, @@ -926,11 +917,11 @@ fn create_type_alias<'tcx>( /// Implementation of `BindingsGenerator::generate_default_ctor`. fn generate_default_ctor<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, core: Rc>, ) -> Result { fn fallible_format_default_ctor<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, core: Rc>, ) -> Result { let tcx = db.tcx(); @@ -996,11 +987,11 @@ fn generate_default_ctor<'tcx>( /// Implementation of `BindingsGenerator::generate_copy_ctor_and_assignment_operator`. fn generate_copy_ctor_and_assignment_operator<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, core: Rc>, ) -> Result { fn fallible_format_copy_ctor_and_assignment_operator<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, core: Rc>, ) -> Result { let tcx = db.tcx(); @@ -1081,11 +1072,11 @@ fn generate_copy_ctor_and_assignment_operator<'tcx>( /// Implementation of `BindingsGenerator::generate_move_ctor_and_assignment_operator`. #[allow(clippy::result_large_err)] fn generate_move_ctor_and_assignment_operator<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, core: Rc>, ) -> Result { fn fallible_format_move_ctor_and_assignment_operator<'tcx>( - db: &dyn BindingsGenerator<'tcx>, + db: &BindingsGenerator<'tcx>, core: Rc>, ) -> Result { let tcx = db.tcx(); @@ -1199,7 +1190,7 @@ fn generate_move_ctor_and_assignment_operator<'tcx>( /// /// Will panic if `def_id` doesn't identify an ADT that can be successfully /// handled by `generate_adt_core`. -fn generate_fwd_decl(db: &Database<'_>, def_id: DefId) -> TokenStream { +fn generate_fwd_decl(db: &BindingsGenerator<'_>, def_id: DefId) -> TokenStream { // `generate_fwd_decl` should only be called for items from // `CcPrerequisites::fwd_decls` and `fwd_decls` should only contain ADTs // that `generate_adt_core` succeeds for. @@ -1223,7 +1214,7 @@ fn generate_fwd_decl(db: &Database<'_>, def_id: DefId) -> TokenStream { } fn generate_kythe_doc_comment( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, def_id: DefId, doc_comment: String, ) -> TokenStream { @@ -1246,7 +1237,7 @@ fn generate_kythe_doc_comment( quote! { __CAPTURE_TAG__ #file_name #start #end __COMMENT__ #doc_comment} } -fn generate_source_location(db: &dyn BindingsGenerator, def_id: DefId) -> String { +fn generate_source_location(db: &BindingsGenerator, def_id: DefId) -> String { let tcx = db.tcx(); let def_span = tcx.def_span(def_id); let rustc_span::FileLines { file, lines } = @@ -1274,7 +1265,7 @@ fn generate_source_location(db: &dyn BindingsGenerator, def_id: DefId) -> String /// Formats the doc comment (if any) associated with the item identified by /// `local_def_id`, and appends the source location at which the item is /// defined. -fn generate_doc_comment(db: &dyn BindingsGenerator, def_id: DefId) -> TokenStream { +fn generate_doc_comment(db: &BindingsGenerator, def_id: DefId) -> TokenStream { let mut docs = db .tcx() .get_all_attrs(def_id) @@ -1299,14 +1290,11 @@ fn generate_doc_comment(db: &dyn BindingsGenerator, def_id: DefId) -> TokenStrea /// Returns the name of the item identified by `def_id`, or "" if /// the item can't be identified. -fn item_name(db: &dyn BindingsGenerator<'_>, def_id: DefId) -> Symbol { +fn item_name(db: &BindingsGenerator<'_>, def_id: DefId) -> Symbol { db.tcx().opt_item_name(def_id).unwrap_or_else(|| Symbol::intern("")) } -fn item_name_for_error_report( - db: &dyn BindingsGenerator<'_>, - def_id: DefId, -) -> error_report::ItemName { +fn item_name_for_error_report(db: &BindingsGenerator<'_>, def_id: DefId) -> error_report::ItemName { let name = format!( "{}::{}", db.tcx().crate_name(db.source_crate_num()), @@ -1318,7 +1306,7 @@ fn item_name_for_error_report( } /// Implementation of `BindingsGenerator::generate_item`. -fn generate_item(db: &dyn BindingsGenerator<'_>, def_id: DefId) -> Result> { +fn generate_item(db: &BindingsGenerator<'_>, def_id: DefId) -> Result> { let tcx = db.tcx(); let generated = generate_item_impl(db, def_id); let attributes = crubit_attr::get_attrs(tcx, def_id).unwrap(); @@ -1349,10 +1337,7 @@ macro_rules! error_scope { // A helper for `generate_item`. // The wrapper is used to ensure that the `must_bind` annotation is enforced. -fn generate_item_impl( - db: &dyn BindingsGenerator<'_>, - def_id: DefId, -) -> Result> { +fn generate_item_impl(db: &BindingsGenerator<'_>, def_id: DefId) -> Result> { let tcx = db.tcx(); if db.symbol_canonical_name(def_id).is_none() { return Ok(None); @@ -1380,11 +1365,7 @@ fn generate_item_impl( /// Formats a C++ comment explaining why no bindings have been generated for /// `local_def_id`. -fn generate_unsupported_def( - db: &dyn BindingsGenerator<'_>, - def_id: DefId, - err: Error, -) -> CcSnippet { +fn generate_unsupported_def(db: &BindingsGenerator<'_>, def_id: DefId, err: Error) -> CcSnippet { let tcx = db.tcx(); db.errors().assert_in_item(item_name_for_error_report(db, def_id)); db.errors().report(&err); @@ -1431,7 +1412,7 @@ fn generate_unsupported_def( /// #tokens /// ``` pub fn format_namespace_bound_cc_tokens( - db: &dyn BindingsGenerator<'_>, + db: &BindingsGenerator<'_>, iter: impl IntoIterator, NamespaceQualifier, TokenStream)>, tcx: TyCtxt, ) -> TokenStream { @@ -1511,7 +1492,7 @@ struct FormattedItem { /// Generate bindings to supported trait implementations. An implementation is supported if both /// its trait and implementing type receive bindings. fn generate_trait_impls<'a, 'b>( - db: &'a dyn BindingsGenerator<'b>, + db: &'a BindingsGenerator<'b>, ) -> impl Iterator + use<'a, 'b> { let tcx = db.tcx(); let supported_traits: Vec = db.supported_traits().iter().copied().collect(); @@ -1627,7 +1608,7 @@ fn generate_trait_impls<'a, 'b>( }) } -fn formatted_items_in_crate(db: &dyn BindingsGenerator<'_>) -> impl Iterator { +fn formatted_items_in_crate(db: &BindingsGenerator<'_>) -> impl Iterator { let tcx = db.tcx(); let defs_in_crate = db.public_paths_by_def_id(db.source_crate_num()); defs_in_crate @@ -1659,7 +1640,7 @@ fn formatted_items_in_crate(db: &dyn BindingsGenerator<'_>) -> impl Iterator Result { +fn generate_crate(db: &BindingsGenerator) -> Result { struct CcDetails { def_id: DefId, namespace: NamespaceQualifier, diff --git a/cc_bindings_from_rs/generate_bindings/test_helpers.rs b/cc_bindings_from_rs/generate_bindings/test_helpers.rs index 4e37722b5..571c246bb 100644 --- a/cc_bindings_from_rs/generate_bindings/test_helpers.rs +++ b/cc_bindings_from_rs/generate_bindings/test_helpers.rs @@ -9,7 +9,7 @@ extern crate rustc_middle; use arc_anyhow::Result; use database::code_snippet::ApiSnippets; -use database::{BindingsGenerator as _, Database, IncludeGuard}; +use database::{BindingsGenerator, IncludeGuard}; use error_report::{FatalErrors, IgnoreErrors}; use generate_bindings::{generate_bindings, new_database, BindingsTokens}; use run_compiler_test_support::{find_def_id_by_name, run_compiler_for_testing}; @@ -72,7 +72,7 @@ fn bindings_db_for_tests_with_features( tcx: TyCtxt, features: flagset::FlagSet, with_kythe_annotations: bool, -) -> Database { +) -> BindingsGenerator { new_database( tcx, /* source_crate_name= */ None, @@ -96,7 +96,7 @@ fn bindings_db_for_tests_with_features( ) } -pub fn bindings_db_for_tests(tcx: TyCtxt) -> Database { +pub fn bindings_db_for_tests(tcx: TyCtxt) -> BindingsGenerator { bindings_db_for_tests_with_features( tcx, crubit_feature::CrubitFeature::Experimental | crubit_feature::CrubitFeature::Supported, diff --git a/common/error_report.rs b/common/error_report.rs index cb135e147..6ee71e4cd 100644 --- a/common/error_report.rs +++ b/common/error_report.rs @@ -224,7 +224,7 @@ pub struct ErrorReport { // a method call, and the methods do not call each other. map: RefCell>, // TODO(jeanpierreda): This should really be passed around rather than mutated in the - // BindingsGenerator. For example, if we used a totally separate `dyn BindingsGenerator` + // BindingsGenerator. For example, if we used a totally separate `BindingsGenerator` // which is the same as the old one except that it has a different input. current_item: RefCell>, } diff --git a/common/memoized.rs b/common/memoized.rs index 203a0891c..c7807ad37 100644 --- a/common/memoized.rs +++ b/common/memoized.rs @@ -24,6 +24,8 @@ //! `Hash`. //! * Supports `#[break_cycles_with = ]`, which generates a //! function that returns if a cycle is detected. +//! * Uses function pointers in the interior of a concrete type, instead of +//! `dyn Trait`. //! //! There are more substantial differences with Salsa 2022 - this was written //! based on Salsa 0.16. We don't need to match exactly the API, but the @@ -41,7 +43,9 @@ /// /// ``` /// query_group! { -/// trait QueryGroupName { +/// // QueryGroup name is the name of the memoized query object, including +/// // all relevant state. +/// struct QueryGroup { /// // First, all shared inputs are specified, in order. /// // /// // These are available to all of the memoized functions, by calling `db.some_input()`, etc., @@ -66,17 +70,17 @@ /// // parameters, and return a `Clone` return type. /// // /// // Each of these must be implemented in the _same module_ as a top-level function, with -/// // the same function signature except taking `&dyn QueryGroupName` instead of `&self`. +/// // the same function signature. /// // -/// // The functions can call methods on the `&dyn QueryGroupName` to access both the shared -/// // inputs, as well to call other memoized functions. +/// // The functions can call methods on the `&QueryGroup` self argument to access both +/// // the shared inputs, as well to call other memoized functions. /// // /// // Inputs to the computation which change from call to call should be specified as function /// // parameters. Inputs which never change can be either `#[input]` functions, or actual /// // program globals. /// // -/// // When called on the `&dyn QueryGroupName` or directly on the concrete type, the functions -/// // will be memoized, and the return value will be cached, automatically. +/// // When called on the `&QueryGroup`, the functions will be memoized, and the return +/// // value will be cached, automatically. /// // /// // Some functions may need to gracefully handle cycles, in which case they should be /// // annotated with `#[break_cycles_with = ]`. This will generate a function @@ -91,33 +95,30 @@ /// /// Doc comment goes here. /// fn some_function(&self, arg: ArgType) -> ReturnType; /// } -/// // The concrete type for the storage of inputs and memoized values. -/// // `query_group!` will add the required fields to this struct. -/// struct Database; /// } /// /// // The non-memoized implementation of the memoized functions -/// fn may_by_cyclic(db: &dyn QueryGroupName, arg: ArgType) -> ReturnType { +/// fn may_by_cyclic(db: &QueryGroup, arg: ArgType) -> ReturnType { /// // ... /// } /// -/// fn some_function(db: &dyn QueryGroupName, arg: ArgType) -> ReturnType { +/// fn some_function(db: &QueryGroup, arg: ArgType) -> ReturnType { /// // ... /// } /// ``` /// -/// A new instance of `Database` can be created by using `Database::new(input, +/// A new instance of `QueryGroup` can be created by using `QueryGroup::new(input, /// values, here)`. It will implement the trait defined above: the `#[input]` -/// functions will return the corresponding values passed in to `Database::new`, +/// functions will return the corresponding values passed in to `QueryGroup::new`, /// and the memoized functions will call the corresponding top-level functions. /// /// For example, above, one could run `let db = -/// Database::new(InputType::default())`. +/// QueryGroup::new(InputType::default())`. /// /// Now, if you call `db.some_function(...)`, it will either return a cached -/// value (if one is present), or else execute `some_function(&db as &dyn -/// QueryGroupName, ...)`, and cache and return the result. A direct call to -/// `some_function` (instead of `db.some_function`) is not directly memoized. +/// value (if one is present), or else execute `some_function(&db)`, and cache +/// and return the result. A direct call to `some_function` (instead of +/// `db.some_function`) is not directly memoized. /// /// Because the results are saved, it's very important that the functions are /// pure and have no side-effects. In particular, internal mutability on the @@ -128,8 +129,8 @@ /// * In the trait definition, all `#[input]` functions must be declared before /// all (non-`#[input]`) memoized functions. The order of the input functions /// is the order of their parameters in `new()`. -/// * Every (non-`#[input]`) trait method _must_ have a matching top-level -/// function, with `&self` replaced by `&dyn QueryGroupName`. +/// * Every (non-`#[input]`) trait method _must_ have a matching function passed +/// to `new()`. /// * Since all trait methods are memoized, their arguments must be `Clone`, /// `Eq`, and `Hash`. /// @@ -140,31 +141,30 @@ /// /// ``` /// query_group! { -/// trait QueryGroupName<'a> { +/// struct QueryGroup<'a> { /// #[input] /// fn some_input(&self) -> &'a InputType; /// fn some_function(&self, arg: &'a ArgType) -> &'a ReturnType; /// } -/// struct Database; /// } /// -/// fn<'a> some_function(db: &dyn QueryGroupName<'a>, arg: &'a ArgType) -> &'a ReturnType { +/// fn<'a> some_function(db: &QueryGroup<'a>, arg: &'a ArgType) -> &'a ReturnType { /// // ... /// } /// ``` /// -/// Note that under the hood, `struct Database` will be replaced by something +/// Note that under the hood, `QueryGroup` will bedefined as something /// like: /// /// ``` -/// struct Database<'a> {...} +/// struct QueryGroup<'a> {...} /// ``` /// /// And so you may need to specify the lifetime in some uses. #[macro_export] macro_rules! query_group { ( - $trait_vis:vis trait $trait:ident $(<$($type_param:tt),*>)?{ + $vis:vis struct $database_struct:ident $(<$($type_param:tt),*>)?{ $( // TODO(jeanpierreda): Ideally would allow putting the doc-comment first, // but this causes parsing ambiguity. @@ -201,73 +201,34 @@ macro_rules! query_group { fn $provided_function:ident(&$provided_self:ident $(, $provided_arg:ident : $provided_arg_type:ty)* $(,)?) -> $provided_type:ty { $($provided_body:tt)* } )* } - - $struct_vis:vis struct $database_struct:ident; ) => { - // First, yes, generate the trait. - $trait_vis trait $trait $(<$($type_param),*>)?{ - $( - $(#[doc = $input_doc])* - fn $input_function(&self) -> $input_type { unimplemented!(concat!("input function '", stringify!($input_function), "'")) } - )* - $( - $(#[doc = $break_cycles_doc])* - fn $break_cycles_function( - &self, - $( - $break_cycles_arg : $break_cycles_arg_type - ),* - ) -> $break_cycles_return_type { _ = ($($break_cycles_arg),*); unimplemented!(concat!("break cycles function '", stringify!($break_cycles_function), "'")) } - )* - $( - $(#[doc = $function_doc])* - fn $function( - &self, - $( - $arg : $arg_type - ),* - ) -> $return_type { _ = ($($arg),*); unimplemented!(concat!("function '", stringify!($function), "'")) } - )* - $( - $(#[doc = $provided_doc])* - fn $provided_function(&$provided_self $(, $provided_arg: $provided_arg_type)*) -> $provided_type { _ = ($($provided_arg),*); unimplemented!(concat!("provided function '", stringify!($provided_function), "'")) } - )* - } - - // Avoid having to repeat the `$type_param` metavariable below, since its repetition - // should not be zipped with other metavariable repetitions. - // This also avoids having to repeat out `&dyn $trait $(<$($type_param),*>)?` all over the - // place. - macro_rules! dyn_trait { - () => { &dyn $trait $(<$($type_param),*>)? }; - } - - // Now we can generate a database struct that contains the lookup tables. - $struct_vis struct $database_struct $(<$($type_param),*>)? { + // The database struct, which contains the lookup tables. + $vis struct $database_struct $(<$($type_param),*>)? { __unwinding_cycles: ::core::cell::Cell, $( $input_function: $input_type, )* $( $break_cycles_function: $crate::internal::FnAndTable< - fn(dyn_trait!(), $($break_cycles_arg_type),*) -> $break_cycles_return_type, + fn(&Self, $($break_cycles_arg_type),*) -> $break_cycles_return_type, ($($break_cycles_arg_type,)*), $break_cycles_return_type >, )* $( $function: $crate::internal::FnAndTable< - fn(dyn_trait!(), $($arg_type),*) -> $return_type, + fn(&Self, $($arg_type),*) -> $return_type, ($($arg_type,)*), $return_type >, )* } - // ...and an implementation of the trait. - impl $(<$($type_param),*>)? $trait $(<$($type_param),*>)? for $database_struct $(<$($type_param),*>)? { + // ...and the methods. + impl $(<$($type_param),*>)? $database_struct $(<$($type_param),*>)? { $( - fn $input_function(&self) -> $input_type { + $(#[doc = $input_doc])* + $vis fn $input_function(&self) -> $input_type { // Have to be very careful to clone whatever the top level value is. // In particular, if it's a reference `&T`, clone the _reference_ to get another `&T`, // not the referent to get a `T`, like if we just cloned `self.$input_function`. @@ -275,7 +236,8 @@ macro_rules! query_group { } )* $( - fn $break_cycles_function( + $(#[doc = $break_cycles_doc])* + $vis fn $break_cycles_function( &self, $( $break_cycles_arg : $break_cycles_arg_type @@ -286,15 +248,15 @@ macro_rules! query_group { $break_cycles_arg, )*), |($($break_cycles_arg,)*)| { - // Force the use of &dyn $trait, so that we don't rule out separate compilation later. - (self.$break_cycles_function.fn_ptr)(self as &dyn $trait, $($break_cycles_arg),*) + (self.$break_cycles_function.fn_ptr)(self, $($break_cycles_arg),*) }, &self.__unwinding_cycles, ).unwrap_or($break_cycles_default_value) } )* $( - fn $function( + $(#[doc = $function_doc])* + $vis fn $function( &self, $( $arg : $arg_type @@ -305,8 +267,7 @@ macro_rules! query_group { $arg, )*), |($($arg,)*)| { - // Force the use of &dyn $trait, so that we don't rule out separate compilation later. - (self.$function.fn_ptr)(self as &dyn $trait, $($arg),*) + (self.$function.fn_ptr)(self, $($arg),*) }, &self.__unwinding_cycles, ).unwrap_or_else( @@ -315,7 +276,8 @@ macro_rules! query_group { } )* $( - fn $provided_function( + $(#[doc = $provided_doc])* + $vis fn $provided_function( &$provided_self, $( $provided_arg : $provided_arg_type @@ -325,12 +287,12 @@ macro_rules! query_group { } )* } - // and the new() function for initialization. + // And the new() functions for initialization. impl $(<$($type_param),*>)? $database_struct $(<$($type_param),*>)? { - $struct_vis fn new( + $vis fn new( $($input_function: $input_type,)* - $($break_cycles_function: fn(dyn_trait!(), $($break_cycles_arg_type),*) -> $break_cycles_return_type,)* - $($function: fn(dyn_trait!(), $($arg_type),*) -> $return_type,)* + $($break_cycles_function: fn(&Self, $($break_cycles_arg_type),*) -> $break_cycles_return_type,)* + $($function: fn(&Self, $($arg_type),*) -> $return_type,)* ) -> Self { Self { __unwinding_cycles: ::core::cell::Cell::new(0), @@ -455,7 +417,7 @@ pub mod tests { #[gtest] fn test_basic_memoization() { crate::query_group! { - pub trait Add10 { + pub struct Add10 { #[input] /// Tracker for how many times this function is called so we can check /// that memoization is indeed happening. This is just for testing; @@ -464,13 +426,12 @@ pub mod tests { fn call_counter(&self) -> Rc>; fn add10(&self, arg: i32) -> i32; } - pub struct Database; } - fn add10(db: &dyn Add10, arg: i32) -> i32 { + fn add10(db: &Add10, arg: i32) -> i32 { db.call_counter().set(db.call_counter().get() + 1); arg + 10 } - let db = Database::new(Rc::new(Cell::new(0)), add10); + let db = Add10::new(Rc::new(Cell::new(0)), add10); assert_eq!(db.add10(100), 110); assert_eq!(db.call_counter().get(), 1); @@ -489,25 +450,24 @@ pub mod tests { #[gtest] fn test_nonstatic_memoization() { crate::query_group! { - pub trait Add10<'a> { + pub struct Add10<'a> { #[input] fn call_counter(&self) -> &'a Cell; fn add10(&self, arg: &'a i32) -> i32; // non-input function with 'a in return type fn identity(&self, arg: &'a i32) -> &'a i32; } - pub struct Database; } - fn add10<'a>(db: &dyn Add10<'a>, arg: &'a i32) -> i32 { + fn add10<'a>(db: &Add10<'a>, arg: &'a i32) -> i32 { db.call_counter().set(db.call_counter().get() + 1); *arg + 10 } - fn identity<'a>(db: &dyn Add10<'a>, arg: &'a i32) -> &'a i32 { + fn identity<'a>(db: &Add10<'a>, arg: &'a i32) -> &'a i32 { db.call_counter().set(db.call_counter().get() + 1); arg } let count = Cell::new(0); - let db = Database::new(&count, add10, identity); + let db = Add10::new(&count, add10, identity); assert_eq!(db.add10(&100), 110); assert_eq!(count.get(), 1); @@ -529,54 +489,51 @@ pub mod tests { #[should_panic(expected = "Cycle detected: 'add10' depends on its own return value")] fn test_cycle() { crate::query_group! { - pub trait Add10 { + pub struct Add10 { fn add10(&self, arg: i32) -> i32; } - pub struct Database; } - fn add10(db: &dyn Add10, arg: i32) -> i32 { + fn add10(db: &Add10, arg: i32) -> i32 { db.add10(arg) // infinite recursion! } - let db = Database::new(add10); + let db = Add10::new(add10); db.add10(1); } #[gtest] fn test_break_cycles_with_option() { crate::query_group! { - pub trait Add10 { + pub struct Add10 { #[break_cycles_with = None] fn add10(&self, arg: i32) -> Option; } - pub struct Database; } - fn add10(db: &dyn Add10, arg: i32) -> Option { + fn add10(db: &Add10, arg: i32) -> Option { db.add10(arg) } - let db = Database::new(add10); + let db = Add10::new(add10); assert_eq!(db.add10(1), None); } #[gtest] fn test_break_cycles_with_sentinel() { crate::query_group! { - pub trait Add10 { + pub struct Add10 { #[break_cycles_with = -1] fn add10(&self, arg: i32) -> i32; } - pub struct Database; } - fn add10(db: &dyn Add10, arg: i32) -> i32 { + fn add10(db: &Add10, arg: i32) -> i32 { db.add10(arg) } - let db = Database::new(add10); + let db = Add10::new(add10); assert_eq!(db.add10(1), -1); } #[gtest] fn test_calls_in_cycle_are_not_memoized() { crate::query_group! { - pub trait Table { + pub struct Table { #[input] fn logging(&self) -> Rc>>; @@ -588,7 +545,6 @@ pub mod tests { fn record(&self, name: &'static str) -> Record; } - pub struct Database; } #[derive(Clone)] @@ -599,7 +555,7 @@ pub mod tests { } // Returns whether or not a record is unsafe, checking recursively. - fn is_unsafe(db: &dyn Table, name: &'static str) -> bool { + fn is_unsafe(db: &Table, name: &'static str) -> bool { let record = db.record(name); let outcome = record.is_unsafe || record.fields.iter().any(|&field| db.is_unsafe(field)); @@ -608,7 +564,7 @@ pub mod tests { } // Helper function so we can refer to records by name instead of by index. - fn record(db: &dyn Table, name: &'static str) -> Record { + fn record(db: &Table, name: &'static str) -> Record { db.records() .iter() .find(|record| record.name == name) @@ -618,7 +574,7 @@ pub mod tests { let logging = Rc::default(); - let db = Database::new( + let db = Table::new( Rc::clone(&logging), &[ Record { name: "A", is_unsafe: false, fields: &["B", "Unsafe"] }, @@ -651,14 +607,13 @@ pub mod tests { #[gtest] fn test_finite_recursion() { crate::query_group! { - pub trait Add10 { + pub struct Add10 { #[input] fn call_counter(&self) -> Rc>; fn add10(&self, arg: i32) -> i32; } - pub struct Database; } - fn add10(db: &dyn Add10, arg: i32) -> i32 { + fn add10(db: &Add10, arg: i32) -> i32 { db.call_counter().set(db.call_counter().get() + 1); if (arg % 10) != 0 { db.add10(arg - 1) + 1 // Some recursion, but not infinite! @@ -666,7 +621,7 @@ pub mod tests { arg + 10 } } - let db = Database::new(Rc::new(Cell::new(0)), add10); + let db = Add10::new(Rc::new(Cell::new(0)), add10); assert_eq!(db.add10(100), 110); assert_eq!(db.call_counter().get(), 1); @@ -690,18 +645,17 @@ pub mod tests { #[gtest] fn test_argless() { crate::query_group! { - pub trait Argless { + pub struct Argless { #[input] fn call_counter(&self) -> Rc>; fn argless_function(&self) -> Rc; } - pub struct Database; } - fn argless_function(db: &dyn Argless) -> Rc { + fn argless_function(db: &Argless) -> Rc { db.call_counter().set(db.call_counter().get() + 1); Rc::new(0) } - let db = Database::new(Rc::new(Cell::new(0)), argless_function); + let db = Argless::new(Rc::new(Cell::new(0)), argless_function); assert_eq!(db.call_counter().get(), 0); let argless_return = db.argless_function(); @@ -714,15 +668,14 @@ pub mod tests { #[gtest] fn test_provided_fn() { crate::query_group! { - pub trait Db { + pub struct Db { #[input] fn input_fn(&self) -> i32; #[provided] fn provided_fn(&self, x: i32) -> i32 { self.input_fn() + x } } - pub struct Database; } - let db = Database::new(42); + let db = Db::new(42); let result = db.provided_fn(10); expect_eq!(result, 52); } diff --git a/rs_bindings_from_cc/generate_bindings/database/code_snippet.rs b/rs_bindings_from_cc/generate_bindings/database/code_snippet.rs index e21842bc2..5115258b2 100644 --- a/rs_bindings_from_cc/generate_bindings/database/code_snippet.rs +++ b/rs_bindings_from_cc/generate_bindings/database/code_snippet.rs @@ -140,7 +140,7 @@ impl Display for RequiredCrubitFeature { /// If the item does have a defining target, and it doesn't enable the specified /// features, then bindings are suppressed for this item. pub fn required_crubit_features( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, item: &Item, ) -> Result> { let mut missing_features = vec![]; diff --git a/rs_bindings_from_cc/generate_bindings/database/db.rs b/rs_bindings_from_cc/generate_bindings/database/db.rs index 3ba44fb70..face53d94 100644 --- a/rs_bindings_from_cc/generate_bindings/database/db.rs +++ b/rs_bindings_from_cc/generate_bindings/database/db.rs @@ -21,13 +21,13 @@ pub fn test_again() {} #[derive(Clone)] pub struct CodegenFunctions { - pub generate_enum: fn(&dyn BindingsGenerator, Rc) -> Result, - pub generate_item: fn(&dyn BindingsGenerator, ir::Item) -> Result, - pub generate_record: fn(&dyn BindingsGenerator, Rc) -> Result, + pub generate_enum: fn(&BindingsGenerator, Rc) -> Result, + pub generate_item: fn(&BindingsGenerator, ir::Item) -> Result, + pub generate_record: fn(&BindingsGenerator, Rc) -> Result, } memoized::query_group! { - pub trait BindingsGenerator<'db> { + pub struct BindingsGenerator<'db> { #[input] fn ir(&self) -> &'db IR; @@ -62,7 +62,7 @@ memoized::query_group! { /// reference lifetimes with the elided lifetime (`'_`). /// /// An `Ok()` return value does not necessarily imply that the resulting `RsTypeKind` is - /// usable in APIs: callers must also check the result of `db::type_visibility()` for + /// usable in APIs: callers must also check the result of `type_visibility()` for /// the type, to see if it is usable within a specific crate. Eventually, all types will /// have a successful non-error return value, even if the type is not generally usable. /// Instead, restrictions will always be done via `type_visibility`. @@ -132,7 +132,7 @@ memoized::query_group! { /// Implementation: rs_bindings_from_cc/generate_bindings/lib.rs?q=function:crubit_abi_type fn crubit_abi_type(&self, rs_type_kind: RsTypeKind) -> Result; - // You should probably use db::type_visibility instead of this function. + // You should probably use `type_visibility()` instead of this function. fn type_target_restriction(&self, rs_type_kind: RsTypeKind) -> Result>; /// Resolves type names to a map from name to ResolvedTypeName. @@ -190,34 +190,25 @@ memoized::query_group! { Some(id) => *id != Some(item_id), } } - } - pub struct Database; -} -/// Returns the `Visibility` of the `rs_type_kind` in the given `library`. -// TODO(jeanpierreda): it would be nice if this was a `#[provided]` function, -// but because it calls `display`, it would need to convert to a -// `dyn BindingsGenerator`, which is not reasonably possible. -// -// See e.g. https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=10f937bb0f13d2ea05f20f676c37439a -pub fn type_visibility( - db: &dyn BindingsGenerator, - library: &BazelLabel, - rs_type_kind: RsTypeKind, -) -> Result { - match db.type_target_restriction(rs_type_kind.clone())? { - Some(label) if &label != library => { - let rs_type_kind = rs_type_kind.display(db); - Err(anyhow!("{rs_type_kind} is `pub(crate)` in {label}")) - } - Some(_) => Ok(Visibility::PubCrate), - None => { - for subtype in rs_type_kind.dfs_iter() { - if let RsTypeKind::Error { visibility_override, .. } = subtype { - return Ok(visibility_override.unwrap_or(Visibility::PubCrate)); + #[provided] + /// Returns the `Visibility` of the `rs_type_kind` in the given `library`. + fn type_visibility(&self, library: &BazelLabel, rs_type_kind: RsTypeKind) -> Result { + match self.type_target_restriction(rs_type_kind.clone())? { + Some(label) if &label != library => { + let rs_type_kind = rs_type_kind.display(self); + Err(anyhow!("{rs_type_kind} is `pub(crate)` in {label}")) + } + Some(_) => Ok(Visibility::PubCrate), + None => { + for subtype in rs_type_kind.dfs_iter() { + if let RsTypeKind::Error { visibility_override, .. } = subtype { + return Ok(visibility_override.unwrap_or(Visibility::PubCrate)); + } + } + Ok(Visibility::Public) } } - Ok(Visibility::Public) } } } diff --git a/rs_bindings_from_cc/generate_bindings/database/lib.rs b/rs_bindings_from_cc/generate_bindings/database/lib.rs index e098f1b51..182cc1a62 100644 --- a/rs_bindings_from_cc/generate_bindings/database/lib.rs +++ b/rs_bindings_from_cc/generate_bindings/database/lib.rs @@ -8,4 +8,4 @@ pub mod code_snippet; pub mod db; pub mod function_types; pub mod rs_snippet; -pub use db::{BindingsGenerator, Database}; +pub use db::BindingsGenerator; 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 32addddcb..3221b2386 100644 --- a/rs_bindings_from_cc/generate_bindings/database/rs_snippet.rs +++ b/rs_bindings_from_cc/generate_bindings/database/rs_snippet.rs @@ -23,6 +23,8 @@ use token_stream_printer::write_unformatted_tokens; pub use ir::BackingType; +use std::ops::Deref; + const SLICE_REF_NAME_RS: &str = "&[]"; /// A struct with information associated with the formatted Rust code snippet. @@ -201,8 +203,8 @@ pub fn format_generic_params<'a, T: ToTokens>( } } -pub fn format_generic_params_replacing_by_self<'a>( - db: &dyn BindingsGenerator, +pub fn format_generic_params_replacing_by_self<'db, 'a>( + db: impl Deref> + Copy, types: impl IntoIterator, trait_record: Option<&Record>, ) -> TokenStream { @@ -282,7 +284,7 @@ impl UniformReprTemplateType { /// Returns none if the template specialization is not for a known type corresponding with /// one of `UniformReprTemplateType`s variants. fn new( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, template_specialization_kind: Option<&TemplateSpecializationKind>, is_return_type: bool, ) -> Result>> { @@ -356,7 +358,7 @@ impl UniformReprTemplateType { } } - fn to_token_stream(&self, db: &dyn BindingsGenerator) -> TokenStream { + fn to_token_stream(&self, db: &BindingsGenerator) -> TokenStream { match self { Self::StdVector { element_type } => { let element_type_tokens = element_type.to_token_stream(db); @@ -468,7 +470,7 @@ pub enum RsTypeKind { fn new_c9_co_record( have_reference_param: bool, record: Rc, - db: &dyn BindingsGenerator, + db: &BindingsGenerator, ) -> Result> { let Some(TemplateSpecialization { kind: TemplateSpecializationKind::C9Co { element_type }, @@ -531,7 +533,7 @@ pub struct Callable { impl Callable { /// Returns a `TokenStream` in the shape of `-> Output`, or None if the return type is void. - pub fn rust_return_type_fragment(&self, db: &dyn BindingsGenerator) -> Option { + pub fn rust_return_type_fragment(&self, db: &BindingsGenerator) -> Option { if self.return_type.is_void() { None } else { @@ -541,7 +543,7 @@ impl Callable { } /// Returns a `TokenStream` in the shape of `dyn Trait(Inputs) -> Output`. - pub fn dyn_fn_spelling(&self, db: &dyn BindingsGenerator) -> TokenStream { + pub fn dyn_fn_spelling(&self, db: &BindingsGenerator) -> TokenStream { let rust_return_type_fragment = self.rust_return_type_fragment(db); let param_type_tokens = self.param_types.iter().map(|param_ty| param_ty.to_token_stream(db)); @@ -589,7 +591,7 @@ impl BridgeRsTypeKind { /// If the record is a bridge type, returns the corresponding BridgeRsTypeKind. /// Otherwise, returns None. This may also return an error if db.rs_type_kind fails, or if the /// record has template parameters that cannot be translated. - pub fn new(record: &Record, db: &dyn BindingsGenerator) -> Result> { + pub fn new(record: &Record, db: &BindingsGenerator) -> Result> { let Some(bridge_type) = &record.bridge_type else { return Ok(None); }; @@ -677,7 +679,7 @@ impl RsTypeKind { /// or if the `RsTypeKind` cannot be created (e.g. a type alias which points to a type that /// cannot receive an `RsTypeKind`). pub fn from_item_raw( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, item: Item, have_reference_param: bool, is_return_type: bool, @@ -698,7 +700,7 @@ impl RsTypeKind { } } - fn new_type_alias(db: &dyn BindingsGenerator, type_alias: Rc) -> Result { + fn new_type_alias(db: &BindingsGenerator, type_alias: Rc) -> Result { let ir = db.ir(); let underlying_type = db.rs_type_kind(type_alias.underlying_type.clone())?; // Note: we don't need to call `.unalias()` for these checks, because we already checked @@ -733,7 +735,7 @@ impl RsTypeKind { } fn new_record( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, record: Rc, have_reference_param: bool, is_return_type: bool, @@ -765,7 +767,7 @@ impl RsTypeKind { } fn new_incomplete_record( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, incomplete_record: Rc, ) -> Result { let ir = db.ir(); @@ -777,7 +779,7 @@ impl RsTypeKind { Ok(RsTypeKind::IncompleteRecord { incomplete_record, crate_path }) } - fn new_enum(db: &dyn BindingsGenerator, enum_: Rc) -> Result { + fn new_enum(db: &BindingsGenerator, enum_: Rc) -> Result { let ir = db.ir(); let crate_path = Rc::new(CratePath::new( ir, @@ -788,7 +790,7 @@ impl RsTypeKind { } fn new_existing_rust_type( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, existing_rust_type: Rc, ) -> Result { if existing_rust_type.rs_name.as_ref() == SLICE_REF_NAME_RS { @@ -891,9 +893,9 @@ impl RsTypeKind { /// for both the template definition and its instantiation, and so both /// would need to be passed in to rs_type_kind() in order to be able to /// merge these two functions. - pub fn required_crubit_features( + pub fn required_crubit_features<'a>( &self, - db: &dyn BindingsGenerator, + db: impl Deref>, enabled_features: flagset::FlagSet, ) -> (flagset::FlagSet, String) { let mut missing_features = >::default(); @@ -943,7 +945,7 @@ impl RsTypeKind { RsTypeKind::IncompleteRecord { .. } => require_feature( CrubitFeature::Wrapper, Some(&|| { - format!("{} is not a complete type)", rs_type_kind.display(db)).into() + format!("{} is not a complete type)", rs_type_kind.display(&db)).into() }), ), // Here, we can very carefully be non-recursive into the _structure_ of the type. @@ -967,7 +969,7 @@ impl RsTypeKind { require_feature( CrubitFeature::Wrapper, Some(&|| { - format!("{} is a template instantiation", rs_type_kind.display(db),) + format!("{} is a template instantiation", rs_type_kind.display(&db),) .into() }), ) @@ -988,7 +990,7 @@ impl RsTypeKind { Some(&|| { format!( "{} is a bridged template instantiation", - rs_type_kind.display(db), + rs_type_kind.display(&db), ) .into() }), @@ -1129,9 +1131,9 @@ impl RsTypeKind { } } - pub fn format_as_return_type_fragment( + pub fn format_as_return_type_fragment<'a>( &self, - db: &dyn BindingsGenerator, + db: impl Deref> + Copy, self_record: Option<&Record>, ) -> Option { match self.unalias() { @@ -1330,7 +1332,7 @@ impl RsTypeKind { /// `RsTypeKind::Pointer` with kind /// `RustPtrKind::CcPtr(PointerTypeKind::Owned)` will emit the corresponding /// owning Rust type rather than a raw pointer. - pub fn to_token_stream_with_owned_ptr_type(&self, db: &dyn BindingsGenerator) -> TokenStream { + pub fn to_token_stream_with_owned_ptr_type(&self, db: &BindingsGenerator) -> TokenStream { // If it's not an owned pointer, just use the default implementation. let Some(pointee) = self.as_owned_ptr() else { return self.to_token_stream(db); @@ -1352,9 +1354,9 @@ impl RsTypeKind { /// Similar to to_token_stream, but replacing RsTypeKind:Record with Self /// when the underlying Record matches the given one. - pub fn to_token_stream_replacing_by_self( + pub fn to_token_stream_replacing_by_self<'a>( &self, - db: &dyn BindingsGenerator, + db: impl Deref> + Copy, self_record: Option<&Record>, ) -> TokenStream { match self { @@ -1425,7 +1427,7 @@ impl RsTypeKind { /// Returns a `Display`able type for this `RsTypeKind`. pub fn display<'a, 'db>( &'a self, - db: &'a dyn BindingsGenerator<'db>, + db: &'a BindingsGenerator<'db>, ) -> impl std::fmt::Display + use<'a, 'db> { DisplayRsTypeKind { rs_type_kind: self, db } } @@ -1446,7 +1448,7 @@ impl RsTypeKind { /// requires a [`BindingsGenerator`] to be able to format the type. pub struct DisplayRsTypeKind<'a, 'db> { rs_type_kind: &'a RsTypeKind, - db: &'a dyn BindingsGenerator<'db>, + db: &'a BindingsGenerator<'db>, } impl std::fmt::Display for DisplayRsTypeKind<'_, '_> { @@ -1465,7 +1467,10 @@ impl std::fmt::Display for DisplayRsTypeKind<'_, '_> { } impl RsTypeKind { - pub fn to_token_stream(&self, db: &dyn BindingsGenerator) -> TokenStream { + pub fn to_token_stream<'a>( + &self, + db: impl Deref> + Copy, + ) -> TokenStream { match self { // errors become opaque blobs RsTypeKind::Error { symbol, .. } => { @@ -1531,7 +1536,7 @@ impl RsTypeKind { owned_ptr_type: _, } => { if let Some(generic_monomorphization) = uniform_repr_template_type { - return generic_monomorphization.to_token_stream(db); + return generic_monomorphization.to_token_stream(&db); } let ident = make_rs_ident(record.rs_name.identifier.as_ref()); quote! { #crate_path #ident } @@ -1697,7 +1702,7 @@ impl RsTypeKind { } } BridgeRsTypeKind::DynCallable(dyn_callable) => { - let dyn_callable_spelling = dyn_callable.dyn_fn_spelling(db); + let dyn_callable_spelling = dyn_callable.dyn_fn_spelling(&db); quote! { ::alloc::boxed::Box<#dyn_callable_spelling> } } } @@ -1731,8 +1736,8 @@ impl RsTypeKind { /// /// This has _very_ limited support for other type expressions, like `&T`, /// and special-cases well known builtin types like `char`. -fn fully_qualify_type( - db: &dyn BindingsGenerator, +fn fully_qualify_type<'a>( + db: impl Deref> + Copy, item: ir::Item, type_expression: &str, ) -> TokenStream { @@ -1917,8 +1922,14 @@ mod tests { assert_eq!(vec!["fn", "::A", "::B", "::C"], dfs_names); } + #[derive(Copy, Clone)] struct EmptyDatabase; - impl<'db> BindingsGenerator<'db> for EmptyDatabase {} + impl Deref for EmptyDatabase { + type Target = BindingsGenerator<'static>; + fn deref(&self) -> &Self::Target { + panic!("Tried to use the empty bindings generator query group.") + } + } #[gtest] fn test_lifetime_elision_for_references() { @@ -1928,7 +1939,7 @@ mod tests { mutability: Mutability::Const, lifetime: Lifetime::new("_"), }; - assert_rs_matches!(reference.to_token_stream(&EmptyDatabase), quote! {&::T}); + assert_rs_matches!(reference.to_token_stream(EmptyDatabase), quote! {&::T}); } #[gtest] @@ -1940,7 +1951,7 @@ mod tests { lifetime: Lifetime::new("_"), }; assert_rs_matches!( - reference.to_token_stream(&EmptyDatabase), + reference.to_token_stream(EmptyDatabase), quote! {RvalueReference<'_, ::T>} ); } @@ -2001,7 +2012,7 @@ mod tests { }, ] { let (all_required_features, reason) = func_ptr.required_crubit_features( - &EmptyDatabase, + EmptyDatabase, >::default(), ); assert_eq!( diff --git a/rs_bindings_from_cc/generate_bindings/generate_bindings_test.rs b/rs_bindings_from_cc/generate_bindings/generate_bindings_test.rs index 0bed032bb..fbcc96d15 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_bindings_test.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_bindings_test.rs @@ -5,7 +5,6 @@ use arc_anyhow::{anyhow, Result}; use database::code_snippet::BindingsTokens; use database::rs_snippet::{Mutability, RsTypeKind}; -use database::BindingsGenerator; use googletest::{expect_eq, gtest}; use ir_testing::{retrieve_func, with_lifetime_macros}; use multiplatform_ir_testing::{ir_from_cc, ir_from_cc_dependency}; diff --git a/rs_bindings_from_cc/generate_bindings/generate_comment.rs b/rs_bindings_from_cc/generate_bindings/generate_comment.rs index 5792efc5c..6bba18fb5 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_comment.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_comment.rs @@ -84,7 +84,7 @@ pub fn generate_doc_comment( } /// Generates Rust source code for a given `UnsupportedItem`. -pub fn generate_unsupported(db: &dyn BindingsGenerator, item: Rc) -> ApiSnippets { +pub fn generate_unsupported(db: &BindingsGenerator, item: Rc) -> ApiSnippets { Item::UnsupportedItem(item.clone()).assert_in_error_scope(db.ir(), db.errors()); for error in item.errors() { db.errors().report(error); diff --git a/rs_bindings_from_cc/generate_bindings/generate_comment_test.rs b/rs_bindings_from_cc/generate_bindings/generate_comment_test.rs index 887a20085..d79864917 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_comment_test.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_comment_test.rs @@ -6,7 +6,7 @@ use arc_anyhow::Result; use database::code_snippet; -use database::{BindingsGenerator, Database}; +use database::BindingsGenerator; use error_report::{ErrorReport, FatalErrors}; use ffi_types::Environment; use generate_bindings::new_database; @@ -120,7 +120,7 @@ impl TestDbFactory { fatal_errors: FatalErrors::new(), } } - fn make_db(&self, environment: Environment) -> Database { + fn make_db(&self, environment: Environment) -> BindingsGenerator { new_database(&self.ir, &self.errors, &self.fatal_errors, environment) } } diff --git a/rs_bindings_from_cc/generate_bindings/generate_dyn_callable.rs b/rs_bindings_from_cc/generate_bindings/generate_dyn_callable.rs index b281c2239..72350a096 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_dyn_callable.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_dyn_callable.rs @@ -11,7 +11,7 @@ use quote::{format_ident, quote}; /// Generates the `CrubitAbiType` for callables. pub fn dyn_callable_crubit_abi_type( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, callable: &Callable, ) -> Result { let dyn_fn_spelling = callable.dyn_fn_spelling(db); @@ -125,7 +125,7 @@ pub fn dyn_callable_crubit_abi_type( /// value. In the case that all inputs and outputs are C-compatible by value, this lambda is simply /// a pointer to the thunk. fn generate_invoker_function_pointer( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, callable: &Callable, cpp_param_types: &[TokenStream], cpp_return_type: &TokenStream, diff --git a/rs_bindings_from_cc/generate_bindings/generate_enum.rs b/rs_bindings_from_cc/generate_bindings/generate_enum.rs index 7e6000b84..59521860a 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_enum.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_enum.rs @@ -16,7 +16,7 @@ use std::collections::HashMap; use std::rc::Rc; /// Implementation of `BindingsGenerator::generate_enum`. -pub fn generate_enum(db: &dyn BindingsGenerator, enum_: Rc) -> Result { +pub fn generate_enum(db: &BindingsGenerator, enum_: Rc) -> Result { let ident = expect_format_cc_ident(&enum_.cc_name.identifier); let namespace_qualifier = db.ir().namespace_qualifier(&enum_).format_for_cc()?; let fully_qualified_cc_name = quote! { #namespace_qualifier #ident }.to_string(); diff --git a/rs_bindings_from_cc/generate_bindings/generate_function.rs b/rs_bindings_from_cc/generate_bindings/generate_function.rs index bb2957948..de8c400f3 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_function.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_function.rs @@ -36,7 +36,7 @@ use std::sync::LazyLock; /// This is used to remove the record whose trait implementation is being /// generated. fn trait_name_to_token_stream_removing_trait_record( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, trait_name: &TraitName, trait_record: Option<&Record>, ) -> TokenStream { @@ -83,7 +83,7 @@ fn trait_name_to_token_stream_removing_trait_record( } } -fn trait_name_to_token_stream(db: &dyn BindingsGenerator, trait_name: &TraitName) -> TokenStream { +fn trait_name_to_token_stream(db: &BindingsGenerator, trait_name: &TraitName) -> TokenStream { trait_name_to_token_stream_removing_trait_record(db, trait_name, None) } @@ -191,7 +191,7 @@ static OPERATOR_METADATA: LazyLock = LazyLock::new(|| { /// /// This is necessary because ADL is needed in order to find friend functions. fn is_friend_of_record_not_visible_by_adl( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, param_types: &[RsTypeKind], ) -> bool { @@ -208,7 +208,7 @@ fn is_friend_of_record_not_visible_by_adl( /// /// Returns the `RsTypeKind` and `Record` of the underlying record type. fn type_by_value_or_under_const_ref<'a>( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, kind: &'a mut RsTypeKind, value_desc: &str, errors: &Errors, @@ -239,7 +239,7 @@ fn type_by_value_or_under_const_ref<'a>( } fn api_func_shape_for_operator_ne( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, param_types: &mut [RsTypeKind], errors: &Errors, @@ -272,7 +272,7 @@ fn api_func_shape_for_operator_ne( } fn api_func_shape_for_operator_eq( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, param_types: &mut [RsTypeKind], errors: &Errors, @@ -297,7 +297,7 @@ fn api_func_shape_for_operator_eq( } fn api_func_shape_for_operator_lt( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, param_types: &mut [RsTypeKind], errors: &Errors, @@ -399,7 +399,7 @@ fn api_func_shape_for_operator_assign( } fn api_func_shape_for_operator_unary_plus( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, param_type: &RsTypeKind, errors: &Errors, ) -> ErrorsOr<(Ident, ImplKind)> { @@ -416,7 +416,7 @@ fn api_func_shape_for_operator_unary_plus( } fn extract_first_operator_parameter( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, param_types: &RsTypeKind, errors: &Errors, ) -> ErrorsOr<(Rc, ImplFor)> { @@ -448,7 +448,7 @@ fn extract_first_operator_parameter( } fn expect_possibly_incomplete_record<'a>( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, type_kind: &'a RsTypeKind, value_desc: &str, errors: &Errors, @@ -469,7 +469,7 @@ fn expect_possibly_incomplete_record<'a>( } fn record_type_of_compound_assignment<'a>( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, lhs_type: &'a mut RsTypeKind, errors: &Errors, ) -> ErrorsOr<&'a Rc> { @@ -520,12 +520,12 @@ fn record_type_of_compound_assignment<'a>( /// Reports a fatal error generating bindings for a function. /// Fatal errors should only be reported -fn report_fatal_func_error(db: &dyn BindingsGenerator, func: &Func, msg: &str) { +fn report_fatal_func_error(db: &BindingsGenerator, func: &Func, msg: &str) { db.fatal_errors().report(&format!("{}: {}", func.source_loc, msg)); } fn api_func_shape_for_operator( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, maybe_record: Option<&Rc>, param_types: &mut [RsTypeKind], @@ -606,7 +606,7 @@ fn api_func_shape_for_operator( } fn api_func_shape_for_identifier( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, maybe_record: Option<&Rc>, param_types: &mut [RsTypeKind], @@ -652,7 +652,7 @@ fn api_func_shape_for_identifier( } fn api_func_shape_for_destructor( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, maybe_record: Option<&Rc>, param_types: &mut [RsTypeKind], @@ -712,7 +712,7 @@ fn api_func_shape_for_destructor( /// Issue any errors related to unsafe constructors being unsupported. fn issue_unsafe_constructor_errors( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, record: &Record, param_types: &[RsTypeKind], @@ -755,7 +755,7 @@ fn issue_unsafe_constructor_errors( } fn api_func_shape_for_constructor( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, maybe_record: Option<&Rc>, param_types: &mut [RsTypeKind], @@ -869,7 +869,7 @@ fn api_func_shape_for_constructor( /// destructor might be mapped to no `Drop` impl at all.) /// * `(func_name, impl_kind)`: The function name and ImplKind. fn api_func_shape( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, param_types: &mut [RsTypeKind], errors: &Errors, @@ -910,7 +910,7 @@ fn api_func_shape( /// Returns the shape of the generated Rust API for a given function definition /// or `None` if no function will be generated. fn api_func_shape_if_some( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, param_types: &mut [RsTypeKind], ) -> Option<(Ident, ImplKind)> { @@ -925,7 +925,7 @@ fn api_func_shape_if_some( /// Implementation of `BindingsGenerator::get_binding`. pub fn get_binding( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, expected_function_name: UnqualifiedIdentifier, expected_param_types: Vec, ) -> Option<(Ident, ImplKind)> { @@ -946,7 +946,7 @@ pub fn get_binding( } /// Implementation of `BindingsGenerator::is_record_clonable`. -pub fn is_record_clonable(db: &dyn BindingsGenerator, record: Rc) -> bool { +pub fn is_record_clonable(db: &BindingsGenerator, record: Rc) -> bool { if !record.is_unpin() { return false; } @@ -1022,7 +1022,7 @@ struct ParamValueAdjustments { /// `param_types`-length list containing any necessary adjustments to the /// parameter values. fn adjust_param_types_for_trait_impl( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, impl_kind: &ImplKind, param_types: &mut [RsTypeKind], errors: &Errors, @@ -1060,7 +1060,7 @@ fn adjust_param_types_for_trait_impl( #[allow(clippy::too_many_arguments)] fn generate_func_body( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, impl_kind: &ImplKind, crate_root_path: TokenStream, return_type: &RsTypeKind, @@ -1326,7 +1326,7 @@ fn func_should_infer_lifetimes_of_references(func: &Func) -> bool { } fn rs_type_kinds_for_func( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, ) -> Result<(Vec, RsTypeKind)> { @@ -1399,7 +1399,7 @@ fn rs_type_kinds_for_func( /// Implementation of `BindingsGenerator::generate_function`. pub fn generate_function( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: Rc, derived_record: Option>, ) -> Result> { @@ -1869,7 +1869,7 @@ struct BindingsSignature { /// * serialize a `()` as the empty string. #[allow(clippy::too_many_arguments)] fn function_signature( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, features: &mut FlagSet, func: &Func, impl_kind: &ImplKind, @@ -2148,7 +2148,7 @@ fn function_signature( } fn move_self_from_out_param_to_return_value( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, return_type: &mut RsTypeKind, api_params: &mut Vec, @@ -2225,7 +2225,7 @@ fn format_tuple_except_singleton(iter: impl IntoIterator) -> } fn format_tuple_except_singleton_replacing_by_self( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, items: &[RsTypeKind], trait_record: Option<&Record>, ) -> TokenStream { @@ -2252,7 +2252,7 @@ fn format_tuple_except_singleton_replacing_by_self( /// /// where `SameType` is the same type as the class this function is declared in. fn has_copy_assignment_operator_from_const_reference( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, copy_constructor: &Func, ) -> bool { let [_self, first_param] = ©_constructor.params[..] else { @@ -2282,9 +2282,7 @@ fn has_copy_assignment_operator_from_const_reference( } /// Implementation of `BindingsGenerator::overload_sets`. -pub fn overload_sets( - db: &dyn BindingsGenerator, -) -> Rc, Option>> { +pub fn overload_sets(db: &BindingsGenerator) -> Rc, Option>> { #[derive(Copy, Clone)] struct CandidateFunction { item_id: ir::ItemId, diff --git a/rs_bindings_from_cc/generate_bindings/generate_function_thunk.rs b/rs_bindings_from_cc/generate_bindings/generate_function_thunk.rs index da9c83864..a567c8044 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_function_thunk.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_function_thunk.rs @@ -23,7 +23,7 @@ use unicode_ident::is_xid_continue; /// If we know the original C++ function is codegenned and already compatible /// with `extern "C"` calling convention we skip creating/calling the C++ thunk /// since we can call the original C++ directly. -pub fn can_skip_cc_thunk(db: &dyn BindingsGenerator, func: &Func) -> bool { +pub fn can_skip_cc_thunk(db: &BindingsGenerator, func: &Func) -> bool { // ## Inline functions // // Inline functions may not be codegenned in the C++ library since Clang doesn't @@ -117,7 +117,7 @@ pub fn can_skip_cc_thunk(db: &dyn BindingsGenerator, func: &Func) -> bool { } pub fn generate_function_thunk( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, param_idents: &[Ident], param_types: &[RsTypeKind], @@ -251,7 +251,7 @@ pub fn thunk_ident(func: &Func) -> Ident { } fn generate_function_assertation_for_identifier( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, id: &Identifier, ) -> Result { @@ -325,7 +325,7 @@ fn generate_function_assertation_for_identifier( } pub fn generate_function_assertation( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, ) -> Result> { if func.adl_enclosing_record.is_some() { @@ -365,7 +365,7 @@ fn is_copy_constructor(func: &Func, record_id: ItemId) -> bool { } pub fn generate_function_thunk_impl( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: &Func, ) -> Result> { if can_skip_cc_thunk(db, func) { diff --git a/rs_bindings_from_cc/generate_bindings/generate_struct_and_union.rs b/rs_bindings_from_cc/generate_bindings/generate_struct_and_union.rs index 941f4a550..fcde7dbe6 100644 --- a/rs_bindings_from_cc/generate_bindings/generate_struct_and_union.rs +++ b/rs_bindings_from_cc/generate_bindings/generate_struct_and_union.rs @@ -12,7 +12,6 @@ use database::code_snippet::{ NoUniqueAddressAccessor, RecursivelyPinnedAttr, SizeofImpl, StructOrUnion, Thunk, ThunkImpl, UpcastImpl, UpcastImplBody, Visibility, }; -use database::db; use database::rs_snippet::{should_derive_clone, RsTypeKind}; use database::BindingsGenerator; use error_report::{bail, ensure}; @@ -54,7 +53,7 @@ fn needs_manually_drop(ty: &RsTypeKind) -> bool { /// Generates Rust source code for a given incomplete record declaration. pub fn generate_incomplete_record( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, incomplete_record: Rc, ) -> Result { // If the record won't have bindings, we default to `public` to keep going anyway. @@ -99,7 +98,7 @@ fn make_rs_field_ident(field: &Field, field_index: usize) -> Ident { /// /// See docs/struct_layout fn get_field_rs_type_kind_for_layout( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, record: &Record, field: &Field, ) -> Result { @@ -164,7 +163,7 @@ fn get_field_rs_type_kind_for_layout( } fn collect_unqualified_member_functions_from_all_bases( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, record: &Record, ) -> Rc<[Rc]> { let ir = db.ir(); @@ -188,7 +187,7 @@ fn collect_unqualified_member_functions_from_all_bases( /// Implementation of `BindingsGenerator::collect_unqualified_member_functions`. pub fn collect_unqualified_member_functions( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, record: Rc, ) -> Rc<[Rc]> { let ir = db.ir(); @@ -216,7 +215,7 @@ pub fn collect_unqualified_member_functions( /// Ambiguous functions are functions that have the same name as a function in /// the base class. fn filter_out_ambiguous_member_functions( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, derived_record: Rc, inherited_functions: Rc<[Rc]>, ) -> Rc<[Rc]> { @@ -249,7 +248,7 @@ fn filter_out_ambiguous_member_functions( #[allow(clippy::too_many_arguments)] fn field_definition( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, record: &Record, field: Option<&ir::Field>, field_index: usize, @@ -315,7 +314,7 @@ fn field_definition( } }; let visibility = if field.access == AccessSpecifier::Public && field_rs_type_kind.is_ok() { - db::type_visibility(db, &record.owning_target, field_rs_type_kind.clone().unwrap()) + db.type_visibility(&record.owning_target, field_rs_type_kind.clone().unwrap()) .unwrap_or_default() } else { Visibility::PubCrate @@ -350,7 +349,7 @@ fn field_definition( } /// Implementation of `BindingsGenerator::generate_record`. -pub fn generate_record(db: &dyn BindingsGenerator, record: Rc) -> Result { +pub fn generate_record(db: &BindingsGenerator, record: Rc) -> Result { let record_rs_type_kind = db.rs_type_kind(record.as_ref().into())?; if matches!( &record_rs_type_kind, @@ -710,7 +709,7 @@ pub fn generate_record(db: &dyn BindingsGenerator, record: Rc) -> Result /// whether each child item should be nested in a module. pub fn child_items<'a, 'db>( record: &'a Record, - db: &'a dyn BindingsGenerator<'db>, + db: &'a BindingsGenerator<'db>, ) -> impl Iterator> + use<'a, 'db> { record.child_item_ids.iter().map(|&child_item_id| { let item = db.ir().find_untyped_decl(child_item_id); @@ -751,7 +750,7 @@ pub fn generate_derives(record: &Record) -> DeriveAttr { DeriveAttr(derives) } -fn cc_struct_layout_assertion(db: &dyn BindingsGenerator, record: &Record) -> Result { +fn cc_struct_layout_assertion(db: &BindingsGenerator, record: &Record) -> Result { let namespace_qualifier = db.ir().namespace_qualifier(record).format_for_cc()?; let fields_and_expected_offsets: Vec<(TokenStream, usize)> = record .fields @@ -801,7 +800,7 @@ fn cc_struct_layout_assertion(db: &dyn BindingsGenerator, record: &Record) -> Re /// Returns the accessor functions for no_unique_address member variables. fn cc_struct_no_unique_address_impl( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, record: &Record, ) -> Result> { let mut no_unique_address_accessors = vec![]; @@ -851,7 +850,7 @@ type UpcastImplResult = Result; /// Returns the implementation of base class conversions, for converting a type /// to its unambiguous public base classes. fn cc_struct_upcast_impl( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, record: &Rc, ir: &IR, ) -> Result<(Vec, Vec, Vec)> { diff --git a/rs_bindings_from_cc/generate_bindings/has_bindings.rs b/rs_bindings_from_cc/generate_bindings/has_bindings.rs index e3ea95d8f..4f81dfb6c 100644 --- a/rs_bindings_from_cc/generate_bindings/has_bindings.rs +++ b/rs_bindings_from_cc/generate_bindings/has_bindings.rs @@ -7,7 +7,6 @@ use database::code_snippet::{ required_crubit_features, BindingsInfo, NoBindingsReason, RequiredCrubitFeature, ResolvedTypeName, Visibility, }; -use database::db; use database::rs_snippet::RsTypeKind; use database::BindingsGenerator; use error_report::{anyhow, bail}; @@ -17,10 +16,7 @@ use std::collections::HashMap; use std::rc::Rc; /// Implementation of `BindingsGenerator::has_bindings`. -pub fn has_bindings( - db: &dyn BindingsGenerator, - item: Item, -) -> Result { +pub fn has_bindings(db: &BindingsGenerator, item: Item) -> Result { let ir = db.ir(); if let Some(name) = item.cc_name_as_str() { @@ -176,7 +172,7 @@ pub fn has_bindings( /// Returns function-specific `has_bindings` information. fn func_has_bindings( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, func: Rc, ) -> Result { if func.is_consteval { @@ -258,7 +254,7 @@ fn func_has_bindings( // // YMMV: feel free to unify the two functions later. pub fn type_target_restriction( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, rs_type_kind: RsTypeKind, ) -> Result> { // We visit `self` twice, but it doesn't matter, we just need a starting value. @@ -292,7 +288,7 @@ struct TargetRestriction { /// Returns an error if both are `pub(crate)`, and the two types are owned by different crates. /// The error contains just a list of the types it found that are incompatible. fn intersect_target_restrictions( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, old_restriction: &mut TargetRestriction, new_restriction: TargetRestriction, ) -> Result<()> { @@ -320,7 +316,7 @@ fn intersect_target_restrictions( /// For example, the top level visibility restriction of `*mut T` is `None` for all `T`, because /// pointers are never `pub(crate)`, only their pointees can be. fn type_target_restriction_shallow( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, rs_type_kind: RsTypeKind, ) -> TargetRestriction { let mut target = match rs_type_kind.unalias() { @@ -351,14 +347,14 @@ fn type_target_restriction_shallow( } fn type_visibility( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, item: &dyn GenericItem, rs_type_kind: RsTypeKind, ) -> Result { let Some(target) = item.owning_target() else { return Ok(Visibility::Public); }; - match db::type_visibility(db, &target, rs_type_kind.clone()) { + match db.type_visibility(&target, rs_type_kind.clone()) { Ok(vis) => Ok(vis), Err(error) => { let missing_features = vec![RequiredCrubitFeature { @@ -387,7 +383,7 @@ fn type_visibility( /// In the future, we may want to extend this to check the value namespace for functions and /// global variables as well. pub fn resolve_type_names( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, parent: Rc, ) -> Result, ResolvedTypeName>>> { let child_item_ids: &[ItemId] = diff --git a/rs_bindings_from_cc/generate_bindings/lib.rs b/rs_bindings_from_cc/generate_bindings/lib.rs index 5a38a83b9..82e7346ff 100644 --- a/rs_bindings_from_cc/generate_bindings/lib.rs +++ b/rs_bindings_from_cc/generate_bindings/lib.rs @@ -10,7 +10,7 @@ use crubit_abi_type::{CrubitAbiType, CrubitAbiTypeToRustExprTokens, FullyQualifi use database::code_snippet::{ self, ApiSnippets, Bindings, BindingsTokens, CppDetails, CppIncludes, Feature, GeneratedItem, }; -use database::db::{self, BindingsGenerator, CodegenFunctions, Database}; +use database::db::{BindingsGenerator, CodegenFunctions}; use database::rs_snippet::{ BridgeRsTypeKind, Callable, FnTrait, Mutability, RsTypeKind, RustPtrKind, }; @@ -101,10 +101,7 @@ pub fn generate_bindings( Ok(Bindings { rs_api, rs_api_impl }) } -fn generate_type_alias( - db: &dyn BindingsGenerator, - type_alias: Rc, -) -> Result { +fn generate_type_alias(db: &BindingsGenerator, type_alias: Rc) -> Result { // Skip the type alias if it maps to a bridge type. let rs_type_kind = db.rs_type_kind((&*type_alias).into())?; let generated_item = if rs_type_kind.unalias().is_bridge_type() { @@ -138,7 +135,8 @@ fn generate_type_alias( Some(&type_alias.source_loc), db.environment(), ), - visibility: db::type_visibility(db, &type_alias.owning_target, rs_type_kind) + visibility: db + .type_visibility(&type_alias.owning_target, rs_type_kind) .unwrap_or_default(), ident: make_rs_ident(&type_alias.rs_name.identifier), underlying_type: underlying_type.to_token_stream(db), @@ -151,7 +149,7 @@ fn generate_type_alias( }) } -fn generate_global_var(db: &dyn BindingsGenerator, var: Rc) -> Result { +fn generate_global_var(db: &BindingsGenerator, var: Rc) -> Result { let type_ = db.rs_type_kind(var.type_.clone())?; Ok(ApiSnippets { @@ -162,14 +160,14 @@ fn generate_global_var(db: &dyn BindingsGenerator, var: Rc) -> Result is_mut: !var.type_.is_const, ident: make_rs_ident(&var.rs_name.identifier), type_tokens: type_.to_token_stream(db), - visibility: db::type_visibility(db, &var.owning_target, type_).unwrap_or_default(), + visibility: db.type_visibility(&var.owning_target, type_).unwrap_or_default(), }, )]), ..Default::default() }) } -fn generate_namespace(db: &dyn BindingsGenerator, namespace: Rc) -> Result { +fn generate_namespace(db: &BindingsGenerator, namespace: Rc) -> Result { let ir = db.ir(); let mut api_snippets = ApiSnippets::default(); @@ -187,7 +185,7 @@ fn generate_namespace(db: &dyn BindingsGenerator, namespace: Rc) -> R } /// Implementation of `BindingsGenerator::generate_item`. -fn generate_item(db: &dyn BindingsGenerator, item: Item) -> Result { +fn generate_item(db: &BindingsGenerator, item: Item) -> Result { let _scope = item.error_scope(db.ir(), db.errors()); let err = match generate_item_impl(db, &item) { Ok(generated) => return Ok(generated), @@ -211,7 +209,7 @@ fn generate_item(db: &dyn BindingsGenerator, item: Item) -> Result /// The implementation of generate_item, without the error recovery logic. /// /// Returns Err if bindings could not be generated for this item. -fn generate_item_impl(db: &dyn BindingsGenerator, item: &Item) -> Result { +fn generate_item_impl(db: &BindingsGenerator, item: &Item) -> Result { let ir = db.ir(); if let Some(owning_target) = item.owning_target() { if !ir.is_current_target(&owning_target) { @@ -301,8 +299,8 @@ pub fn new_database<'db>( errors: &'db dyn ErrorReporting, fatal_errors: &'db dyn ReportFatalError, environment: Environment, -) -> Database<'db> { - Database::new( +) -> BindingsGenerator<'db> { + BindingsGenerator::new( ir, errors, fatal_errors, @@ -494,7 +492,7 @@ pub fn generate_bindings_tokens( } /// Implementation of `BindingsGenerator::is_rs_type_kind_unsafe`. -fn is_rs_type_kind_unsafe(db: &dyn BindingsGenerator, rs_type_kind: RsTypeKind) -> bool { +fn is_rs_type_kind_unsafe(db: &BindingsGenerator, rs_type_kind: RsTypeKind) -> bool { match rs_type_kind { RsTypeKind::Error { .. } => true, RsTypeKind::Pointer { .. } => true, @@ -549,7 +547,7 @@ fn is_rs_type_kind_unsafe(db: &dyn BindingsGenerator, rs_type_kind: RsTypeKind) /// Helper function for `is_rs_type_kind_unsafe`. /// Returns true if the record is unsafe, or if it transitively contains a public field of /// an unsafe type. -fn is_record_unsafe(db: &dyn BindingsGenerator, record: &Record) -> bool { +fn is_record_unsafe(db: &BindingsGenerator, record: &Record) -> bool { if record.is_unsafe_type { return true; } @@ -577,7 +575,7 @@ fn is_record_unsafe(db: &dyn BindingsGenerator, record: &Record) -> bool { } fn generate_rs_api_impl_includes( - db: &Database, + db: &BindingsGenerator, crubit_support_path_format: Format<1>, has_callables: bool, ) -> CppIncludes { @@ -684,7 +682,7 @@ fn make_transmute_abi_type_from_item( item: &impl GenericItem, rs_name: &str, cc_name: &str, - db: &dyn BindingsGenerator, + db: &BindingsGenerator, ) -> Result { // Rust names are of the form ":: tuples_golden :: NontrivialDrop" let mut rust_path = rs_name; @@ -716,7 +714,7 @@ fn make_transmute_abi_type_from_item( } /// Implementation of `BindingsGenerator::crubit_abi_type`. -fn crubit_abi_type(db: &dyn BindingsGenerator, rs_type_kind: RsTypeKind) -> Result { +fn crubit_abi_type(db: &BindingsGenerator, rs_type_kind: RsTypeKind) -> Result { match rs_type_kind { RsTypeKind::Error { error, .. } => { bail!("Type has an error and cannot be bridged: {error}") @@ -889,7 +887,7 @@ fn crubit_abi_type(db: &dyn BindingsGenerator, rs_type_kind: RsTypeKind) -> Resu /// `None` is returned if there is issue generating the thunk. The specific error is not reported /// because it will be reported elsewhere. fn generate_dyn_callable_cpp_thunk( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, dyn_callable: &Callable, param_idents: &[Ident], ) -> Option { @@ -976,7 +974,7 @@ fn generate_dyn_callable_cpp_thunk( /// `None` is returned if there is issue generating the definition. The specific error is not /// reported because it will be reported elsewhere. fn generate_dyn_callable_rust_thunk_impl( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, dyn_callable: Rc, param_idents: &[Ident], ) -> Option { @@ -1166,7 +1164,7 @@ fn strip_leading_colon2(path: &mut &str) -> bool { fn make_cpp_type_from_item( item: &impl GenericItem, cc_name_parts: &[&str], - db: &dyn BindingsGenerator, + db: &BindingsGenerator, ) -> Result { let namespace_qualifier = db.ir().namespace_qualifier(item); let parts = namespace_qualifier 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 ee0aef7d3..698ad19d6 100644 --- a/rs_bindings_from_cc/generate_bindings/rs_type_kind.rs +++ b/rs_bindings_from_cc/generate_bindings/rs_type_kind.rs @@ -11,7 +11,7 @@ use std::rc::Rc; /// Implementation of `BindingsGenerator::rs_type_kind`. pub fn rs_type_kind_with_lifetime_elision( - db: &dyn BindingsGenerator, + db: &BindingsGenerator, ty: CcType, lifetime_options: LifetimeOptions, ) -> Result { diff --git a/rs_bindings_from_cc/generate_bindings/test_generators.rs b/rs_bindings_from_cc/generate_bindings/test_generators.rs index bb9b4e211..1aec48c8b 100644 --- a/rs_bindings_from_cc/generate_bindings/test_generators.rs +++ b/rs_bindings_from_cc/generate_bindings/test_generators.rs @@ -6,7 +6,7 @@ use arc_anyhow::Result; use database::code_snippet::BindingsTokens; -use database::db::Database; +use database::db::BindingsGenerator; use error_report::{bail, ErrorReport, FatalErrors}; use ffi_types::Environment; use generate_bindings::{generate_bindings_tokens, new_database}; @@ -43,7 +43,7 @@ impl TestDbFactory { fatal_errors: FatalErrors::new(), }) } - pub fn make_db(&self) -> Database { + pub fn make_db(&self) -> BindingsGenerator { new_database(&self.ir, &self.errors, &self.fatal_errors, Environment::Production) } }