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#[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 {}