Skip to main content

charon_lib/transform/
utils.rs

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