diff --git a/cc_bindings_from_rs/generate_bindings/format_type.rs b/cc_bindings_from_rs/generate_bindings/format_type.rs index 509c5f9ca..0a187d454 100644 --- a/cc_bindings_from_rs/generate_bindings/format_type.rs +++ b/cc_bindings_from_rs/generate_bindings/format_type.rs @@ -122,7 +122,6 @@ pub fn format_str_ref_for_cc(db: &dyn BindingsGenerator<'_>) -> CcSnippet { pub fn format_transparent_pointee_or_reference_for_cc<'tcx>( db: &dyn BindingsGenerator<'tcx>, referent_ty: Ty<'tcx>, - referer_hir: Option<&rustc_hir::Ty<'tcx>>, mutability: rustc_middle::mir::Mutability, pointer_sigil: TokenStream, ) -> Option { @@ -137,11 +136,7 @@ pub fn format_transparent_pointee_or_reference_for_cc<'tcx>( } let referent_mid = substs[0].expect_ty(); - let referent = if db.enable_hir_types() { - SugaredTy::new(referent_mid, referer_hir) - } else { - SugaredTy::missing_hir(referent_mid) - }; + let referent = SugaredTy::missing_hir(referent_mid); format_pointer_or_reference_ty_for_cc(db, referent, mutability, pointer_sigil).ok() } @@ -159,14 +154,6 @@ pub fn format_ty_for_cc<'tcx>( CcSnippet::new(tokens) } - // format_core_alias_for_cc relies on hir types to determine if an alias is present, so there's - // no reason to check one if hir types are disabled. - if db.enable_hir_types() { - if let Some(alias) = format_core_alias_for_cc(db, ty) { - return Ok(alias); - } - } - Ok(match ty.mid().kind() { ty::TyKind::Never => match location { TypeLocation::FnReturn => keyword(quote! { void }), @@ -371,44 +358,20 @@ pub fn format_ty_for_cc<'tcx>( ty::TyKind::RawPtr(pointee_mid, mutbl) => { if let ty::TyKind::Slice(slice_ty) = pointee_mid.kind() { check_slice_layout(db.tcx(), ty.mid()); - let sugared_ty = if db.enable_hir_types() { - let mut slice_hir_ty = None; - if let Some(hir) = ty.hir(db) { - if let rustc_hir::TyKind::Ptr(pointee) = &hir.kind { - if let rustc_hir::TyKind::Slice(slice_ty) = &pointee.ty.kind { - slice_hir_ty = Some(*slice_ty); - } - } - } - SugaredTy::new(*slice_ty, slice_hir_ty) - } else { - SugaredTy::missing_hir(*slice_ty) - }; + let sugared_ty = SugaredTy::missing_hir(*slice_ty); return format_slice_pointer_for_cc(db, sugared_ty, *mutbl); } - let mut pointee_hir = None; - if let Some(hir) = ty.hir(db) { - if let rustc_hir::TyKind::Ptr(mut_p) = hir.kind { - pointee_hir = Some(mut_p.ty); - } - } - // Early return in case we handle a transparent pointer type. if let Some(snippet) = format_transparent_pointee_or_reference_for_cc( db, *pointee_mid, - pointee_hir, *mutbl, quote! { * }, ) { return Ok(snippet); } - let pointee = if db.enable_hir_types() { - SugaredTy::new(*pointee_mid, pointee_hir) - } else { - SugaredTy::missing_hir(*pointee_mid) - }; + let pointee = SugaredTy::missing_hir(*pointee_mid); format_pointer_or_reference_ty_for_cc(db, pointee, *mutbl, quote! { * }).with_context( || format!("Failed to format the pointee of the pointer type `{ty}`"), )? @@ -435,13 +398,6 @@ pub fn format_ty_for_cc<'tcx>( return Ok(format_str_ref_for_cc(db)); } - let mut referent_hir = None; - if let Some(hir) = ty.hir(db) { - if let rustc_hir::TyKind::Ref(_, mut_p, ..) = &hir.kind { - referent_hir = Some(mut_p.ty); - } - } - let treat_ref_as_ptr = treat_ref_as_ptr(tcx, ty.mid(), location); let mut prereqs = CcPrerequisites::default(); @@ -468,18 +424,13 @@ pub fn format_ty_for_cc<'tcx>( if let Some(snippet) = format_transparent_pointee_or_reference_for_cc( db, *referent_mid, - referent_hir, *mutability, ptr_or_ref_prefix.clone(), ) { return Ok(snippet); } - let referent = if db.enable_hir_types() { - SugaredTy::new(*referent_mid, referent_hir) - } else { - SugaredTy::missing_hir(*referent_mid) - }; + let referent = SugaredTy::missing_hir(*referent_mid); let tokens = format_pointer_or_reference_ty_for_cc(db, referent, *mutability, ptr_or_ref_prefix) .with_context(|| { @@ -525,17 +476,10 @@ pub fn format_ty_for_cc<'tcx>( let mut prereqs = CcPrerequisites::default(); prereqs.includes.insert(db.support_header("internal/cxx20_backports.h")); - let mut sig_hir = None; - if let Some(hir) = ty.hir(db) { - if let rustc_hir::TyKind::FnPtr(bare_fn) = &hir.kind { - sig_hir = Some(bare_fn.decl); - } - } - let ret_type = format_ret_ty_for_cc(db, &sig, sig_hir)?.into_tokens(&mut prereqs); - let param_types = - format_param_types_for_cc(db, &sig, sig_hir, /*has_self_param=*/ false)? - .into_iter() - .map(|cc_param| cc_param.snippet.into_tokens(&mut prereqs)); + let ret_type = format_ret_ty_for_cc(db, &sig)?.into_tokens(&mut prereqs); + let param_types = format_param_types_for_cc(db, &sig, /*has_self_param=*/ false)? + .into_iter() + .map(|cc_param| cc_param.snippet.into_tokens(&mut prereqs)); let tokens = quote! { crubit::type_identity_t< #ret_type( #( #param_types ),* ) @@ -592,84 +536,12 @@ fn treat_ref_as_ptr<'tcx>( RefConvert::ToRef } -/// Returns `Some(CcSnippet)` if `ty` is a special-cased alias type from -/// `core::ffi` (AKA `std::ffi`). -/// -/// TODO(b/283258442): Also handle `libc` aliases. -fn format_core_alias_for_cc<'tcx>( - db: &dyn BindingsGenerator<'tcx>, - ty: SugaredTy<'tcx>, -) -> Option { - use rustc_hir::definitions::{DefPathData::TypeNs, DisambiguatedDefPathData}; - fn matches_type_path(actual: &[DisambiguatedDefPathData], expected: &[&str]) -> bool { - if actual.len() != expected.len() { - return false; - } - for i in 0..actual.len() { - let TypeNs(actual_elem) = actual[i].data else { - return false; - }; - if actual_elem.as_str() != expected[i] { - return false; - } - } - true - } - - let tcx = db.tcx(); - let hir_ty = ty.hir(db)?; - let rustc_hir::TyKind::Path(rustc_hir::QPath::Resolved(None, path)) = &hir_ty.kind else { - return None; - }; - let rustc_hir::def::Res::Def(rustc_hir::def::DefKind::TyAlias, alias_def_id) = &path.res else { - return None; - }; - let def_path = tcx.def_path(*alias_def_id); - - // Note: the `std::ffi` aliases are still originally defined in `core::ffi`, so - // we only need to check for a crate name of `core` here. - if tcx.crate_name(def_path.krate) != sym::core { - return None; - }; - let [module_path @ .., item] = def_path.data.as_slice() else { return None }; - // Primitives are defined in both `core::ffi` and `core::ffi::primitives - if !matches_type_path(module_path, &["ffi"]) - && !matches_type_path(module_path, &["ffi", "primitives"]) - { - return None; - } - let TypeNs(item) = item.data else { - return None; - }; - - let cpp_type = match item.as_str() { - "c_char" => quote! { char}, - "c_schar" => quote! { signed char}, - "c_uchar" => quote! { unsigned char}, - "c_short" => quote! { short}, - "c_ushort" => quote! { unsigned short}, - "c_int" => quote! { int}, - "c_uint" => quote! { unsigned int}, - "c_long" => quote! { long}, - "c_ulong" => quote! { unsigned long}, - "c_longlong" => quote! { long long}, - "c_ulonglong" => quote! { unsigned long long}, - _ => return None, - }; - Some(CcSnippet::new(cpp_type)) -} - /// Returns the C++ return type. -/// -/// `sig_hir` is the optional HIR `FnDecl`, if available. This is used to -/// retrieve alias information. pub fn format_ret_ty_for_cc<'tcx>( db: &dyn BindingsGenerator<'tcx>, sig_mid: &ty::FnSig<'tcx>, - sig_hir: Option<&rustc_hir::FnDecl<'tcx>>, ) -> Result { - let output_ty = - SugaredTy::fn_output(sig_mid, if db.enable_hir_types() { sig_hir } else { None }); + let output_ty = SugaredTy::fn_output(sig_mid, None); db.format_ty_for_cc(output_ty, TypeLocation::FnReturn) .with_context(|| format!("Error formatting function return type `{output_ty}`")) } @@ -711,18 +583,13 @@ pub struct CcParamTy { } /// Returns the C++ parameter types. -/// -/// `sig_hir` is the optional HIR FnSig, if available. This is used to retrieve -/// alias information. pub fn format_param_types_for_cc<'tcx>( db: &dyn BindingsGenerator<'tcx>, sig_mid: &ty::FnSig<'tcx>, - sig_hir: Option<&rustc_hir::FnDecl<'tcx>>, has_self_param: bool, ) -> Result> { let elided_is_output = has_elided_region(db.tcx(), sig_mid.output()); - let param_types = - SugaredTy::fn_inputs(sig_mid, if db.enable_hir_types() { sig_hir } else { None }); + let param_types = SugaredTy::fn_inputs(sig_mid, None); let mut snippets = Vec::with_capacity(param_types.len()); for (i, param_type) in param_types.enumerate() { let is_self_param = i == 0 && has_self_param; diff --git a/cc_bindings_from_rs/generate_bindings/format_type_test.rs b/cc_bindings_from_rs/generate_bindings/format_type_test.rs index 19036ff06..0fd0100cc 100644 --- a/cc_bindings_from_rs/generate_bindings/format_type_test.rs +++ b/cc_bindings_from_rs/generate_bindings/format_type_test.rs @@ -159,24 +159,6 @@ fn test_format_ty_for_cc_successes() { case!(rs: "bool", cc: "bool"), case!(rs: "f32", cc: "float"), case!(rs: "f64", cc: "double"), - // The ffi aliases are special-cased to refer to the C++ fundamental integer types, - // if the type alias information is not lost (e.g. from generics). - case!(rs: "std::ffi::c_char", cc: "char"), - case!(rs: "::std::ffi::c_char", cc: "char"), - case!(rs: "core::ffi::c_char", cc: "char"), - case!(rs: "::core::ffi::c_char", cc: "char"), - case!(rs: "std::ffi::c_uchar", cc: "unsigned char"), - case!(rs: "std::ffi::c_longlong", cc: "long long"), - case!(rs: "c_char", cc: "char"), - // Simple pointers/references do not lose the type alias information. - case!(rs: "*const std::ffi::c_uchar", cc: "unsigned char const *"), - case!( - rs: "&'static std::ffi::c_uchar", - cc: "unsigned char const * [[clang :: annotate_type (\"lifetime\" , \"static\")]] crubit_nonnull", - includes: [""] - ), - // Generics lose type alias information. - case!(rs: "Identity", cc: "std::int64_t", includes: [""]), case!(rs: "i8", cc: "std::int8_t", includes: [""]), case!(rs: "i16", cc: "std::int16_t", includes: [""]), case!(rs: "i32", cc: "std::int32_t", includes: [""]), @@ -218,11 +200,6 @@ fn test_format_ty_for_cc_successes() { cc: "rs_std::SliceRef", includes: ["", ""] ), - case!( - rs: "*const [c_char]", - cc: "rs_std::SliceRef", - includes: [""] - ), case!( rs: "*mut [SomeStruct]", cc: "rs_std::SliceRef< ::rust_out::SomeStruct>", @@ -334,10 +311,6 @@ fn test_format_ty_for_cc_successes() { #[allow(unused)] type Identity = T; - - pub use core::ffi::c_char; - // TODO(b/283258442): Correctly handle something like this: - // pub type MyChar = core::ffi::c_char; }; test_ty( TypeLocation::FnParam { is_self_param: false, elided_is_output: false }, diff --git a/cc_bindings_from_rs/generate_bindings/generate_bindings_test.rs b/cc_bindings_from_rs/generate_bindings/generate_bindings_test.rs index 09262776c..9a879a405 100644 --- a/cc_bindings_from_rs/generate_bindings/generate_bindings_test.rs +++ b/cc_bindings_from_rs/generate_bindings/generate_bindings_test.rs @@ -289,23 +289,27 @@ fn test_generated_bindings_prereq_fwd_decls_deterministic_order() { // Verifying that we get the same order in each test // run is the essence of this test. namespace a { - struct S1; struct S2; + struct S1; } ... - void f3 ... + void f2 ... namespace b { ... struct CRUBIT_INTERNAL_RUST_TYPE(...) alignas(...) [[clang::trivial_abi]] S3 final { ... } ... } ... - void f2 ... - void f1 ... + namespace a { ... + struct CRUBIT_INTERNAL_RUST_TYPE(...) alignas(...) [[clang::trivial_abi]] S2 final { ... } ... + } ... + + void f3 ... namespace a { ... struct CRUBIT_INTERNAL_RUST_TYPE(...) alignas(...) [[clang::trivial_abi]] S1 final { ... } ... - struct CRUBIT_INTERNAL_RUST_TYPE(...) alignas(...) [[clang::trivial_abi]] S2 final { ... } ... } ... + + void f1 ... } // namespace rust_out } ); diff --git a/cc_bindings_from_rs/generate_bindings/generate_function.rs b/cc_bindings_from_rs/generate_bindings/generate_function.rs index 84a2046cb..bed4aae39 100644 --- a/cc_bindings_from_rs/generate_bindings/generate_function.rs +++ b/cc_bindings_from_rs/generate_bindings/generate_function.rs @@ -627,16 +627,14 @@ pub fn generate_function(db: &dyn BindingsGenerator<'_>, def_id: DefId) -> Resul }; let mut main_api_prereqs = CcPrerequisites::default(); - let main_api_ret_type = - format_ret_ty_for_cc(db, &sig_mid, sig_hir)?.into_tokens(&mut main_api_prereqs); + let main_api_ret_type = format_ret_ty_for_cc(db, &sig_mid)?.into_tokens(&mut main_api_prereqs); let params = { let names = tcx.fn_arg_idents(def_id).iter(); - let cpp_types = - format_param_types_for_cc(db, &sig_mid, sig_hir, function_kind.has_self_param())?; + let cpp_types = format_param_types_for_cc(db, &sig_mid, function_kind.has_self_param())?; names .enumerate() - .zip(SugaredTy::fn_inputs(&sig_mid, if db.enable_hir_types() { sig_hir } else { None })) + .zip(SugaredTy::fn_inputs(&sig_mid, None)) .zip(cpp_types) .map(|(((i, name), ty), cpp_type)| { // TODO(jeanpierreda): deduplicate this with thunk_param_names. @@ -725,8 +723,7 @@ pub fn generate_function(db: &dyn BindingsGenerator<'_>, def_id: DefId) -> Resul quote! { #cpp_type #cc_name #annotation } }) .collect_vec(); - let rs_return_type = - SugaredTy::fn_output(&sig_mid, if db.enable_hir_types() { sig_hir } else { None }); + let rs_return_type = SugaredTy::fn_output(&sig_mid, None); let main_api = { let doc_comment = { let doc_comment = generate_doc_comment(db, def_id); 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 0ebe55c35..106e0cfe8 100644 --- a/cc_bindings_from_rs/generate_bindings/generate_function_thunk.rs +++ b/cc_bindings_from_rs/generate_bindings/generate_function_thunk.rs @@ -88,10 +88,10 @@ pub fn generate_thunk_decl<'tcx>( ) -> Result { let tcx = db.tcx(); let mut prereqs = CcPrerequisites::default(); - let main_api_ret_type = format_ret_ty_for_cc(db, sig_mid, sig_hir)?.into_tokens(&mut prereqs); + let main_api_ret_type = format_ret_ty_for_cc(db, sig_mid)?.into_tokens(&mut prereqs); let mut thunk_params = { - let cpp_types = format_param_types_for_cc(db, sig_mid, sig_hir, has_self_param)?; + let cpp_types = format_param_types_for_cc(db, sig_mid, has_self_param)?; sig_mid .inputs() .iter() @@ -161,8 +161,7 @@ pub fn generate_thunk_decl<'tcx>( let mut attributes = vec![]; // Attribute: noreturn - let rs_return_type = - SugaredTy::fn_output(sig_mid, if db.enable_hir_types() { sig_hir } else { None }); + let rs_return_type = SugaredTy::fn_output(sig_mid, None); if *rs_return_type.mid().kind() == ty::TyKind::Never { attributes.push(quote! {[[noreturn]]}); } 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 f2264ddfa..f74a5b0b7 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 @@ -77,33 +77,7 @@ fn cpp_enum_cpp_underlying_type(db: &dyn BindingsGenerator, def_id: DefId) -> Re let field_middle_ty = cpp_enum_rust_underlying_type(tcx, def_id)?; - let field_type = if db.enable_hir_types() { - use rustc_hir::ItemKind; - let field_hir_ty = match tcx.hir_node_by_def_id(def_id.expect_local()) { - rustc_hir::Node::Item(hir_item) => match hir_item.kind { - ItemKind::Struct(_, _, variant_data) => { - if variant_data.fields().len() != 1 { - return Err(anyhow!( - "Expected one field in cpp_enum hir item, got {:?}", - variant_data.fields().len() - )); - } - Some(variant_data.fields()[0].ty) - } - _ => { - // ItemKind is not Struct. - return Err(anyhow!( - "Unexpected `ItemKind` in cpp_enum hir item: {:?}", - hir_item.kind - )); - } - }, - _ => None, // HIR node is not an Item. - }; - SugaredTy::new(field_middle_ty, field_hir_ty) - } else { - SugaredTy::missing_hir(field_middle_ty) - }; + let field_type = SugaredTy::missing_hir(field_middle_ty); db.format_ty_for_cc(field_type, TypeLocation::Other) } @@ -911,7 +885,7 @@ fn generate_tuple_struct_ctor<'tcx>( let field_tys = variant_fields_iter(tcx, core.as_ref()) .next() .expect("Tuple structs must have one variant") - .map(|IndexedVariantField { field_def, hir_field_ty, .. }| { + .map(|IndexedVariantField { field_def, .. }| { if field_def.vis != ty::Visibility::Public { // If our synthesized constructor would have a non public visibility, don't generate it as // we can't mirror that visibility in C++. @@ -929,11 +903,7 @@ fn generate_tuple_struct_ctor<'tcx>( return None; } - if db.enable_hir_types() { - Some(SugaredTy::new(ty, hir_field_ty)) - } else { - Some(SugaredTy::missing_hir(ty)) - } + Some(SugaredTy::missing_hir(ty)) }) .collect::>>()?; @@ -1080,12 +1050,8 @@ fn generate_fields<'tcx>( let mut variants_fields = variant_fields_iter(tcx, core) .map(|field_iter| { field_iter - .map(|IndexedVariantField { index, field_def, hir_field_ty }| { - let ty = if db.enable_hir_types() { - SugaredTy::new(field_def.ty(tcx, adt_generic_args), hir_field_ty) - } else { - SugaredTy::missing_hir(field_def.ty(tcx, adt_generic_args)) - }; + .map(|IndexedVariantField { index, field_def, .. }| { + let ty = SugaredTy::missing_hir(field_def.ty(tcx, adt_generic_args)); let size = get_layout(tcx, ty.mid()).map(|layout| layout.size().bytes()); let type_info = size.and_then(|size| { diff --git a/cc_bindings_from_rs/generate_bindings/generate_struct_and_union_test.rs b/cc_bindings_from_rs/generate_bindings/generate_struct_and_union_test.rs index e98e2353c..ac0f02ffe 100644 --- a/cc_bindings_from_rs/generate_bindings/generate_struct_and_union_test.rs +++ b/cc_bindings_from_rs/generate_bindings/generate_struct_and_union_test.rs @@ -1263,7 +1263,6 @@ fn test_cpp_enum_fails_if_implements_method() { } #[test] -#[should_panic] fn test_cpp_enum_fails_for_rust_union() { let test_src = r#" #![feature(transparent_unions)] @@ -1275,7 +1274,17 @@ fn test_cpp_enum_fails_for_rust_union() { } "#; - test_format_item(test_src, "Color", |_result| {}); + test_format_item(test_src, "Color", |result| { + assert_cc_matches!( + result.unwrap().unwrap().main_api.tokens, + quote! { + ... + __COMMENT__ "CRUBIT_ANNOTATE: cpp_enum=enum class\n\nGenerated from: ;l=6" + union CRUBIT_INTERNAL_RUST_TYPE(":: rust_out :: Color") Color : std::int32_t {}; + ... + } + ); + }); } #[test] diff --git a/cc_bindings_from_rs/generate_bindings/lib.rs b/cc_bindings_from_rs/generate_bindings/lib.rs index 3f513b68f..32e262471 100644 --- a/cc_bindings_from_rs/generate_bindings/lib.rs +++ b/cc_bindings_from_rs/generate_bindings/lib.rs @@ -53,7 +53,6 @@ use query_compiler::{ use quote::{format_ident, quote}; use rustc_abi::{AddressSpace, BackendRepr, Integer, Primitive, Scalar}; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{Item, ItemKind, Node}; use rustc_middle::dep_graph::DepContext; use rustc_middle::metadata::{ModChild, Reexport}; use rustc_middle::mir::ConstValue; @@ -774,21 +773,8 @@ fn generate_const(db: &dyn BindingsGenerator<'_>, def_id: DefId) -> Result item.expect_const().2, - Node::ImplItem(item) => item.expect_const().0, - _ => panic!("{}", unsupported_node_item_msg), - } - }); - SugaredTy::new(ty, hir_ty) - } else { - SugaredTy::missing_hir(ty) - }; + let rust_type = SugaredTy::missing_hir(ty); let cc_type_snippet = db.format_ty_for_cc(rust_type, TypeLocation::Const)?; let cc_type = cc_type_snippet.tokens; @@ -842,19 +828,7 @@ fn generate_type_alias( ) -> Result { let tcx = db.tcx(); let mir_ty = tcx.type_of(def_id).instantiate_identity(); - let alias_type = if db.enable_hir_types() { - let hir_ty = def_id.as_local().map(|local_def_id| { - let Item { kind: ItemKind::TyAlias(_, _, hir_ty, ..), .. } = - tcx.hir_expect_item(local_def_id) - else { - panic!("called generate_type_alias on a non-type-alias"); - }; - *hir_ty - }); - SugaredTy::new(mir_ty, hir_ty) - } else { - SugaredTy::missing_hir(mir_ty) - }; + let alias_type = SugaredTy::missing_hir(mir_ty); create_type_alias(db, def_id, using_name, alias_type) }