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}