Skip to main content

charon_lib/ast/
meta.rs

1//! Meta information about programs (spans, etc.).
2use derive_generic_visitor::{Drive, DriveMut, DriveTwo};
3use macros::EnumIsA;
4use serde::{Deserialize, Serialize};
5use serde_state::{DeserializeState, SerializeState};
6
7use super::from_rustc::LangItem;
8
9pub mod attrs;
10pub mod names;
11pub mod spans;
12
13pub use attrs::*;
14pub use names::*;
15pub use spans::*;
16
17/// How much to translate for a given item.
18#[derive(
19    Debug,
20    Copy,
21    Clone,
22    PartialEq,
23    Eq,
24    PartialOrd,
25    Ord,
26    Serialize,
27    Deserialize,
28    Drive,
29    DriveMut,
30    DriveTwo,
31    EnumIsA,
32)]
33pub enum ItemOpacity {
34    /// Translate the item fully.
35    Transparent,
36    /// Translate the item depending on the normal rust visibility of its contents: for types, we
37    /// translate fully if it is a struct with public fields or an enum; for other items this is
38    /// equivalent to `Opaque`.
39    Foreign,
40    /// Translate the item name and signature, but not its contents. For function and globals, this
41    /// means we don't translate the body (the code); for ADTs, this means we don't translate the
42    /// fields/variants. For traits and trait impls, this doesn't change anything. For modules,
43    /// this means we don't explore its contents (we still translate any of its items mentioned
44    /// from somewhere else).
45    ///
46    /// This can happen either if the item was annotated with `#[charon::opaque]` or if it was
47    /// declared opaque via a command-line argument.
48    #[cfg_attr(feature = "charon_on_charon", charon::rename("ItemOpaque"))]
49    Opaque,
50    /// Translate nothing of this item. The corresponding map will not have an entry for the
51    /// `ItemId`. Useful when even the signature of the item causes errors.
52    Invisible,
53}
54
55/// Meta information about an item (function, trait decl, trait impl, type decl, global).
56#[derive(Debug, Clone, SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
57#[serde_state(stateless)]
58pub struct ItemMeta {
59    #[serde_state(stateful)]
60    pub name: Name,
61    pub span: Span,
62    /// The source code that corresponds to this item.
63    pub source_text: Option<String>,
64    /// Attributes and visibility.
65    pub attr_info: AttrInfo,
66    /// `true` if the type decl is a local type decl, `false` if it comes from an external crate.
67    pub is_local: bool,
68    /// Whether this item is considered opaque. For function and globals, this means we don't
69    /// translate the body (the code); for ADTs, this means we don't translate the fields/variants.
70    /// For traits and trait impls, this doesn't change anything. For modules, this means we don't
71    /// explore its contents (we still translate any of its items mentioned from somewhere else).
72    ///
73    /// This can happen either if the item was annotated with `#[charon::opaque]` or if it was
74    /// declared opaque via a command-line argument.
75    pub opacity: ItemOpacity,
76    /// If the item is a rustc lang item, record which one it is.
77    pub lang_item: Option<LangItem>,
78    /// If the item is a rustc diagnostic item, record its internal identifier.
79    pub diagnostic_item: Option<String>,
80}
81
82impl ItemOpacity {
83    pub fn with_content_visibility(self, contents_are_public: bool) -> Self {
84        use ItemOpacity::*;
85        match self {
86            Invisible => Invisible,
87            Transparent => Transparent,
88            Foreign if contents_are_public => Transparent,
89            Foreign => Opaque,
90            Opaque => Opaque,
91        }
92    }
93
94    pub fn with_private_contents(self) -> Self {
95        self.with_content_visibility(false)
96    }
97}
98
99impl ItemMeta {
100    pub fn renamed_name(&self) -> Name {
101        let mut name = self.name.clone();
102        if let Some(rename) = self.attr_info.rename.clone() {
103            *name.name.last_mut().unwrap() = PathElem::Ident(rename, Disambiguator::new(0));
104        }
105        name
106    }
107
108    pub fn dummy_public(span: Span, name: Name, is_local: bool, opacity: ItemOpacity) -> Self {
109        ItemMeta {
110            name,
111            span,
112            source_text: None,
113            attr_info: AttrInfo::dummy_public(),
114            is_local,
115            opacity,
116            lang_item: None,
117            diagnostic_item: None,
118        }
119    }
120}