rune/compile/
context_error.rs

1use core::fmt;
2
3use crate::alloc;
4use crate::alloc::prelude::*;
5use crate::compile::meta::AssociatedKind;
6use crate::runtime::{RuntimeError, TypeInfo};
7use crate::{Hash, ItemBuf};
8
9/// An error raised when building the context.
10#[derive(Debug)]
11#[allow(missing_docs)]
12#[non_exhaustive]
13pub enum ContextError {
14    AllocError {
15        error: alloc::Error,
16    },
17    InvalidConstValue {
18        item: ItemBuf,
19        error: Box<RuntimeError>,
20    },
21    InvalidAssociatedConstValue {
22        container: TypeInfo,
23        kind: Box<AssociatedKind>,
24        error: Box<RuntimeError>,
25    },
26    UnitAlreadyPresent,
27    InternalAlreadyPresent {
28        name: &'static str,
29    },
30    ConflictingFunction {
31        part: Box<str>,
32        hash: Hash,
33    },
34    ConflictingFunctionName {
35        item: ItemBuf,
36        hash: Hash,
37    },
38    ConflictingMacroName {
39        item: ItemBuf,
40        hash: Hash,
41    },
42    ConflictingConstantName {
43        item: ItemBuf,
44        hash: Hash,
45    },
46    ConflictingInstanceFunction {
47        type_info: TypeInfo,
48        name: Box<str>,
49    },
50    ConflictingProtocolFunction {
51        type_info: TypeInfo,
52        name: Box<str>,
53    },
54    ConflictingFieldFunction {
55        type_info: TypeInfo,
56        name: Box<str>,
57        field: Box<str>,
58    },
59    ConflictingIndexFunction {
60        type_info: TypeInfo,
61        name: Box<str>,
62        index: usize,
63    },
64    ConflictingModule {
65        item: ItemBuf,
66        hash: Hash,
67    },
68    ConflictingType {
69        item: ItemBuf,
70        type_info: TypeInfo,
71        hash: Hash,
72    },
73    ConflictingReexport {
74        item: ItemBuf,
75        hash: Hash,
76        to: ItemBuf,
77    },
78    ConflictingTrait {
79        item: ItemBuf,
80        hash: Hash,
81    },
82    ConflictingTraitImpl {
83        trait_item: ItemBuf,
84        trait_hash: Hash,
85        item: ItemBuf,
86        hash: Hash,
87    },
88    MissingTraitFunction {
89        name: String,
90        item: ItemBuf,
91        hash: Hash,
92        trait_item: ItemBuf,
93        trait_hash: Hash,
94    },
95    MissingTrait {
96        item: ItemBuf,
97        hash: Hash,
98        impl_item: ItemBuf,
99        impl_hash: Hash,
100    },
101    ConflictingTypeMeta {
102        item: ItemBuf,
103        type_info: TypeInfo,
104    },
105    ConflictingVariantMeta {
106        type_info: TypeInfo,
107        name: &'static str,
108    },
109    ConflictingMetaHash {
110        item: ItemBuf,
111        hash: Hash,
112        existing: Hash,
113    },
114    ConflictingTypeHash {
115        hash: Hash,
116        existing: Hash,
117    },
118    ConflictingVariant {
119        item: ItemBuf,
120    },
121    ConstructorConflict {
122        type_info: TypeInfo,
123    },
124    VariantConstructorConflict {
125        type_info: TypeInfo,
126        name: &'static str,
127    },
128    ConstructorArgumentsMismatch {
129        type_info: TypeInfo,
130        expected: usize,
131        actual: usize,
132    },
133    VariantConstructorArgumentsMismatch {
134        type_info: TypeInfo,
135        name: &'static str,
136        expected: usize,
137        actual: usize,
138    },
139    ConflictingConstConstruct {
140        type_info: TypeInfo,
141        hash: Hash,
142    },
143    MissingType {
144        item: ItemBuf,
145        type_info: TypeInfo,
146    },
147    MissingEnum {
148        item: ItemBuf,
149        type_info: TypeInfo,
150    },
151    MissingContainer {
152        container: TypeInfo,
153    },
154    MissingVariant {
155        index: usize,
156        type_info: TypeInfo,
157    },
158    ExpectedAssociated,
159    TypeHashMismatch {
160        type_info: TypeInfo,
161        item: ItemBuf,
162        hash: Hash,
163        item_hash: Hash,
164    },
165    StaticTypeHashMismatch {
166        type_info: TypeInfo,
167        item: ItemBuf,
168        hash: Hash,
169        item_hash: Hash,
170    },
171}
172
173impl From<alloc::Error> for ContextError {
174    #[inline]
175    fn from(error: alloc::Error) -> Self {
176        ContextError::AllocError { error }
177    }
178}
179
180impl From<alloc::alloc::AllocError> for ContextError {
181    #[inline]
182    fn from(error: alloc::alloc::AllocError) -> Self {
183        ContextError::AllocError {
184            error: error.into(),
185        }
186    }
187}
188
189impl fmt::Display for ContextError {
190    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
191        match self {
192            ContextError::AllocError { error } => {
193                error.fmt(f)?;
194            }
195            ContextError::InvalidConstValue { item, error } => {
196                write!(f, "Error when building constant {item}: {error}")?;
197            }
198            ContextError::InvalidAssociatedConstValue {
199                container,
200                kind,
201                error,
202            } => {
203                write!(
204                    f,
205                    "Error when building associated constant in {container}::{kind}: {error}"
206                )?;
207            }
208            ContextError::UnitAlreadyPresent => {
209                write!(f, "Unit `()` type is already present")?;
210            }
211            ContextError::InternalAlreadyPresent { name } => {
212                write!(f, "Type for name `{name}` is already present")?;
213            }
214            ContextError::ConflictingFunction { part, hash } => {
215                write!(
216                    f,
217                    "Function with hash `{hash}` part of `{part}` already exists"
218                )?;
219            }
220            ContextError::ConflictingFunctionName { item, hash } => {
221                write!(f, "Function `{item}` already exists with hash `{hash}`")?;
222            }
223            ContextError::ConflictingMacroName { item, hash } => {
224                write!(f, "Macro `{item}` already exists with hash `{hash}`")?;
225            }
226            ContextError::ConflictingConstantName { item, hash } => {
227                write!(f, "Constant `{item}` already exists with hash `{hash}`")?;
228            }
229            ContextError::ConflictingInstanceFunction { type_info, name } => {
230                write!(
231                    f,
232                    "Instance function `{name}` for type `{type_info}` already exists"
233                )?;
234            }
235            ContextError::ConflictingProtocolFunction { type_info, name } => {
236                write!(
237                    f,
238                    "Protocol function `{name}` for type `{type_info}` already exists"
239                )?;
240            }
241            ContextError::ConflictingFieldFunction {
242                type_info,
243                name,
244                field,
245            } => {
246                write!(f,"Field function `{name}` for field `{field}` and type `{type_info}` already exists")?;
247            }
248            ContextError::ConflictingIndexFunction {
249                type_info,
250                name,
251                index,
252            } => {
253                write!(f,"Index function `{name}` for index `{index}` and type `{type_info}` already exists")?;
254            }
255            ContextError::ConflictingModule { item, hash } => {
256                write!(f, "Module `{item}` with hash `{hash}` already exists")?;
257            }
258            ContextError::ConflictingType {
259                item,
260                type_info,
261                hash,
262            } => {
263                write!(
264                    f,
265                    "Type `{item}` already exists `{type_info}` with hash `{hash}`"
266                )?;
267            }
268            ContextError::ConflictingReexport { item, hash, to } => {
269                write!(
270                    f,
271                    "Reexport at `{item}` with hash `{hash}` to `{to}` already exists"
272                )?;
273            }
274            ContextError::ConflictingTrait { item, hash } => {
275                write!(
276                    f,
277                    "Trait `{item}` with hash `{hash}` conflicts with other item in module"
278                )?;
279            }
280            ContextError::ConflictingTraitImpl {
281                trait_item,
282                trait_hash,
283                item,
284                hash,
285            } => {
286                write!(
287                    f,
288                    "Trait `{trait_item}` with hash `{trait_hash}` is implemented multiple types for type `{item}` with hash `{hash}`"
289                )?;
290            }
291            ContextError::MissingTraitFunction {
292                name,
293                item,
294                hash,
295                trait_item,
296                trait_hash,
297            } => {
298                write!(
299                    f,
300                    "Missing required associated `{name}` for type `{item}` with hash `{hash}` when implementing trait `{trait_item}` with hash `{trait_hash}`"
301                )?;
302            }
303            ContextError::MissingTrait {
304                item,
305                hash,
306                impl_item,
307                impl_hash,
308            } => {
309                write!(
310                    f,
311                    "Missing trait `{item}` with hash `{hash}` when implementing it for `{impl_item}` with hash `{impl_hash}`"
312                )?;
313            }
314            ContextError::ConflictingTypeMeta { item, type_info } => {
315                write!(
316                    f,
317                    "Type `{item}` at `{type_info}` already has a specification"
318                )?;
319            }
320            ContextError::ConflictingVariantMeta { type_info, name } => {
321                write!(
322                    f,
323                    "Variant `{name}` for `{type_info}` already has a specification"
324                )?;
325            }
326            ContextError::ConflictingMetaHash {
327                item,
328                hash,
329                existing,
330            } => {
331                write!(f,"Conflicting meta hash `{hash}` for existing `{existing}` when inserting item `{item}`")?;
332            }
333            ContextError::ConflictingTypeHash { hash, existing } => {
334                write!(
335                    f,
336                    "Tried to insert conflicting hash `{hash}` for `{existing}`"
337                )?;
338            }
339            ContextError::ConflictingVariant { item } => {
340                write!(f, "Variant with `{item}` already exists")?;
341            }
342            ContextError::ConstructorConflict { type_info } => {
343                write!(f, "Constructor for `{type_info}` already exists")?;
344            }
345            ContextError::VariantConstructorConflict { type_info, name } => {
346                write!(
347                    f,
348                    "Constructor for variant `{name}` for `{type_info}` already exists"
349                )?;
350            }
351            ContextError::ConstructorArgumentsMismatch {
352                type_info,
353                expected,
354                actual,
355            } => {
356                write!(
357                    f,
358                    "Constructor for `{type_info}` has {actual} arguments but expected {expected}"
359                )?;
360            }
361            ContextError::VariantConstructorArgumentsMismatch {
362                type_info,
363                name,
364                expected,
365                actual,
366            } => {
367                write!(
368                    f,
369                    "Constructor for variant `{name}` for `{type_info}` has {actual} arguments but expected {expected}"
370                )?;
371            }
372            ContextError::ConflictingConstConstruct { type_info, hash } => {
373                write!(
374                    f,
375                    "Constant constructor with hash {hash} for `{type_info}` already exists"
376                )?;
377            }
378            ContextError::MissingType { item, type_info } => {
379                write!(f, "Type `{item}` with info `{type_info}` isn't registered")?;
380            }
381            ContextError::MissingEnum { item, type_info } => {
382                write!(
383                    f,
384                    "Type `{item}` with info `{type_info}` is registered but is not an enum"
385                )?;
386            }
387            ContextError::MissingContainer { container } => {
388                write!(f, "Container `{container}` is not registered")?;
389            }
390            ContextError::MissingVariant { index, type_info } => {
391                write!(f, "Missing variant {index} for `{type_info}`")?;
392            }
393            ContextError::ExpectedAssociated => {
394                write!(f, "Expected associated function")?;
395            }
396            ContextError::TypeHashMismatch {
397                type_info,
398                item,
399                hash,
400                item_hash,
401            } => {
402                let expected = item.parent().unwrap_or_default();
403
404                write! {
405                    f,
406                    "Type hash mismatch for `{type_info}`, from module is `{hash}` while from item `{item}` is `{item_hash}`.\n\
407                    You might not have the #[rune(item = {expected})] attribute set."
408                }?;
409            }
410            ContextError::StaticTypeHashMismatch {
411                type_info,
412                item,
413                hash,
414                item_hash,
415            } => {
416                write!(f, "Static type hash mismatch for `{type_info}`, from module is `{hash}` while from item `{item}` is `{item_hash}`. The static item might be registered in the wrong module, or that the static type hash is miscalculated.")?;
417            }
418        }
419
420        Ok(())
421    }
422}
423
424impl core::error::Error for ContextError {}