rust-bindgen icon indicating copy to clipboard operation
rust-bindgen copied to clipboard

bindgen generates a value depending on a type parameter in `enable_if` on Mac

Open adetaylor opened this issue 9 months ago • 2 comments

Reproduction:

  • Mac OS 15.3.1, with the headers that come from xcode in /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
  • Input C++:
#include <cstddef>
  • Command line: cargo run -- test.hpp --no-layout-tests --enable-cxx-namespaces -- -std=c++14

Output:

/* automatically generated by rust-bindgen 0.71.1 */

#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
pub mod root {
    #[allow(unused_imports)]
    use self::super::root;
    pub const _LIBCPP_ABI_VERSION: u32 = 1;
    pub const _LIBCPP_HARDENING_MODE_DEFAULT: u32 = 2;
    pub const _LIBCPP_VERSION: u32 = 180100;
    pub const _LIBCPP_STD_VER: u32 = 14;
    pub const _LIBCPP_OBJECT_FORMAT_MACHO: u32 = 1;
    pub const _LIBCPP_HARDENING_MODE_NONE: u32 = 2;
    pub const _LIBCPP_HARDENING_MODE_FAST: u32 = 4;
    pub const _LIBCPP_HARDENING_MODE_EXTENSIVE: u32 = 16;
    pub const _LIBCPP_HARDENING_MODE_DEBUG: u32 = 8;
    pub const _LIBCPP_HARDENING_MODE: u32 = 2;
    pub const _LIBCPP_LOCALE__L_EXTENSIONS: u32 = 1;
    pub const _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION: u32 = 0;
    pub const _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY: u32 = 1;
    pub const _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT: u32 = 1;
    pub const _LIBCPP_AVAILABILITY_HAS_SYNC: u32 = 1;
    pub const _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT: u32 = 0;
    pub const _LIBCPP_AVAILABILITY_HAS_PMR: u32 = 1;
    pub const _LIBCPP_AVAILABILITY_HAS_TZDB: u32 = 0;
    pub const _LIBCPP_AVAILABILITY_HAS_PRINT: u32 = 0;
    pub const _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 : u32 = 1 ;
    pub const __cpp_lib_chrono_udls: u32 = 201304;
    pub const __cpp_lib_complex_udls: u32 = 201309;
    pub const __cpp_lib_exchange_function: u32 = 201304;
    pub const __cpp_lib_generic_associative_lookup: u32 = 201304;
    pub const __cpp_lib_integer_sequence: u32 = 201304;
    pub const __cpp_lib_integral_constant_callable: u32 = 201304;
    pub const __cpp_lib_is_final: u32 = 201402;
    pub const __cpp_lib_is_null_pointer: u32 = 201309;
    pub const __cpp_lib_make_reverse_iterator: u32 = 201402;
    pub const __cpp_lib_make_unique: u32 = 201304;
    pub const __cpp_lib_null_iterators: u32 = 201304;
    pub const __cpp_lib_quoted_string_io: u32 = 201304;
    pub const __cpp_lib_result_of_sfinae: u32 = 201210;
    pub const __cpp_lib_robust_nonmodifying_seq_ops: u32 = 201304;
    pub const __cpp_lib_shared_timed_mutex: u32 = 201402;
    pub const __cpp_lib_string_udls: u32 = 201304;
    pub const __cpp_lib_transformation_trait_aliases: u32 = 201304;
    pub const __cpp_lib_transparent_operators: u32 = 201210;
    pub const __cpp_lib_tuple_element_t: u32 = 201402;
    pub const __cpp_lib_tuples_by_type: u32 = 201304;
    pub mod std {
        #[allow(unused_imports)]
        use self::super::super::root;
        unsafe extern "C" {
            #[link_name = "\u{1}__ZNSt3__122__libcpp_verbose_abortEPKcz"]
            pub fn __libcpp_verbose_abort(
                __format: *const ::std::os::raw::c_char,
                ...
            );
        }
        unsafe extern "C" {
            #[link_name = "\u{1}__ZNSt3__15__useEPKcz"]
            pub fn __use(arg1: *const ::std::os::raw::c_char, ...);
        }
        pub type __enable_if_t = u8;
        pub type enable_if_t = u8;
        pub type integral_constant_value_type<_Tp> = _Tp;
        pub type integral_constant_type = u8;
        unsafe extern "C" {
            pub static value: _Tp;
        }
        pub type true_type = u8;
        pub type false_type = u8;
        pub type _BoolConstant = u8;
        #[repr(C)]
        #[derive(Debug, Copy, Clone)]
        pub struct remove_const {
            pub _address: u8,
        }
        pub type remove_const_type<_Tp> = _Tp;
        pub type __remove_const_t<_Tp> = _Tp;
        pub type remove_const_t<_Tp> = root::std::__remove_const_t<_Tp>;
        #[repr(C)]
        #[derive(Debug, Copy, Clone)]
        pub struct remove_volatile {
            pub _address: u8,
        }
        pub type remove_volatile_type<_Tp> = _Tp;
        pub type __remove_volatile_t<_Tp> = _Tp;
        pub type remove_volatile_t<_Tp> = root::std::__remove_volatile_t<_Tp>;
        #[repr(C)]
        #[derive(Debug, Copy, Clone)]
        pub struct remove_cv {
            pub _address: u8,
        }
        pub type remove_cv_type<_Tp> = _Tp;
        pub type __remove_cv_t<_Tp> = _Tp;
        pub type remove_cv_t<_Tp> = root::std::__remove_cv_t<_Tp>;
        #[repr(C)]
        #[derive(Debug, Copy, Clone)]
        pub struct __libcpp_is_integral {
            pub _address: u8,
        }
        pub const __libcpp_is_integral_value:
            root::std::__libcpp_is_integral__bindgen_ty_1 = 0;
        pub type __libcpp_is_integral__bindgen_ty_1 = i32;
        #[repr(C)]
        #[derive(Debug, Copy, Clone)]
        pub struct is_integral {
            pub _address: u8,
        }
    }
    pub type max_align_t = f64;
}

Note this bit:

        unsafe extern "C" {
            pub static value: _Tp;
        }

_Tp here is not a type available at this time, so the resultant bindings don't build:

error[E0412]: cannot find type `_Tp` in this scope

I'll try to creduce this and report back here whether I succeed or fail.

As this depends on the surrounding heade

adetaylor avatar Feb 26 '25 11:02 adetaylor

Reproduction across Mac and Linux:

  • On Mac: clang -E test.hpp > bigtest.hpp
  • Edit bigtest.hpp to remove lines 30 and 31 defining char16_t and friends
  • Transfer bigtest.hpp to Linux
  • Run cargo run -- bigtest.hpp --no-layout-tests --enable-cxx-namespaces -- -std=c++14 on Linux I'm loath to add bigtest.hpp to here as it may contain OS X copyrighted stuff I guess. I'll see if I can creduce it.

adetaylor avatar Feb 26 '25 13:02 adetaylor

Here's the creduced version:

template <class _Tp, _Tp> struct a {
  static const _Tp value;
};
template <class _Tp, _Tp b> const _Tp a<_Tp, b>::value;
 cargo run -- test.hpp --no-layout-tests --enable-cxx-namespaces -- -std=c++14

gives

#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
pub mod root {
    #[allow(unused_imports)]
    use self::super::root;
    unsafe extern "C" {
        pub static value: _Tp;
    }
}

adetaylor avatar Feb 28 '25 13:02 adetaylor