Skip to content

Commit a38b830

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 a38b830

File tree

4 files changed

+66
-21
lines changed

4 files changed

+66
-21
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

+24-9
Original file line numberDiff line numberDiff line change
@@ -783,16 +783,31 @@ 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() {
788-
debug!(
789-
"add_item_to_module: adding {:?} as child of parent module {:?}",
790-
item.id(),
791-
item.parent_id()
792-
);
786+
if let Some(parent_item) = self.resolve_item_fallible(item.parent_id())
787+
{
788+
let ancestor_module_id = if parent_item.is_module() {
789+
Some(item.parent_id())
790+
} else {
791+
item.parent_id().ancestors(self).find(|id| {
792+
let ancestor_item = self.resolve_item_fallible(*id);
793+
ancestor_item.map_or(false, |i| i.is_module())
794+
})
795+
};
793796

794-
module.children_mut().insert(item.id());
795-
return;
797+
if let Some(ancestor_module_id) = ancestor_module_id {
798+
if let Some(ref mut ancestor) = self.items[ancestor_module_id.0]
799+
{
800+
if let Some(module) = ancestor.as_module_mut() {
801+
debug!(
802+
"add_item_to_module: adding {:?} as child of ancestor module {:?}",
803+
item.id(),
804+
ancestor_module_id
805+
);
806+
807+
module.children_mut().insert(item.id());
808+
return;
809+
}
810+
}
796811
}
797812
}
798813

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)