charon_lib/transform/
compute_short_names.rs

1use std::collections::{hash_map::Entry, HashMap};
2
3use crate::ast::*;
4
5use super::{ctx::TransformPass, TransformCtx};
6
7enum FoundName {
8    Unique(AnyTransId),
9    Multiple,
10}
11
12pub struct Transform;
13impl TransformPass for Transform {
14    fn transform_ctx(&self, ctx: &mut TransformCtx) {
15        let mut short_names: HashMap<String, FoundName> = Default::default();
16        for (&id, mut name) in &ctx.translated.item_names {
17            // Trait impls are sufficiently unique information, so truncate starting from the
18            // rightmost impl.
19            let trunc_name;
20            if let Some((i, _)) = name
21                .name
22                .as_slice()
23                .iter()
24                .enumerate()
25                .rfind(|(_, elem)| matches!(elem, PathElem::Impl(ImplElem::Trait(..), ..)))
26            {
27                trunc_name = Name {
28                    name: name.name[i..].to_vec(),
29                };
30                ctx.translated.short_names.insert(id, trunc_name.clone());
31                name = &trunc_name;
32            }
33            match name.name.as_slice() {
34                [.., PathElem::Ident(ident, _)] => match short_names.entry(ident.clone()) {
35                    Entry::Occupied(mut e) => {
36                        e.insert(FoundName::Multiple);
37                    }
38                    Entry::Vacant(e) => {
39                        e.insert(FoundName::Unique(id));
40                    }
41                },
42                _ => {}
43            }
44        }
45
46        for (short, found) in short_names {
47            if let FoundName::Unique(id) = found {
48                ctx.translated.short_names.insert(
49                    id,
50                    Name {
51                        name: vec![PathElem::Ident(short, Disambiguator::ZERO)],
52                    },
53                );
54            }
55        }
56    }
57}