Skip to content

Commit e68b8c0

Browse files
authored
Merge pull request #2287 from goffrie/dont-traverse-stdint
Don't traverse through special-cased <stdint.h> types.
2 parents b5ec18e + 70115a0 commit e68b8c0

File tree

4 files changed

+78
-14
lines changed

4 files changed

+78
-14
lines changed

src/ir/context.rs

+20-14
Original file line numberDiff line numberDiff line change
@@ -2250,24 +2250,27 @@ If you encounter an error missing from this list, please file an issue or a PR!"
22502250
// Sized integer types from <stdint.h> get mapped to Rust primitive
22512251
// types regardless of whether they are blocklisted, so ensure that
22522252
// standard traits are considered derivable for them too.
2253-
None => match name {
2254-
"int8_t" | "uint8_t" | "int16_t" | "uint16_t" |
2255-
"int32_t" | "uint32_t" | "int64_t" |
2256-
"uint64_t" | "uintptr_t" | "intptr_t" |
2257-
"ptrdiff_t" => Some(CanDerive::Yes),
2258-
"size_t" if self.options.size_t_is_usize => {
2259-
Some(CanDerive::Yes)
2260-
}
2261-
"ssize_t" if self.options.size_t_is_usize => {
2262-
Some(CanDerive::Yes)
2263-
}
2264-
_ => Some(CanDerive::No),
2265-
},
2253+
None => Some(if self.is_stdint_type(name) {
2254+
CanDerive::Yes
2255+
} else {
2256+
CanDerive::No
2257+
}),
22662258
})
22672259
.unwrap_or(CanDerive::No)
22682260
})
22692261
}
22702262

2263+
/// Is the given type a type from <stdint.h> that corresponds to a Rust primitive type?
2264+
pub fn is_stdint_type(&self, name: &str) -> bool {
2265+
match name {
2266+
"int8_t" | "uint8_t" | "int16_t" | "uint16_t" | "int32_t" |
2267+
"uint32_t" | "int64_t" | "uint64_t" | "uintptr_t" |
2268+
"intptr_t" | "ptrdiff_t" => true,
2269+
"size_t" | "ssize_t" => self.options.size_t_is_usize,
2270+
_ => false,
2271+
}
2272+
}
2273+
22712274
/// Get a reference to the set of items we should generate.
22722275
pub fn codegen_items(&self) -> &ItemSet {
22732276
assert!(self.in_codegen_phase());
@@ -2355,7 +2358,10 @@ If you encounter an error missing from this list, please file an issue or a PR!"
23552358
TypeKind::Opaque |
23562359
TypeKind::TypeParam => return true,
23572360
_ => {}
2358-
};
2361+
}
2362+
if self.is_stdint_type(&name) {
2363+
return true;
2364+
}
23592365
}
23602366

23612367
// Unnamed top-level enums are special and we

src/ir/ty.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,13 @@ impl Trace for Type {
12061206
where
12071207
T: Tracer,
12081208
{
1209+
if self
1210+
.name()
1211+
.map_or(false, |name| context.is_stdint_type(name))
1212+
{
1213+
// These types are special-cased in codegen and don't need to be traversed.
1214+
return;
1215+
}
12091216
match *self.kind() {
12101217
TypeKind::Pointer(inner) |
12111218
TypeKind::Reference(inner) |

tests/expectations/tests/stdint_typedef.rs

+41
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/headers/stdint_typedef.h

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// bindgen-flags: --allowlist-type="Struct" --allowlist-function="fun"
2+
3+
// no typedef should be emitted for `__uint64_t`
4+
typedef unsigned long long __uint64_t;
5+
typedef __uint64_t uint64_t;
6+
7+
uint64_t fun();
8+
struct Struct {
9+
uint64_t field;
10+
};

0 commit comments

Comments
 (0)