Skip to content

Commit f09ec6a

Browse files
committed
transpile: add submodule's reexports to consumers' import set
other exports from the submodule (for types it defines via enum/struct definitions) are already added to this set, but reexports were not. this meant that if we organized imports of std/core types into a submodule (which the transpiler itself does when `--reorganize-definitions` is passed), these imports would then be missing from the main module.
1 parent 714d0a2 commit f09ec6a

File tree

1 file changed

+54
-1
lines changed
  • c2rust-transpile/src/translator

1 file changed

+54
-1
lines changed

c2rust-transpile/src/translator/mod.rs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use syn::{
1818
ForeignItemStatic, ForeignItemType, Ident, Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn,
1919
ItemForeignMod, ItemImpl, ItemMacro, ItemMod, ItemStatic, ItemStruct, ItemTrait,
2020
ItemTraitAlias, ItemType, ItemUnion, ItemUse, Lit, MacroDelimiter, PathSegment, ReturnType,
21-
Stmt, Type, TypeTuple, Visibility,
21+
Stmt, Type, TypeTuple, UseTree, Visibility,
2222
};
2323
use syn::{BinOp, UnOp}; // To override `c_ast::{BinOp,UnOp}` from glob import.
2424

@@ -916,6 +916,42 @@ pub fn translate(
916916
}
917917
}
918918

919+
/// Represent the set of names made visible by a `use`: either a set of specific names, or a glob.
920+
enum IdentsOrGlob<'a> {
921+
Idents(Vec<&'a Ident>),
922+
Glob,
923+
}
924+
925+
impl<'a> IdentsOrGlob<'a> {
926+
fn join(self, other: Self) -> Self {
927+
use IdentsOrGlob::*;
928+
match (self, other) {
929+
(Glob, _) => Glob,
930+
(_, Glob) => Glob,
931+
(Idents(mut own), Idents(other)) => Idents({
932+
own.extend(other.into_iter());
933+
own
934+
}),
935+
}
936+
}
937+
}
938+
939+
/// Extract the set of names made visible by a `use`.
940+
fn use_idents<'a>(i: &'a UseTree) -> IdentsOrGlob<'a> {
941+
match i {
942+
UseTree::Path(up) => use_idents(&up.tree),
943+
UseTree::Name(un) => IdentsOrGlob::Idents(vec![&un.ident]),
944+
UseTree::Rename(ur) => IdentsOrGlob::Idents(vec![&ur.rename]),
945+
UseTree::Glob(_ugl) => IdentsOrGlob::Glob,
946+
UseTree::Group(ugr) => ugr
947+
.items
948+
.iter()
949+
.map(|tree| use_idents(tree))
950+
.reduce(IdentsOrGlob::join)
951+
.unwrap_or(IdentsOrGlob::Idents(vec![])),
952+
}
953+
}
954+
919955
fn item_ident(i: &Item) -> Option<&Ident> {
920956
use Item::*;
921957
Some(match i {
@@ -1038,6 +1074,23 @@ fn make_submodule(
10381074
}
10391075

10401076
for item in uses.into_items() {
1077+
// Consumers will `use` reexported items at their exported locations.
1078+
if let Item::Use(ItemUse {
1079+
vis: Visibility::Public(_),
1080+
tree,
1081+
..
1082+
}) = &*item
1083+
{
1084+
match use_idents(tree) {
1085+
IdentsOrGlob::Idents(idents) => {
1086+
for ident in idents {
1087+
// Add a `use` for `self::this_module::exported_name`.
1088+
use_item_store.add_use(false, use_path(), &ident.to_string());
1089+
}
1090+
}
1091+
IdentsOrGlob::Glob => {}
1092+
}
1093+
}
10411094
items.push(item);
10421095
}
10431096

0 commit comments

Comments
 (0)