Skip to content

Commit 083c43f

Browse files
committed
Prevent emission of type aliases in root module for inner types
* Emit aliases in the nearest ancestor module if the parent is not a module, rather than in the root module * If an alias would refer to itself, don't emit it (this is really a workaround for the fact that names are sometimes not unique enough, e.g. the header in #2056 produces two items called f_iterator)
1 parent 97ab915 commit 083c43f

File tree

4 files changed

+52
-16
lines changed

4 files changed

+52
-16
lines changed

bindgen-tests/tests/expectations/tests/opaque-template-instantiation-namespaced.rs

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

bindgen/codegen/mod.rs

+30
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,36 @@ impl Item {
500500
return false;
501501
}
502502

503+
// Skip duplicate type aliases.
504+
// If this item is a type alias or resolved ref, and its ultimate target
505+
// has the same canonical path and will also be generated, skip this one.
506+
if let ItemKind::Type(ty) = self.kind() {
507+
match ty.kind() {
508+
TypeKind::Alias(target_id) |
509+
TypeKind::ResolvedTypeRef(target_id) => {
510+
let direct_target = ctx.resolve_item(*target_id);
511+
// Check if the direct target has the same path and will be generated.
512+
// If so, skip generating this alias/ref because the direct target
513+
// will either be generated or skipped in favour of its target.
514+
if direct_target.id() != self.id() &&
515+
direct_target.canonical_path(ctx) ==
516+
self.canonical_path(ctx) &&
517+
ctx.codegen_items().contains(&direct_target.id())
518+
{
519+
debug!(
520+
"<Item as CodeGenerator>::process_before_codegen: Skipping duplicate alias {:?} because its direct target {:?} has the same path and will be generated",
521+
self.id(),
522+
direct_target.id()
523+
);
524+
// Mark as seen so we don't process it again if reachable through another path
525+
result.set_seen(self.id());
526+
return false;
527+
}
528+
}
529+
_ => {}
530+
}
531+
}
532+
503533
if !ctx.codegen_items().contains(&self.id()) {
504534
// TODO(emilio, #453): Figure out what to do when this happens
505535
// legitimately, we could track the opaque stuff and disable the

bindgen/ir/context.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -783,17 +783,23 @@ If you encounter an error missing from this list, please file an issue or a PR!"
783783
assert_ne!(item.id(), self.root_module);
784784
assert!(self.resolve_item_fallible(item.id()).is_none());
785785

786-
if let Some(ref mut parent) = self.items[item.parent_id().0] {
787-
if let Some(module) = parent.as_module_mut() {
786+
let mut ancestor_id = item.parent_id();
787+
while let Some(ref mut ancestor_item) = self.items[ancestor_id.0] {
788+
if let Some(module) = ancestor_item.as_module_mut() {
788789
debug!(
789-
"add_item_to_module: adding {:?} as child of parent module {:?}",
790+
"add_item_to_module: adding {:?} as child of ancestor module {:?}",
790791
item.id(),
791-
item.parent_id()
792+
ancestor_id
792793
);
793794

794795
module.children_mut().insert(item.id());
795796
return;
796797
}
798+
799+
ancestor_id = ancestor_item.parent_id();
800+
if ancestor_id == ancestor_item.id() {
801+
break;
802+
}
797803
}
798804

799805
debug!(

bindgen/ir/ty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,7 @@ impl Type {
10581058
CXType_Typedef => {
10591059
let inner = cursor.typedef_type().expect("Not valid Type?");
10601060
let inner_id =
1061-
Item::from_ty_or_ref(inner, location, None, ctx);
1061+
Item::from_ty_or_ref(inner, location, parent_id, ctx);
10621062
if inner_id == potential_id {
10631063
warn!(
10641064
"Generating opaque type instead of self-referential \

0 commit comments

Comments
 (0)