charon_lib/transform/
utils.rs

1use crate::ast::*;
2use crate::formatter::FmtCtx;
3use crate::pretty::FmtWithCtx;
4use derive_generic_visitor::*;
5use macros::EnumIsA;
6use std::fmt::Debug;
7
8/// Each `GenericArgs` is meant for a corresponding `GenericParams`; this describes which one.
9#[derive(Debug, Clone, Eq, PartialEq, Hash, EnumIsA, Drive, DriveMut)]
10pub enum GenericsSource {
11    /// A top-level item.
12    Item(ItemId),
13    /// A trait method.
14    Method(TraitDeclId, TraitItemName),
15    /// A builtin item like `Box`.
16    Builtin,
17    /// Some other use of generics outside the main Charon ast.
18    Other,
19}
20
21impl GenericsSource {
22    pub fn item<I: Into<ItemId>>(id: I) -> Self {
23        Self::Item(id.into())
24    }
25
26    /// Return a path that represents the target item.
27    pub fn item_name(&self, translated: &TranslatedCrate, fmt_ctx: &FmtCtx) -> String {
28        match self {
29            GenericsSource::Item(id) => translated
30                .item_name(*id)
31                .unwrap()
32                .to_string_with_ctx(fmt_ctx),
33            GenericsSource::Method(trait_id, method_name) => format!(
34                "{}::{method_name}",
35                translated
36                    .item_name(*trait_id)
37                    .unwrap()
38                    .to_string_with_ctx(fmt_ctx),
39            ),
40            GenericsSource::Builtin => format!("<built-in>"),
41            GenericsSource::Other => format!("<unknown>"),
42        }
43    }
44}
45
46impl TypeId {
47    pub fn generics_target(&self) -> GenericsSource {
48        match *self {
49            TypeId::Adt(decl_id) => GenericsSource::item(decl_id),
50            TypeId::Tuple | TypeId::Builtin(..) => GenericsSource::Builtin,
51        }
52    }
53}
54impl FunId {
55    pub fn generics_target(&self) -> GenericsSource {
56        match *self {
57            FunId::Regular(fun_id) => GenericsSource::item(fun_id),
58            FunId::Builtin(..) => GenericsSource::Builtin,
59        }
60    }
61}
62impl FnPtrKind {
63    pub fn generics_target(&self) -> GenericsSource {
64        match self {
65            FnPtrKind::Fun(fun_id) => fun_id.generics_target(),
66            FnPtrKind::Trait(trait_ref, name, _) => {
67                GenericsSource::Method(trait_ref.trait_decl_ref.skip_binder.id, name.clone())
68            }
69        }
70    }
71}