charon_lib/transform/
utils.rs

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