Skip to content

Commit 0f281b4

Browse files
committed
reorganize_definitions: Shorten paths that are imported into the current module
1 parent 2a81bcc commit 0f281b4

File tree

1 file changed

+59
-3
lines changed

1 file changed

+59
-3
lines changed

c2rust-refactor/src/transform/reorganize_definitions.rs

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ impl<'a, 'tcx> Reorganizer<'a, 'tcx> {
880880
});
881881

882882
// Mapping from ident to the module we are importing that ident from
883-
let mut uses: PerNS<HashMap<Ident, NodeId>> = PerNS::default();
883+
let mut uses: PerNS<HashMap<Ident, (NodeId, NodeId, DefId)>> = PerNS::default();
884884
mod_items.retain(|item| {
885885
if let ItemKind::Use(u) = &item.kind {
886886
match u.kind {
@@ -913,7 +913,7 @@ impl<'a, 'tcx> Reorganizer<'a, 'tcx> {
913913
{
914914
if let Some(Replacement {parent, ..}) = self.path_mapping.get(&def_id) {
915915
for ns in &[Namespace::ValueNS, Namespace::TypeNS] {
916-
if let Some(target_mod) = uses[*ns].get(&u.ident()) {
916+
if let Some((target_mod, _, _)) = uses[*ns].get(&u.ident()) {
917917
if target_mod == parent {
918918
return false;
919919
} else if *ns == namespace {
@@ -946,13 +946,69 @@ impl<'a, 'tcx> Reorganizer<'a, 'tcx> {
946946
DUMMY_NODE_ID
947947
}
948948
};
949-
uses[namespace].insert(u.ident(), mod_id);
949+
uses[namespace].insert(u.ident(), (mod_id, item.id, def_id));
950950
}
951951
}
952952
}
953953
}
954954
true
955955
});
956+
957+
// If any items are imported into the current module,
958+
// use the short paths, e.g., bar instead of crate::foo::bar
959+
//
960+
// TODO: this could be a separate transform
961+
fold_resolved_paths_with_id(&mut item, self.cx, |id, qself, mut path, defs| {
962+
debug!("Shortening {:?} (def: {:?})", path, defs);
963+
for def in defs {
964+
if let (Some(path_def_id), Some(ns)) = (def.opt_def_id(), def.ns()) {
965+
let item_hir_id = self.cx.hir_map().node_to_hir_id(id);
966+
let item_mod_ldid = self.cx.ty_ctxt().parent_module(item_hir_id);
967+
let item_mod_id = self.cx.hir_map().local_def_id_to_node_id(item_mod_ldid);
968+
969+
// Check if the current path is defined in the same module
970+
// First check our remapped paths to see if we moved
971+
// the definition to another module; otherwise,
972+
// check the original definition.
973+
let path_def_mod_id = remapped_paths
974+
.get(&id)
975+
.map(|(mod_def_id, _)| *mod_def_id)
976+
.or_else(|| path_def_id.as_local().map(|ldid| {
977+
let parent = self.cx.ty_ctxt().parent_module_from_def_id(ldid);
978+
self.cx.hir_map().local_def_id_to_node_id(parent)
979+
}));
980+
if Some(item_mod_id) == path_def_mod_id {
981+
// Current path matches one of the definitions
982+
// in the current module, shorten it
983+
path.segments.drain(0..path.segments.len() - 1);
984+
break;
985+
}
986+
987+
let last_seg = path.segments.last().expect("empty path");
988+
let (_, use_id, seg_def_id) = match uses[ns].get(&last_seg.ident) {
989+
Some(x) => x,
990+
None => continue
991+
};
992+
if id == *use_id {
993+
continue;
994+
}
995+
if path_def_id != *seg_def_id {
996+
continue;
997+
}
998+
999+
// For now, only shorten paths to uses within the same module
1000+
let use_hir_id = self.cx.hir_map().node_to_hir_id(*use_id);
1001+
let use_mod_ldid = self.cx.ty_ctxt().parent_module(use_hir_id);
1002+
if item_mod_ldid == use_mod_ldid {
1003+
// Current path matches one of the uses
1004+
// in the current module, shorten it
1005+
path.segments.drain(0..path.segments.len() - 1);
1006+
break;
1007+
}
1008+
}
1009+
}
1010+
(qself, path)
1011+
});
9561012
}
9571013
smallvec![item]
9581014
});

0 commit comments

Comments
 (0)