charon_lib/ast/
meta.rs

1//! Meta-information about programs (spans, etc.).
2
3pub use super::meta_utils::*;
4use crate::names::Name;
5use derive_generic_visitor::{Drive, DriveMut};
6use macros::{EnumAsGetters, EnumIsA, EnumToGetters};
7use serde::{Deserialize, Serialize};
8use std::path::PathBuf;
9
10generate_index_type!(FileId);
11
12#[derive(
13    Debug,
14    Copy,
15    Clone,
16    PartialEq,
17    Eq,
18    PartialOrd,
19    Ord,
20    Hash,
21    Serialize,
22    Deserialize,
23    Drive,
24    DriveMut,
25)]
26pub struct Loc {
27    /// The (1-based) line number.
28    pub line: usize,
29    /// The (0-based) column offset.
30    pub col: usize,
31}
32
33/// Span information
34#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Drive, DriveMut)]
35pub struct RawSpan {
36    #[charon::rename("file")]
37    pub file_id: FileId,
38    #[charon::rename("beg_loc")]
39    pub beg: Loc,
40    #[charon::rename("end_loc")]
41    pub end: Loc,
42}
43
44/// Meta information about a piece of code (block, statement, etc.)
45#[derive(
46    Debug,
47    Copy,
48    Clone,
49    PartialEq,
50    Eq,
51    PartialOrd,
52    Ord,
53    Hash,
54    Serialize,
55    Deserialize,
56    Drive,
57    DriveMut,
58)]
59#[drive(skip)]
60pub struct Span {
61    /// The source code span.
62    ///
63    /// If this meta information is for a statement/terminator coming from a macro
64    /// expansion/inlining/etc., this span is (in case of macros) for the macro
65    /// before expansion (i.e., the location the code where the user wrote the call
66    /// to the macro).
67    ///
68    /// Ex:
69    /// ```text
70    /// // Below, we consider the spans for the statements inside `test`
71    ///
72    /// //   the statement we consider, which gets inlined in `test`
73    ///                          VV
74    /// macro_rules! macro { ... st ... } // `generated_from_span` refers to this location
75    ///
76    /// fn test() {
77    ///     macro!(); // <-- `span` refers to this location
78    /// }
79    /// ```
80    pub span: RawSpan,
81    /// Where the code actually comes from, in case of macro expansion/inlining/etc.
82    pub generated_from_span: Option<RawSpan>,
83}
84
85/// `#[inline]` built-in attribute.
86#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Drive, DriveMut)]
87pub enum InlineAttr {
88    /// `#[inline]`
89    Hint,
90    /// `#[inline(never)]`
91    Never,
92    /// `#[inline(always)]`
93    Always,
94}
95
96/// Attributes (`#[...]`).
97#[derive(
98    Debug,
99    Clone,
100    PartialEq,
101    Eq,
102    EnumIsA,
103    EnumAsGetters,
104    EnumToGetters,
105    Serialize,
106    Deserialize,
107    Drive,
108    DriveMut,
109)]
110#[charon::variants_prefix("Attr")]
111pub enum Attribute {
112    /// Do not translate the body of this item.
113    /// Written `#[charon::opaque]`
114    Opaque,
115    /// Provide a new name that consumers of the llbc can use.
116    /// Written `#[charon::rename("new_name")]`
117    Rename(String),
118    /// For enums only: rename the variants by pre-pending their names with the given prefix.
119    /// Written `#[charon::variants_prefix("prefix_")]`.
120    VariantsPrefix(String),
121    /// Same as `VariantsPrefix`, but appends to the name instead of pre-pending.
122    VariantsSuffix(String),
123    /// A doc-comment such as `/// ...`.
124    DocComment(String),
125    /// A non-charon-specific attribute.
126    Unknown(RawAttribute),
127}
128
129/// A general attribute.
130#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Drive, DriveMut)]
131pub struct RawAttribute {
132    pub path: String,
133    /// The arguments passed to the attribute, if any. We don't distinguish different delimiters or
134    /// the `path = lit` case.
135    pub args: Option<String>,
136}
137
138/// Information about the attributes and visibility of an item, field or variant..
139#[derive(Debug, Clone, Serialize, Deserialize, Drive, DriveMut)]
140pub struct AttrInfo {
141    /// Attributes (`#[...]`).
142    pub attributes: Vec<Attribute>,
143    /// Inline hints (on functions only).
144    pub inline: Option<InlineAttr>,
145    /// The name computed from `charon::rename` and `charon::variants_prefix` attributes, if any.
146    /// This provides a custom name that can be used by consumers of llbc. E.g. Aeneas uses this to
147    /// rename definitions in the extracted code.
148    pub rename: Option<String>,
149    /// Whether this item is declared public. Impl blocks and closures don't have visibility
150    /// modifiers; we arbitrarily set this to `false` for them.
151    ///
152    /// Note that this is different from being part of the crate's public API: to be part of the
153    /// public API, an item has to also be reachable from public items in the crate root. For
154    /// example:
155    /// ```rust,ignore
156    /// mod foo {
157    ///     pub struct X;
158    /// }
159    /// mod bar {
160    ///     pub fn something(_x: super::foo::X) {}
161    /// }
162    /// pub use bar::something; // exposes `X`
163    /// ```
164    /// Without the `pub use ...`, neither `X` nor `something` would be part of the crate's public
165    /// API (this is called "pub-in-priv" items). With or without the `pub use`, we set `public =
166    /// true`; computing item reachability is harder.
167    pub public: bool,
168}
169
170#[derive(
171    Debug,
172    Copy,
173    Clone,
174    PartialEq,
175    Eq,
176    PartialOrd,
177    Ord,
178    Serialize,
179    Deserialize,
180    Drive,
181    DriveMut,
182    EnumIsA,
183)]
184pub enum ItemOpacity {
185    /// Translate the item fully.
186    Transparent,
187    /// Translate the item depending on the normal rust visibility of its contents: for types, we
188    /// translate fully if it is a struct with public fields or an enum; for other items this is
189    /// equivalent to `Opaque`.
190    Foreign,
191    /// Translate the item name and signature, but not its contents. For function and globals, this
192    /// means we don't translate the body (the code); for ADTs, this means we don't translate the
193    /// fields/variants. For traits and trait impls, this doesn't change anything. For modules,
194    /// this means we don't explore its contents (we still translate any of its items mentioned
195    /// from somewhere else).
196    ///
197    /// This can happen either if the item was annotated with `#[charon::opaque]` or if it was
198    /// declared opaque via a command-line argument.
199    Opaque,
200    /// Translate nothing of this item. The corresponding map will not have an entry for the
201    /// `AnyTransId`. Useful when even the signature of the item causes errors.
202    Invisible,
203}
204
205/// Meta information about an item (function, trait decl, trait impl, type decl, global).
206#[derive(Debug, Clone, Serialize, Deserialize, Drive, DriveMut)]
207pub struct ItemMeta {
208    pub name: Name,
209    pub span: Span,
210    /// The source code that corresponds to this item.
211    #[drive(skip)]
212    pub source_text: Option<String>,
213    /// Attributes and visibility.
214    #[drive(skip)]
215    pub attr_info: AttrInfo,
216    /// `true` if the type decl is a local type decl, `false` if it comes from an external crate.
217    #[drive(skip)]
218    pub is_local: bool,
219    /// Whether this item is considered opaque. For function and globals, this means we don't
220    /// translate the body (the code); for ADTs, this means we don't translate the fields/variants.
221    /// For traits and trait impls, this doesn't change anything. For modules, this means we don't
222    /// explore its contents (we still translate any of its items mentioned from somewhere else).
223    ///
224    /// This can happen either if the item was annotated with `#[charon::opaque]` or if it was
225    /// declared opaque via a command-line argument.
226    #[charon::opaque]
227    #[drive(skip)]
228    pub opacity: ItemOpacity,
229    /// If the item is built-in, record its internal builtin identifier.
230    #[drive(skip)]
231    pub lang_item: Option<String>,
232}
233
234/// A filename.
235#[derive(
236    Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord, Serialize, Deserialize, Drive, DriveMut,
237)]
238pub enum FileName {
239    /// A remapped path (namely paths into stdlib)
240    #[drive(skip)] // drive is not implemented for `PathBuf`
241    Virtual(PathBuf),
242    /// A local path (a file coming from the current crate for instance)
243    #[drive(skip)] // drive is not implemented for `PathBuf`
244    Local(PathBuf),
245    /// A "not real" file name (macro, query, etc.)
246    #[charon::opaque]
247    NotReal(String),
248}
249
250#[derive(
251    Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord, Serialize, Deserialize, Drive, DriveMut,
252)]
253pub struct File {
254    /// The path to the file.
255    pub name: FileName,
256    /// The contents of the source file, as seen by rustc at the time of translation.
257    /// Some files don't have contents.
258    pub contents: Option<String>,
259}