charon_lib/transform/
compute_short_names.rs1use std::collections::{HashMap, hash_map::Entry};
2
3use crate::ast::*;
4
5use super::{TransformCtx, ctx::TransformPass};
6
7enum FoundName<'a> {
8 Unique {
9 long: &'a [PathElem],
10 ids: Vec<AnyTransId>,
11 },
12 Multiple,
13}
14
15pub struct Transform;
16impl TransformPass for Transform {
17 fn transform_ctx(&self, ctx: &mut TransformCtx) {
18 let mut short_names: HashMap<&str, FoundName> = Default::default();
19 for (&id, name) in &ctx.translated.item_names {
20 let mut name_slice = name.name.as_slice();
21
22 if let Some((i, _)) = name_slice
25 .iter()
26 .enumerate()
27 .rfind(|(_, elem)| matches!(elem, PathElem::Impl(ImplElem::Trait(..), ..)))
28 {
29 name_slice = &name.name[i..];
30 let trunc_name = Name {
31 name: name_slice.to_vec(),
32 };
33 ctx.translated.short_names.insert(id, trunc_name);
34 }
35
36 if let [prefix @ .., PathElem::Monomorphized(..)] = name_slice {
37 name_slice = prefix;
38 }
39 match name_slice {
43 [.., PathElem::Ident(ident, _)] => match short_names.entry(ident) {
44 Entry::Occupied(mut e) => match e.get_mut() {
45 FoundName::Unique { long, ids } => {
46 if *long == name_slice {
47 ids.push(id)
48 } else {
49 e.insert(FoundName::Multiple);
50 }
51 }
52 FoundName::Multiple => {}
53 },
54 Entry::Vacant(e) => {
55 e.insert(FoundName::Unique {
56 long: name_slice,
57 ids: vec![id],
58 });
59 }
60 },
61 _ => {}
62 }
63 }
64
65 for (short, found) in short_names {
66 if let FoundName::Unique { ids, .. } = found {
67 for id in ids {
68 let mut short_name = Name {
69 name: vec![PathElem::Ident(short.to_owned(), Disambiguator::ZERO)],
70 };
71 if let [.., mono @ PathElem::Monomorphized(..)] =
72 ctx.translated.item_names[&id].name.as_slice()
73 {
74 short_name.name.push(mono.clone());
75 }
76 ctx.translated.short_names.insert(id, short_name);
77 }
78 }
79 }
80 }
81}