abi_stable/type_layout/
tl_other.rs

1use super::*;
2
3use crate::{abi_stability::ConstGeneric, sabi_types::Constructor};
4
5/////////////////////////////////////////////////////
6
7/// The `repr(..)` attribute used on a type.
8#[repr(u8)]
9#[derive(Debug, Copy, Clone, PartialEq, Eq, StableAbi)]
10#[sabi(unsafe_sabi_opaque_fields)]
11pub enum ReprAttr {
12    /// This is an `Option<NonZeroType>`.
13    /// In which the size and alignment of the `Option<_>` is exactly that of its contents.
14    ///
15    /// When translated to C,it is equivalent to the type parameter.
16    OptionNonZero,
17    /// This is an ffi-safe primitive type,declared in the compiler.
18    Primitive,
19    /// A struct whose fields are laid out like C,
20    C,
21    /// An enum with a `#[repr(C, IntegerType)]` attribute.
22    CAndInt(DiscriminantRepr),
23    /// A type with the same size,alignment and function ABI as
24    /// its only non-zero-sized field.
25    Transparent,
26    /// Means that only `repr(IntegerType)` was used.
27    Int(DiscriminantRepr),
28    // Added just in case that I add support for it
29    #[doc(hidden)]
30    Packed {
31        /// The alignment represented as a `1 << alignment_power_of_two`.
32        alignment_power_of_two: u8,
33    },
34}
35
36/////////////////////////////////////////////////////
37
38/// A module path.
39#[repr(transparent)]
40#[derive(Debug, Copy, Clone, Eq, PartialEq, StableAbi)]
41#[sabi(unsafe_sabi_opaque_fields)]
42pub struct ModPath(NulStr<'static>);
43
44impl ModPath {
45    /// An item without a path
46    pub const NO_PATH: Self = ModPath(nulstr_trunc!("<no path>"));
47
48    /// An item in the prelude.
49    pub const PRELUDE: Self = ModPath(nulstr_trunc!("<prelude>"));
50
51    /// Constructs a ModPath from a string with a module path.
52    pub const fn inside(path: NulStr<'static>) -> Self {
53        ModPath(path)
54    }
55}
56
57impl Display for ModPath {
58    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59        Display::fmt(&self.0, f)
60    }
61}
62
63/////////////////////////////////////////////////////
64
65/// The compressed generic parameters of a type,
66/// which can be expanded into a `GenericParams` by calling `expand`.
67#[repr(C)]
68#[derive(Debug, Copy, Clone, PartialEq, Eq, StableAbi)]
69#[sabi(unsafe_sabi_opaque_fields)]
70pub struct CompGenericParams {
71    /// The names of the lifetimes declared by a type.
72    lifetime: NulStr<'static>,
73    /// The type parameters of a type,getting them from the containing TypeLayout.
74    types: StartLen,
75    /// The const parameters of a type,getting them from the containing TypeLayout.
76    consts: StartLen,
77    lifetime_count: u8,
78}
79
80impl CompGenericParams {
81    /// Constructs a CompGenericParams.
82    pub const fn new(
83        lifetime: NulStr<'static>,
84        lifetime_count: u8,
85        types: StartLen,
86        consts: StartLen,
87    ) -> Self {
88        Self {
89            lifetime,
90            lifetime_count,
91            types,
92            consts,
93        }
94    }
95
96    /// Expands this `CompGenericParams` into a `GenericParams`.
97    pub fn expand(self, shared_vars: &'static SharedVars) -> GenericParams {
98        GenericParams {
99            lifetime: self.lifetime,
100            types: Constructor::wrap_slice(&shared_vars.type_layouts()[self.types.to_range()]),
101            consts: &shared_vars.constants()[self.consts.to_range()],
102            lifetime_count: self.lifetime_count,
103        }
104    }
105}
106
107/// The generic parameters of a type.
108#[derive(Copy, Clone, PartialEq, Eq)]
109pub struct GenericParams {
110    /// The names of the lifetimes declared by a type.
111    pub(super) lifetime: NulStr<'static>,
112    /// The type parameters of a type,getting them from the containing TypeLayout.
113    pub(super) types: &'static [Constructor<&'static TypeLayout>],
114    /// The const parameters of a type,getting them from the containing TypeLayout.
115    pub(super) consts: &'static [ConstGeneric],
116    pub(super) lifetime_count: u8,
117}
118
119impl GenericParams {
120    /// Whether this contains any generic parameters
121    pub fn is_empty(&self) -> bool {
122        self.lifetime.to_str().is_empty() && self.types.is_empty() && self.consts.is_empty()
123    }
124
125    /// Gets an iterator over the names of the lifetime parameters of the type.
126    pub fn lifetimes(&self) -> impl Iterator<Item = &'static str> + Clone + Send + Sync + 'static {
127        self.lifetime.to_str().split(',').filter(|x| !x.is_empty())
128    }
129    /// The amount of lifetimes of the type.
130    pub const fn lifetime_count(&self) -> usize {
131        self.lifetime_count as usize
132    }
133    /// The type parameters of the type.
134    pub fn type_params(&self) -> &'static [extern "C" fn() -> &'static TypeLayout] {
135        Constructor::unwrap_slice(self.types)
136    }
137    /// The const parameters of the type.
138    pub const fn const_params(&self) -> &'static [ConstGeneric] {
139        self.consts
140    }
141}
142
143impl Display for GenericParams {
144    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145        fmt::Display::fmt("<", f)?;
146
147        let post_iter = |i: usize, len: usize, f: &mut Formatter<'_>| -> fmt::Result {
148            if i + 1 < len {
149                fmt::Display::fmt(", ", f)?;
150            }
151            Ok(())
152        };
153
154        for (i, param) in self.lifetimes().enumerate() {
155            fmt::Display::fmt(param, &mut *f)?;
156            post_iter(i, self.lifetime_count(), &mut *f)?;
157        }
158        for (i, param) in self.types.iter().cloned().enumerate() {
159            fmt::Debug::fmt(&param.get().full_type(), &mut *f)?;
160            post_iter(i, self.types.len(), &mut *f)?;
161        }
162        for (i, param) in self.consts.iter().enumerate() {
163            fmt::Debug::fmt(param, &mut *f)?;
164            post_iter(i, self.consts.len(), &mut *f)?;
165        }
166        fmt::Display::fmt(">", f)?;
167        Ok(())
168    }
169}
170
171///////////////////////////////////////////////////////////////////////////////
172
173/// Types defined in the compiler
174#[repr(u8)]
175#[derive(Debug, Copy, Clone, PartialEq, Eq, StableAbi)]
176#[sabi(unsafe_sabi_opaque_fields)]
177pub enum TLPrimitive {
178    ///
179    U8,
180    ///
181    I8,
182    ///
183    U16,
184    ///
185    I16,
186    ///
187    U32,
188    ///
189    I32,
190    ///
191    U64,
192    ///
193    I64,
194    ///
195    Usize,
196    ///
197    Isize,
198    ///
199    F32,
200    ///
201    F64,
202    ///
203    Bool,
204    /// A `&T`
205    SharedRef,
206    /// A `&mut T`
207    MutRef,
208    /// A `*const T`
209    ConstPtr,
210    /// A `*mut T`
211    MutPtr,
212    /// An array.
213    Array,
214}
215
216///////////////////////////
217
218/// The typename and generics of the type this layout is associated to,
219/// used for printing types (eg: `RVec<u8>` ).
220#[derive(Copy, Clone, PartialEq, Eq)]
221pub struct FmtFullType {
222    pub(super) name: &'static str,
223    pub(super) generics: GenericParams,
224    pub(super) primitive: Option<TLPrimitive>,
225    pub(super) utypeid: UTypeId,
226}
227
228impl FmtFullType {
229    /// The name of a type.
230    pub const fn name(&self) -> &'static str {
231        self.name
232    }
233    /// The generic parmaters of a type.
234    pub const fn generics(&self) -> GenericParams {
235        self.generics
236    }
237}
238
239////////////////////////////////////
240
241/// Either a TLField or a TLFunction.
242#[repr(u8)]
243#[derive(Copy, Clone, Debug, Eq, PartialEq, StableAbi)]
244#[sabi(unsafe_sabi_opaque_fields)]
245pub enum TLFieldOrFunction {
246    ///
247    Field(TLField),
248    ///
249    Function(TLFunction),
250}
251
252impl From<TLField> for TLFieldOrFunction {
253    fn from(x: TLField) -> Self {
254        TLFieldOrFunction::Field(x)
255    }
256}
257
258impl From<TLFunction> for TLFieldOrFunction {
259    fn from(x: TLFunction) -> Self {
260        TLFieldOrFunction::Function(x)
261    }
262}
263
264impl Display for TLFieldOrFunction {
265    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
266        match self {
267            TLFieldOrFunction::Field(x) => Display::fmt(x, f),
268            TLFieldOrFunction::Function(x) => Display::fmt(x, f),
269        }
270    }
271}
272
273impl TLFieldOrFunction {
274    /// Outputs this into a String with `Display` formatting.
275    pub fn formatted_layout(&self) -> String {
276        match self {
277            TLFieldOrFunction::Field(x) => x.layout().to_string(),
278            TLFieldOrFunction::Function(x) => x.to_string(),
279        }
280    }
281}
282
283//////////////////////////////////////////////////////////////////////////////