Skip to content

Commit fc01611

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 rust-lang#2056 produces two items called f_iterator)
1 parent 26663d8 commit fc01611

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
@@ -499,6 +499,36 @@ impl Item {
499499
return false;
500500
}
501501

502+
// Skip duplicate type aliases.
503+
// If this item is a type alias or resolved ref, and its ultimate target
504+
// has the same canonical path and will also be generated, skip this one.
505+
if let ItemKind::Type(ty) = self.kind() {
506+
match ty.kind() {
507+
TypeKind::Alias(target_id) |
508+
TypeKind::ResolvedTypeRef(target_id) => {
509+
let direct_target = ctx.resolve_item(*target_id);
510+
// Check if the direct target has the same path and will be generated.
511+
// If so, skip generating this alias/ref because the direct target
512+
// will either be generated or skipped in favour of its target.
513+
if direct_target.id() != self.id() &&
514+
direct_target.canonical_path(ctx) ==
515+
self.canonical_path(ctx) &&
516+
ctx.codegen_items().contains(&direct_target.id())
517+
{
518+
debug!(
519+
"<Item as CodeGenerator>::process_before_codegen: Skipping duplicate alias {:?} because its direct target {:?} has the same path and will be generated",
520+
self.id(),
521+
direct_target.id()
522+
);
523+
// Mark as seen so we don't process it again if reachable through another path
524+
result.set_seen(self.id());
525+
return false;
526+
}
527+
}
528+
_ => {}
529+
}
530+
}
531+
502532
if !ctx.codegen_items().contains(&self.id()) {
503533
// TODO(emilio, #453): Figure out what to do when this happens
504534
// 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
@@ -1071,7 +1071,7 @@ impl Type {
10711071
CXType_Typedef => {
10721072
let inner = cursor.typedef_type().expect("Not valid Type?");
10731073
let inner_id =
1074-
Item::from_ty_or_ref(inner, location, None, ctx);
1074+
Item::from_ty_or_ref(inner, location, parent_id, ctx);
10751075
if inner_id == potential_id {
10761076
warn!(
10771077
"Generating opaque type instead of self-referential \

0 commit comments

Comments
 (0)