Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/bindgen/ir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,16 @@ impl Type {
_ => return None,
};

if path.generics().is_empty() {
return None;
// Special-case: when a ZST like `()` is used as the generic parameter of `NonNull`, it
// evaporates during parsing and `NonNull` ends up with zero generics. In that case, treat
// it as `void*` so aliases like `type Id = NonNull<()>;` lower correctly.
if path.generics().is_empty() && path.name() == "NonNull" {
return Some(Type::Ptr {
ty: Box::new(Type::Primitive(PrimitiveType::Void)),
is_const: false,
is_nullable: false,
is_ref: false,
});
}

if path.generics().len() != 1 {
Expand Down
4 changes: 4 additions & 0 deletions tests/expectations-symbols/nonnull_unit.c.sym
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
takes_id;
takes_unit_ptr;
};
10 changes: 10 additions & 0 deletions tests/expectations/nonnull_unit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef void *MyId;

void takes_id(MyId id);

void takes_unit_ptr(void *id);
18 changes: 18 additions & 0 deletions tests/expectations/nonnull_unit.compat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef void *MyId;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void takes_id(MyId id);

void takes_unit_ptr(void *id);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
15 changes: 15 additions & 0 deletions tests/expectations/nonnull_unit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>

using MyId = void*;

extern "C" {

void takes_id(MyId id);

void takes_unit_ptr(void *id);

} // extern "C"
13 changes: 13 additions & 0 deletions tests/expectations/nonnull_unit.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
cdef extern from *:
ctypedef bint bool
ctypedef struct va_list

cdef extern from *:

ctypedef void *MyId;

void takes_id(MyId id);

void takes_unit_ptr(void *id);
16 changes: 16 additions & 0 deletions tests/rust/nonnull_unit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use core::ptr::NonNull;

// Reproducer: generic argument is a ZST `()` which evaporates in parsing.
pub type MyId = NonNull<()>;

#[no_mangle]
pub extern "C" fn takes_id(id: MyId) {
let _ = id;
}

#[no_mangle]
pub extern "C" fn takes_unit_ptr(id: *mut ()) {
let _ = id;
}