Skip to main content

rune/compile/
error.rs

1use core::convert::Infallible;
2use core::fmt;
3
4#[cfg(feature = "std")]
5use std::io;
6#[cfg(feature = "std")]
7use std::path::PathBuf;
8
9use crate as rune;
10use crate::alloc::prelude::*;
11use crate::alloc::{self, Box, String, Vec};
12use crate::ast;
13use crate::ast::unescape;
14use crate::ast::{Span, Spanned};
15use crate::compile::ir;
16use crate::compile::num::FromFloatError;
17use crate::compile::{HasSpan, Location, MetaInfo, Visibility};
18use crate::hash::TooManyParameters;
19use crate::indexing::items::{GuardMismatch, MissingLastId};
20use crate::macros::{SyntheticId, SyntheticKind};
21use crate::parse::{Expectation, IntoExpectation, LexerMode};
22use crate::runtime::debug::DebugSignature;
23use crate::runtime::unit::EncodeError;
24use crate::runtime::{
25    AccessError, AnyObjError, ExpectedType, RuntimeError, TypeInfo, TypeOf, VmError,
26};
27#[cfg(feature = "std")]
28use crate::source;
29use crate::{Hash, Item, ItemBuf, SourceId};
30
31/// An error raised by the compiler.
32#[derive(Debug)]
33pub struct Error {
34    // The span the error is associated with.
35    span: Span,
36    // Errors are exempt from fallible allocations since they're not commonly
37    // constructed.
38    kind: rust_alloc::boxed::Box<ErrorKind>,
39}
40
41impl Error {
42    /// Construct a new compile error.
43    pub(crate) fn new<S, K>(span: S, kind: K) -> Self
44    where
45        S: Spanned,
46        ErrorKind: From<K>,
47    {
48        Self {
49            span: span.span(),
50            kind: rust_alloc::boxed::Box::new(ErrorKind::from(kind)),
51        }
52    }
53
54    /// Construct an error which is made of a single message.
55    pub fn msg<S, M>(span: S, message: M) -> Self
56    where
57        S: Spanned,
58        M: fmt::Display,
59    {
60        Self {
61            span: span.span(),
62            kind: rust_alloc::boxed::Box::new(ErrorKind::msg(message)),
63        }
64    }
65
66    /// Get the kind of the error.
67    #[cfg(feature = "emit")]
68    pub(crate) fn kind(&self) -> &ErrorKind {
69        &self.kind
70    }
71
72    /// Convert into the kind of the error.
73    #[cfg(test)]
74    pub(crate) fn into_kind(self) -> ErrorKind {
75        *self.kind
76    }
77}
78
79impl Spanned for Error {
80    #[inline]
81    fn span(&self) -> Span {
82        self.span
83    }
84}
85
86impl core::error::Error for Error {
87    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
88        self.kind.source()
89    }
90}
91
92impl fmt::Display for Error {
93    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94        fmt::Display::fmt(&self.kind, f)
95    }
96}
97
98impl From<Infallible> for Error {
99    #[inline]
100    fn from(value: Infallible) -> Self {
101        match value {}
102    }
103}
104
105impl<S, E> From<HasSpan<S, E>> for Error
106where
107    S: Spanned,
108    ErrorKind: From<E>,
109{
110    fn from(spanned: HasSpan<S, E>) -> Self {
111        Self::new(spanned.span(), spanned.into_inner())
112    }
113}
114
115impl From<TooManyParameters> for ErrorKind {
116    #[inline]
117    fn from(error: TooManyParameters) -> Self {
118        ErrorKind::TooManyParameters(error)
119    }
120}
121
122impl From<fmt::Error> for ErrorKind {
123    #[inline]
124    fn from(fmt::Error: fmt::Error) -> Self {
125        ErrorKind::FormatError
126    }
127}
128
129impl From<syntree::Error<alloc::Error>> for ErrorKind {
130    #[inline]
131    fn from(error: syntree::Error<alloc::Error>) -> Self {
132        ErrorKind::Syntree(error)
133    }
134}
135
136#[cfg(feature = "std")]
137impl From<io::Error> for ErrorKind {
138    #[inline]
139    fn from(error: io::Error) -> Self {
140        ErrorKind::msg(error)
141    }
142}
143
144impl From<ir::scopes::MissingLocal> for ErrorKind {
145    #[inline]
146    fn from(error: ir::scopes::MissingLocal) -> Self {
147        ErrorKind::MissingLocal { name: error.0 }
148    }
149}
150
151#[cfg(feature = "anyhow")]
152impl From<anyhow::Error> for ErrorKind {
153    #[inline]
154    fn from(error: anyhow::Error) -> Self {
155        ErrorKind::msg(error)
156    }
157}
158
159impl From<&'static str> for ErrorKind {
160    #[inline]
161    fn from(value: &'static str) -> Self {
162        ErrorKind::msg(value)
163    }
164}
165
166// NB: Sometimes errors are boxed because they're so big.
167impl<T> From<Box<T>> for ErrorKind
168where
169    ErrorKind: From<T>,
170{
171    #[inline]
172    fn from(kind: Box<T>) -> Self {
173        ErrorKind::from(Box::into_inner(kind))
174    }
175}
176
177impl From<FromFloatError> for ErrorKind {
178    #[inline]
179    fn from(error: FromFloatError) -> Self {
180        match error {
181            FromFloatError::Error => ErrorKind::BadFloatLiteral,
182            FromFloatError::ScratchInUse => ErrorKind::msg("scratch space in use"),
183            FromFloatError::Alloc(error) => ErrorKind::AllocError { error },
184        }
185    }
186}
187
188// TODO: remove implementation.
189impl<T> From<rust_alloc::boxed::Box<T>> for ErrorKind
190where
191    ErrorKind: From<T>,
192{
193    #[inline]
194    fn from(kind: rust_alloc::boxed::Box<T>) -> Self {
195        ErrorKind::from(*kind)
196    }
197}
198
199impl From<ExpectedType> for ErrorKind {
200    #[inline]
201    fn from(error: ExpectedType) -> Self {
202        ErrorKind::ExpectedType {
203            actual: error.actual,
204            expected: error.expected,
205        }
206    }
207}
208
209impl From<alloc::Error> for rust_alloc::boxed::Box<ErrorKind> {
210    #[inline]
211    fn from(error: alloc::Error) -> Self {
212        rust_alloc::boxed::Box::new(ErrorKind::from(error))
213    }
214}
215
216impl Error {
217    /// Error when we got mismatched meta.
218    pub fn expected_meta<S>(spanned: S, meta: MetaInfo, expected: &'static str) -> Self
219    where
220        S: Spanned,
221    {
222        Self::new(spanned, ErrorKind::ExpectedMeta { meta, expected })
223    }
224
225    /// Construct an resolve expected error.
226    pub(crate) fn expected<A, E>(actual: A, expected: E) -> Self
227    where
228        A: IntoExpectation + Spanned,
229        E: IntoExpectation,
230    {
231        Self::new(
232            actual.span(),
233            ErrorKind::Expected {
234                actual: actual.into_expectation(),
235                expected: expected.into_expectation(),
236            },
237        )
238    }
239
240    /// Construct an unsupported error.
241    pub(crate) fn unsupported<T, E>(actual: T, what: E) -> Self
242    where
243        T: Spanned,
244        E: IntoExpectation,
245    {
246        Self::new(
247            actual.span(),
248            ErrorKind::Unsupported {
249                what: what.into_expectation(),
250            },
251        )
252    }
253
254    /// An error raised when we expect a certain constant value but get another.
255    pub(crate) fn expected_type<E>(spanned: impl Spanned, actual: TypeInfo) -> Self
256    where
257        E: TypeOf,
258    {
259        Self::new(
260            spanned,
261            IrErrorKind::Expected {
262                expected: TypeInfo::from(E::STATIC_TYPE_INFO),
263                actual,
264            },
265        )
266    }
267}
268
269/// Compiler error.
270#[derive(Debug)]
271#[non_exhaustive]
272pub(crate) enum ErrorKind {
273    Custom {
274        error: String,
275    },
276    AllocError {
277        error: alloc::Error,
278    },
279    Ir(IrErrorKind),
280    Meta(MetaError),
281    Access(AccessError),
282    Vm(VmError),
283    Encode(EncodeError),
284    MissingLastId(MissingLastId),
285    GuardMismatch(GuardMismatch),
286    MissingScope(MissingScope),
287    PopError(PopError),
288    UnescapeError(unescape::ErrorKind),
289    Syntree(syntree::Error<alloc::Error>),
290    TooManyParameters(TooManyParameters),
291    FormatError,
292    #[cfg(feature = "std")]
293    SourceError {
294        path: PathBuf,
295        error: source::FromPathError,
296    },
297    ExpectedType {
298        actual: TypeInfo,
299        expected: TypeInfo,
300    },
301    Expected {
302        actual: Expectation,
303        expected: Expectation,
304    },
305    Unsupported {
306        what: Expectation,
307    },
308    #[cfg(feature = "std")]
309    ModNotFound {
310        path: PathBuf,
311    },
312    ModAlreadyLoaded {
313        item: ItemBuf,
314        #[cfg(feature = "emit")]
315        existing: (SourceId, Span),
316    },
317    MissingMacro {
318        item: ItemBuf,
319    },
320    MissingSelf,
321    MissingLocal {
322        name: Box<str>,
323    },
324    MissingItem {
325        item: ItemBuf,
326    },
327    MissingItemHash {
328        hash: Hash,
329    },
330    MissingItemParameters {
331        item: ItemBuf,
332        parameters: [Option<Hash>; 2],
333    },
334    UnsupportedGlobal,
335    UnsupportedModuleSource,
336    #[cfg(feature = "std")]
337    UnsupportedModuleRoot {
338        root: PathBuf,
339    },
340    #[cfg(feature = "std")]
341    SourceWithoutPath,
342    #[cfg(feature = "std")]
343    UnsupportedModuleItem {
344        item: ItemBuf,
345    },
346    UnsupportedSelf,
347    UnsupportedUnaryOp {
348        op: ast::UnOp,
349    },
350    UnsupportedBinaryOp {
351        op: ast::BinOp,
352    },
353    UnsupportedLitObject {
354        meta: MetaInfo,
355    },
356    LitObjectMissingField {
357        field: Box<str>,
358        item: ItemBuf,
359    },
360    LitObjectNotField {
361        field: Box<str>,
362        item: ItemBuf,
363    },
364    UnsupportedAssignExpr,
365    UnsupportedBinaryExpr,
366    UnsupportedRef,
367    StaticInConstContext {
368        item: ItemBuf,
369    },
370    StaticInPattern {
371        item: ItemBuf,
372    },
373    ConflictingStatic {
374        item: ItemBuf,
375    },
376    BadArgumentCount {
377        expected: usize,
378        actual: usize,
379    },
380    UnsupportedPatternExpr,
381    UnsupportedBinding,
382    DuplicateObjectKey {
383        #[cfg(feature = "emit")]
384        existing: Span,
385        #[cfg(feature = "emit")]
386        object: Span,
387    },
388    InstanceFunctionOutsideImpl,
389    UnsupportedTupleIndex {
390        number: ast::Number,
391    },
392    BreakUnsupported,
393    BreakUnsupportedValue,
394    ContinueUnsupported,
395    ContinueUnsupportedBlock,
396    SelectMultipleDefaults,
397    ExpectedBlockSemiColon {
398        #[cfg(feature = "emit")]
399        followed_span: Span,
400    },
401    FnConstAsyncConflict,
402    BlockConstAsyncConflict,
403    ClosureKind,
404    UnsupportedSelfType,
405    UnsupportedSuper,
406    UnsupportedSuperInSelfType,
407    UnsupportedAfterGeneric,
408    IllegalUseSegment,
409    UseAliasNotSupported,
410    FunctionConflict {
411        existing: DebugSignature,
412    },
413    FunctionReExportConflict {
414        hash: Hash,
415    },
416    ConstantConflict {
417        hash: Hash,
418    },
419    StaticStringMissing {
420        hash: Hash,
421        slot: usize,
422    },
423    StaticBytesMissing {
424        hash: Hash,
425        slot: usize,
426    },
427    StaticStringHashConflict {
428        hash: Hash,
429        current: String,
430        existing: String,
431    },
432    StaticBytesHashConflict {
433        hash: Hash,
434        current: Vec<u8>,
435        existing: Vec<u8>,
436    },
437    StaticObjectKeysMissing {
438        hash: Hash,
439        slot: usize,
440    },
441    StaticObjectKeysHashConflict {
442        hash: Hash,
443        current: Box<[String]>,
444        existing: Box<[String]>,
445    },
446    ConflictingLabels {
447        #[cfg_attr(not(feature = "emit"), allow(unused))]
448        existing: Span,
449    },
450    DuplicateSelectDefault {
451        #[cfg_attr(not(feature = "emit"), allow(unused))]
452        existing: Span,
453    },
454    MissingLabel {
455        label: Box<str>,
456    },
457    ExpectedLeadingPathSegment,
458    UnsupportedVisibility,
459    ExpectedMeta {
460        expected: &'static str,
461        meta: MetaInfo,
462    },
463    NoSuchBuiltInMacro {
464        name: Box<str>,
465    },
466    VariableMoved {
467        #[cfg(feature = "emit")]
468        moved_at: Span,
469    },
470    UnsupportedGenerics,
471    NestedTest {
472        #[cfg(feature = "emit")]
473        nested_span: Span,
474    },
475    NestedBench {
476        #[cfg(feature = "emit")]
477        nested_span: Span,
478    },
479    MissingFunctionHash {
480        hash: Hash,
481    },
482    FunctionConflictHash {
483        hash: Hash,
484    },
485    PatternMissingFields {
486        item: ItemBuf,
487        #[cfg(feature = "emit")]
488        fields: Box<[Box<str>]>,
489    },
490    MissingLabelLocation {
491        name: &'static str,
492        index: usize,
493    },
494    MaxMacroRecursion {
495        depth: usize,
496        max: usize,
497    },
498    YieldInConst,
499    AwaitInConst,
500    AwaitOutsideAsync,
501    ExpectedEof {
502        actual: ast::Kind,
503    },
504    UnexpectedEof,
505    BadLexerMode {
506        actual: LexerMode,
507        expected: LexerMode,
508    },
509    ExpectedEscape,
510    UnterminatedStrLit,
511    UnterminatedByteStrLit,
512    UnterminatedCharLit,
513    UnterminatedByteLit,
514    ExpectedCharClose,
515    ExpectedCharOrLabel,
516    ExpectedByteClose,
517    UnexpectedChar {
518        c: char,
519    },
520    PrecedenceGroupRequired,
521    BadSignedOutOfBounds {
522        size: ast::NumberSize,
523    },
524    BadUnsignedOutOfBounds {
525        size: ast::NumberSize,
526    },
527    BadFieldAccess,
528    ExpectedMacroCloseDelimiter {
529        expected: ast::Kind,
530        actual: ast::Kind,
531    },
532    MultipleMatchingAttributes {
533        name: &'static str,
534    },
535    MissingSourceId {
536        source_id: SourceId,
537    },
538    ExpectedMultilineCommentTerm,
539    BadSlice,
540    BadSyntheticId {
541        kind: SyntheticKind,
542        id: SyntheticId,
543    },
544    BadCharLiteral,
545    BadByteLiteral,
546    BadNumberLiteral,
547    BadFloatLiteral,
548    AmbiguousItem {
549        item: ItemBuf,
550        #[cfg(feature = "emit")]
551        locations: Vec<(Location, ItemBuf)>,
552    },
553    AmbiguousContextItem {
554        item: ItemBuf,
555        #[cfg(feature = "emit")]
556        infos: Box<[MetaInfo]>,
557    },
558    NotVisible {
559        #[cfg(feature = "emit")]
560        chain: Vec<Location>,
561        #[cfg(feature = "emit")]
562        location: Location,
563        visibility: Visibility,
564        item: ItemBuf,
565        from: ItemBuf,
566    },
567    NotVisibleMod {
568        #[cfg(feature = "emit")]
569        chain: Vec<Location>,
570        #[cfg(feature = "emit")]
571        location: Location,
572        visibility: Visibility,
573        item: ItemBuf,
574        from: ItemBuf,
575    },
576    MissingMod {
577        item: ItemBuf,
578    },
579    ImportCycle {
580        #[cfg(feature = "emit")]
581        path: Vec<ImportStep>,
582    },
583    ImportRecursionLimit {
584        count: usize,
585        #[allow(unused)]
586        path: Vec<ImportStep>,
587    },
588    LastUseComponent,
589    RttiConflict {
590        hash: Hash,
591    },
592    TypeRttiConflict {
593        hash: Hash,
594    },
595    ArenaWriteSliceOutOfBounds {
596        index: usize,
597    },
598    ArenaAllocError {
599        requested: usize,
600    },
601    UnsupportedPatternRest,
602    UnsupportedMut,
603    UnsupportedSuffix,
604    ClosureInConst,
605    AsyncBlockInConst,
606    #[cfg(feature = "fmt")]
607    BadSpan {
608        len: usize,
609    },
610    UnexpectedEndOfSyntax {
611        inside: Expectation,
612    },
613    UnexpectedEndOfSyntaxWith {
614        inside: Expectation,
615        expected: Expectation,
616    },
617    ExpectedSyntaxEnd {
618        inside: Expectation,
619        actual: Expectation,
620    },
621    #[cfg(feature = "fmt")]
622    BadIndent {
623        level: isize,
624        indent: usize,
625    },
626    ExpectedSyntax {
627        expected: Expectation,
628        actual: Expectation,
629    },
630    ExpectedSyntaxIn {
631        inside: Expectation,
632        expected: Expectation,
633        actual: Expectation,
634    },
635    ExpectedOne {
636        inside: Expectation,
637        expected: Expectation,
638    },
639    ExpectedAtMostOne {
640        inside: Expectation,
641        expected: Expectation,
642        count: usize,
643    },
644    ExpectedAtLeastOne {
645        inside: Expectation,
646        expected: Expectation,
647    },
648    #[cfg(feature = "fmt")]
649    UnsupportedDelimiter {
650        expectation: Expectation,
651    },
652}
653
654impl ErrorKind {
655    #[inline]
656    pub(crate) fn msg<M>(message: M) -> Self
657    where
658        M: fmt::Display,
659    {
660        match crate::alloc::fmt::try_format(format_args!("{message}")) {
661            Ok(string) => Self::Custom { error: string },
662            Err(error) => Self::AllocError { error },
663        }
664    }
665}
666
667impl core::error::Error for ErrorKind {
668    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
669        match self {
670            ErrorKind::Ir(source) => Some(source),
671            ErrorKind::Meta(source) => Some(source),
672            ErrorKind::Access(source) => Some(source),
673            ErrorKind::Vm(source) => Some(source),
674            ErrorKind::Encode(source) => Some(source),
675            ErrorKind::MissingLastId(source) => Some(source),
676            ErrorKind::GuardMismatch(source) => Some(source),
677            ErrorKind::MissingScope(source) => Some(source),
678            ErrorKind::PopError(source) => Some(source),
679            ErrorKind::UnescapeError(source) => Some(source),
680            #[cfg(feature = "std")]
681            ErrorKind::SourceError { error, .. } => Some(error),
682            _ => None,
683        }
684    }
685}
686
687impl fmt::Display for ErrorKind {
688    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
689        match self {
690            ErrorKind::Custom { error } => {
691                error.fmt(f)?;
692            }
693            ErrorKind::AllocError { error } => {
694                error.fmt(f)?;
695            }
696            ErrorKind::Ir(error) => {
697                error.fmt(f)?;
698            }
699            ErrorKind::Meta(error) => {
700                error.fmt(f)?;
701            }
702            ErrorKind::Access(error) => {
703                error.fmt(f)?;
704            }
705            ErrorKind::Vm(error) => {
706                error.fmt(f)?;
707            }
708            ErrorKind::Encode(error) => {
709                error.fmt(f)?;
710            }
711            ErrorKind::MissingLastId(error) => {
712                error.fmt(f)?;
713            }
714            ErrorKind::GuardMismatch(error) => {
715                error.fmt(f)?;
716            }
717            ErrorKind::MissingScope(error) => {
718                error.fmt(f)?;
719            }
720            ErrorKind::PopError(error) => {
721                error.fmt(f)?;
722            }
723            ErrorKind::UnescapeError(error) => {
724                error.fmt(f)?;
725            }
726            ErrorKind::Syntree(error) => {
727                error.fmt(f)?;
728            }
729            ErrorKind::TooManyParameters(error) => {
730                error.fmt(f)?;
731            }
732            ErrorKind::FormatError => {
733                write!(f, "Formatting error")?;
734            }
735            #[cfg(feature = "std")]
736            ErrorKind::SourceError { path, error } => {
737                write!(
738                    f,
739                    "Failed to load source at `{path}`: {error}",
740                    path = path.display(),
741                )?;
742            }
743            ErrorKind::ExpectedType { actual, expected } => {
744                write!(f, "Expected type `{expected}` but found `{actual}`")?;
745            }
746            ErrorKind::Expected { actual, expected } => {
747                write!(f, "Expected {expected} but got {actual}")?;
748            }
749            ErrorKind::Unsupported { what } => {
750                write!(f, "Unsupported {what}")?;
751            }
752            #[cfg(feature = "std")]
753            ErrorKind::ModNotFound { path } => {
754                write!(
755                    f,
756                    "File not found, expected a module file like `{path}.rn`",
757                    path = path.display()
758                )?;
759            }
760            ErrorKind::ModAlreadyLoaded { item, .. } => {
761                write!(f, "Module `{item}` has already been loaded")?;
762            }
763            ErrorKind::MissingMacro { item } => {
764                write!(f, "Missing macro {item}")?;
765            }
766            ErrorKind::MissingSelf => write!(f, "No `self` in current context")?,
767            ErrorKind::MissingLocal { name } => {
768                write!(f, "No local variable `{name}`")?;
769            }
770            ErrorKind::MissingItem { item } => {
771                write!(f, "Missing item {item}")?;
772            }
773            ErrorKind::MissingItemHash { hash } => {
774                write!(
775                    f,
776                    "Tried to insert meta with hash `{hash}` which does not have an item",
777                )?;
778            }
779            ErrorKind::MissingItemParameters { item, parameters } => {
780                write!(f, "Missing item {}", ParameterizedItem(item, parameters))?;
781            }
782            ErrorKind::UnsupportedGlobal => {
783                write!(f, "Unsupported crate prefix `::`")?;
784            }
785            ErrorKind::UnsupportedModuleSource => {
786                write!(
787                    f,
788                    "Cannot load modules using a source without an associated URL"
789                )?;
790            }
791            #[cfg(feature = "std")]
792            ErrorKind::UnsupportedModuleRoot { root } => {
793                write!(
794                    f,
795                    "Cannot load modules relative to `{root}`",
796                    root = root.display()
797                )?;
798            }
799            #[cfg(feature = "std")]
800            ErrorKind::SourceWithoutPath => {
801                write!(
802                    f,
803                    "Cannot load module from source without an associated path"
804                )?;
805            }
806            #[cfg(feature = "std")]
807            ErrorKind::UnsupportedModuleItem { item } => {
808                write!(f, "Cannot load module for `{item}`")?;
809            }
810            ErrorKind::UnsupportedSelf => {
811                write!(f, "Keyword `self` not supported here")?;
812            }
813            ErrorKind::UnsupportedUnaryOp { op } => {
814                write!(f, "Unsupported unary operator `{op}`")?;
815            }
816            ErrorKind::UnsupportedBinaryOp { op } => {
817                write!(f, "Unsupported binary operator `{op}`")?;
818            }
819            ErrorKind::UnsupportedLitObject { meta } => {
820                write!(f, "Item `{meta}` is not an object")?;
821            }
822            ErrorKind::LitObjectMissingField { field, item } => {
823                write!(f, "Missing field `{field}` in declaration of `{item}`")?;
824            }
825            ErrorKind::LitObjectNotField { field, item } => {
826                write!(f, "Field `{field}` is not a field in `{item}`")?;
827            }
828            ErrorKind::UnsupportedAssignExpr => {
829                write!(f, "Cannot assign to expression")?;
830            }
831            ErrorKind::UnsupportedBinaryExpr => {
832                write!(f, "Unsupported binary expression")?;
833            }
834            ErrorKind::UnsupportedRef => {
835                write!(f, "Cannot take reference of expression")?;
836            }
837            ErrorKind::StaticInConstContext { item } => {
838                write!(
839                    f,
840                    "The static `{item}` cannot be used in a constant context, since its value is only known at runtime"
841                )?;
842            }
843            ErrorKind::StaticInPattern { item } => {
844                write!(
845                    f,
846                    "The static `{item}` cannot be used in a pattern, since its value is only known at runtime"
847                )?;
848            }
849            ErrorKind::ConflictingStatic { item } => {
850                write!(
851                    f,
852                    "The item `{item}` conflicts with a static of the same name which was declared with the build"
853                )?;
854            }
855            ErrorKind::BadArgumentCount { expected, actual } => {
856                write!(f, "Wrong number of arguments {actual}, expected {expected}",)?;
857            }
858            ErrorKind::UnsupportedPatternExpr => {
859                write!(f, "This kind of expression is not supported as a pattern")?;
860            }
861            ErrorKind::UnsupportedBinding => {
862                write!(f, "Not a valid binding")?;
863            }
864            ErrorKind::DuplicateObjectKey { .. } => {
865                write!(f, "Duplicate key in literal object")?;
866            }
867            ErrorKind::InstanceFunctionOutsideImpl => {
868                write!(f, "Instance function declared outside of `impl` block")?;
869            }
870            ErrorKind::UnsupportedTupleIndex { number } => {
871                write!(f, "Unsupported tuple index `{number}`")?;
872            }
873            ErrorKind::BreakUnsupported => {
874                write!(f, "Break outside of loop")?;
875            }
876            ErrorKind::BreakUnsupportedValue => {
877                write!(
878                    f,
879                    "Can only break with a value inside `loop` or breakable block"
880                )?;
881            }
882            ErrorKind::ContinueUnsupported => {
883                write!(f, "Continue outside of loop")?;
884            }
885            ErrorKind::ContinueUnsupportedBlock => {
886                write!(f, "Labeled blocks cannot be `continue`'d")?;
887            }
888            ErrorKind::SelectMultipleDefaults => {
889                write!(f, "Multiple `default` branches in select")?;
890            }
891            ErrorKind::ExpectedBlockSemiColon { .. } => {
892                write!(f, "Expected expression to be terminated by a semicolon `;`")?;
893            }
894            ErrorKind::FnConstAsyncConflict => {
895                write!(
896                    f,
897                    "An `fn` can't both be `async` and `const` at the same time"
898                )?;
899            }
900            ErrorKind::BlockConstAsyncConflict => {
901                write!(
902                    f,
903                    "A block can't both be `async` and `const` at the same time"
904                )?;
905            }
906            ErrorKind::ClosureKind => {
907                write!(f, "Unsupported closure kind")?;
908            }
909            ErrorKind::UnsupportedSelfType => {
910                write!(
911                    f,
912                    "Keyword `Self` is only supported inside of `impl` blocks"
913                )?;
914            }
915            ErrorKind::UnsupportedSuper => {
916                write!(
917                    f,
918                    "Keyword `super` is not supported at the root module level"
919                )?;
920            }
921            ErrorKind::UnsupportedSuperInSelfType => {
922                write!(
923                    f,
924                    "Keyword `super` can't be used in paths starting with `Self`"
925                )?;
926            }
927            ErrorKind::UnsupportedAfterGeneric => {
928                write!(
929                    f,
930                    "This kind of path component cannot follow a generic argument"
931                )?;
932            }
933            ErrorKind::IllegalUseSegment => {
934                write!(
935                    f,
936                    "Another segment can't follow wildcard `*` or group imports"
937                )?;
938            }
939            ErrorKind::UseAliasNotSupported => {
940                write!(
941                    f,
942                    "Use aliasing is not supported for wildcard `*` or group imports"
943                )?;
944            }
945            ErrorKind::FunctionConflict { existing } => {
946                write!(
947                    f,
948                    "Conflicting function signature already exists `{existing}`",
949                )?;
950            }
951            ErrorKind::FunctionReExportConflict { hash } => {
952                write!(f, "Conflicting function hash already exists `{hash}`")?;
953            }
954            ErrorKind::ConstantConflict { hash } => {
955                write!(f, "Conflicting constant for hash `{hash}`")?;
956            }
957            ErrorKind::StaticStringMissing { hash, slot } => {
958                write!(
959                    f,
960                    "Missing static string for hash `{hash}` and slot `{slot}`",
961                )?;
962            }
963            ErrorKind::StaticBytesMissing { hash, slot } => {
964                write!(
965                    f,
966                    "Missing static byte string for hash `{hash}` and slot `{slot}`",
967                )?;
968            }
969            ErrorKind::StaticStringHashConflict {
970                hash,
971                current,
972                existing,
973            } => {
974                write!(f,"Conflicting static string for hash `{hash}` between `{existing:?}` and `{current:?}`")?;
975            }
976            ErrorKind::StaticBytesHashConflict {
977                hash,
978                current,
979                existing,
980            } => {
981                write!(f,"Conflicting static string for hash `{hash}` between `{existing:?}` and `{current:?}`")?;
982            }
983            ErrorKind::StaticObjectKeysMissing { hash, slot } => {
984                write!(
985                    f,
986                    "Missing static object keys for hash `{hash}` and slot `{slot}`",
987                )?;
988            }
989            ErrorKind::StaticObjectKeysHashConflict {
990                hash,
991                current,
992                existing,
993            } => {
994                write!(f,"Conflicting static object keys for hash `{hash}` between `{existing:?}` and `{current:?}`")?;
995            }
996            ErrorKind::ConflictingLabels { .. } => {
997                write!(f, "Multiple labels provided")?;
998            }
999            ErrorKind::DuplicateSelectDefault { .. } => {
1000                write!(f, "Multiple default select branches")?;
1001            }
1002            ErrorKind::MissingLabel { label } => {
1003                write!(f, "Missing label '{label}")?;
1004            }
1005            ErrorKind::ExpectedLeadingPathSegment => {
1006                write!(f, "Segment is only supported in the first position")?;
1007            }
1008            ErrorKind::UnsupportedVisibility => {
1009                write!(f, "Visibility modifier not supported")?;
1010            }
1011            ErrorKind::ExpectedMeta { expected, meta } => {
1012                write!(f, "Expected {expected} but got `{meta}`")?;
1013            }
1014            ErrorKind::NoSuchBuiltInMacro { name } => {
1015                write!(f, "No such built-in macro `{name}`")?;
1016            }
1017            ErrorKind::VariableMoved { .. } => {
1018                write!(f, "Variable moved")?;
1019            }
1020            ErrorKind::UnsupportedGenerics => {
1021                write!(f, "Unsupported generic argument")?;
1022            }
1023            ErrorKind::NestedTest { .. } => {
1024                write!(f, "Attribute `#[test]` is not supported on nested items")?;
1025            }
1026            ErrorKind::NestedBench { .. } => {
1027                write!(f, "Attribute `#[bench]` is not supported on nested items")?;
1028            }
1029            ErrorKind::MissingFunctionHash { hash } => {
1030                write!(f, "Missing function with hash `{hash}`")?;
1031            }
1032            ErrorKind::FunctionConflictHash { hash } => {
1033                write!(f, "Conflicting function already exists `{hash}`")?;
1034            }
1035            ErrorKind::PatternMissingFields { item, .. } => {
1036                write!(f, "Non-exhaustive pattern for `{item}`")?;
1037            }
1038            ErrorKind::MissingLabelLocation { name, index } => {
1039                write!(
1040                    f,
1041                    "Use of label `{name}_{index}` which has no code location",
1042                )?;
1043            }
1044            ErrorKind::MaxMacroRecursion { depth, max } => {
1045                write!(
1046                    f,
1047                    "Reached macro recursion limit at {depth}, limit is {max}",
1048                )?;
1049            }
1050            ErrorKind::YieldInConst => {
1051                write!(f, "Expression `yield` inside of constant function")?;
1052            }
1053            ErrorKind::AwaitInConst => {
1054                write!(f, "Expression `.await` inside of constant context")?;
1055            }
1056            ErrorKind::AwaitOutsideAsync => {
1057                write!(f, "Expression `.await` outside of async function or block")?;
1058            }
1059            ErrorKind::ExpectedEof { actual } => {
1060                write!(f, "Expected end of file, but got {actual}")?;
1061            }
1062            ErrorKind::UnexpectedEof => {
1063                write!(f, "Unexpected end of file")?;
1064            }
1065            ErrorKind::BadLexerMode { actual, expected } => {
1066                write!(f, "Bad lexer mode `{actual}`, expected `{expected}`")?;
1067            }
1068            ErrorKind::ExpectedEscape => {
1069                write!(f, "Expected escape sequence")?;
1070            }
1071            ErrorKind::UnterminatedStrLit => {
1072                write!(f, "Unterminated string literal")?;
1073            }
1074            ErrorKind::UnterminatedByteStrLit => {
1075                write!(f, "Unterminated byte string literal")?;
1076            }
1077            ErrorKind::UnterminatedCharLit => {
1078                write!(f, "Unterminated character literal")?;
1079            }
1080            ErrorKind::UnterminatedByteLit => {
1081                write!(f, "Unterminated byte literal")?;
1082            }
1083            ErrorKind::ExpectedCharClose => {
1084                write!(f, "Expected character literal to be closed")?;
1085            }
1086            ErrorKind::ExpectedCharOrLabel => {
1087                write!(f, "Expected label or character")?;
1088            }
1089            ErrorKind::ExpectedByteClose => {
1090                write!(f, "Expected byte literal to be closed")?;
1091            }
1092            ErrorKind::UnexpectedChar { c } => {
1093                write!(f, "Unexpected character `{c}`")?;
1094            }
1095            ErrorKind::PrecedenceGroupRequired => {
1096                write!(f, "Group required in expression to determine precedence")?;
1097            }
1098            ErrorKind::BadSignedOutOfBounds { size } => {
1099                write!(
1100                    f,
1101                    "Signed number literal out of bounds `{}` to `{}`",
1102                    size.signed_min(),
1103                    size.signed_max(),
1104                )?;
1105            }
1106            ErrorKind::BadUnsignedOutOfBounds { size } => {
1107                write!(
1108                    f,
1109                    "Unsigned number literal out of bounds `{}` to `{}`",
1110                    size.unsigned_min(),
1111                    size.unsigned_max(),
1112                )?;
1113            }
1114            ErrorKind::BadFieldAccess => {
1115                write!(f, "Unsupported field access")?;
1116            }
1117            ErrorKind::ExpectedMacroCloseDelimiter { expected, actual } => {
1118                write!(f, "Expected close delimiter {expected}, but got {actual}")?;
1119            }
1120            ErrorKind::MultipleMatchingAttributes { name } => {
1121                write!(f, "Can only specify one attribute named `{name}`")?;
1122            }
1123            ErrorKind::MissingSourceId { source_id } => {
1124                write!(f, "Missing source id `{source_id}`")?;
1125            }
1126            ErrorKind::ExpectedMultilineCommentTerm => {
1127                write!(f, "Expected multiline comment to be terminated with a `*/`")?;
1128            }
1129            ErrorKind::BadSlice => {
1130                write!(f, "Tried to read bad slice from source")?;
1131            }
1132            ErrorKind::BadSyntheticId { kind, id } => {
1133                write!(
1134                    f,
1135                    "Tried to get bad synthetic identifier `{id}` for `{kind}`",
1136                )?;
1137            }
1138            ErrorKind::BadCharLiteral => {
1139                write!(f, "Bad character literal")?;
1140            }
1141            ErrorKind::BadByteLiteral => {
1142                write!(f, "Bad byte literal")?;
1143            }
1144            ErrorKind::BadNumberLiteral => {
1145                write!(f, "Bad number literal")?;
1146            }
1147            ErrorKind::BadFloatLiteral => {
1148                write!(f, "Bad float literal")?;
1149            }
1150            ErrorKind::AmbiguousItem { item, .. } => {
1151                write!(f, "Item `{item}` can refer to multiple things")?;
1152            }
1153            ErrorKind::AmbiguousContextItem { item, .. } => {
1154                write!(
1155                    f,
1156                    "Item `{item}` can refer to multiple things from the context"
1157                )?;
1158            }
1159            ErrorKind::NotVisible {
1160                visibility,
1161                item,
1162                from,
1163                ..
1164            } => {
1165                write!(f,"Item `{item}` with visibility `{visibility}`, is not accessible from module `{from}`")?;
1166            }
1167            ErrorKind::NotVisibleMod {
1168                visibility,
1169                item,
1170                from,
1171                ..
1172            } => {
1173                write!(f,"Module `{item}` with {visibility} visibility, is not accessible from module `{from}`")?;
1174            }
1175            ErrorKind::MissingMod { item } => {
1176                write!(f, "Missing query meta for module {item}")?;
1177            }
1178            ErrorKind::ImportCycle { .. } => {
1179                write!(f, "Cycle in import")?;
1180            }
1181            ErrorKind::ImportRecursionLimit { count, .. } => {
1182                write!(f, "Import recursion limit reached ({count})")?;
1183            }
1184            ErrorKind::LastUseComponent => {
1185                write!(f, "Missing last use component")?;
1186            }
1187            ErrorKind::RttiConflict { hash } => {
1188                write!(f,"Tried to insert variant runtime type information, but conflicted with hash `{hash}`")?;
1189            }
1190            ErrorKind::TypeRttiConflict { hash } => {
1191                write!(
1192                    f,
1193                    "Tried to insert runtime type information, but conflicted with hash `{hash}`"
1194                )?;
1195            }
1196            ErrorKind::ArenaWriteSliceOutOfBounds { index } => {
1197                write!(f, "Writing arena slice out of bounds for index {index}")?;
1198            }
1199            ErrorKind::ArenaAllocError { requested } => {
1200                write!(f, "Allocation error for {requested} bytes")?;
1201            }
1202            ErrorKind::UnsupportedPatternRest => {
1203                write!(f, "Pattern `..` is not supported in this location")?;
1204            }
1205            ErrorKind::UnsupportedMut => {
1206                write!(
1207                    f,
1208                    "The `mut` modifier is not supported in Rune, everything is mutable by default"
1209                )?;
1210            }
1211            ErrorKind::UnsupportedSuffix => {
1212                write!(
1213                    f,
1214                    "Unsupported suffix, expected one of `u8`, `i64`, `u64`, or `f64`"
1215                )?;
1216            }
1217            ErrorKind::ClosureInConst => {
1218                write!(f, "Closures are not supported in constant contexts")?;
1219            }
1220            ErrorKind::AsyncBlockInConst => {
1221                write!(f, "Async blocks are not supported in constant contexts")?;
1222            }
1223            #[cfg(feature = "fmt")]
1224            ErrorKind::BadSpan { len } => {
1225                write!(f, "Span is outside of source 0-{len}")?;
1226            }
1227            ErrorKind::UnexpectedEndOfSyntax { inside } => {
1228                write!(f, "Unexpected end of syntax while parsing {inside}")?;
1229            }
1230            ErrorKind::UnexpectedEndOfSyntaxWith { inside, expected } => {
1231                write!(
1232                    f,
1233                    "Expected {expected} but got end of syntax while parsing {inside}"
1234                )?;
1235            }
1236            ErrorKind::ExpectedSyntaxEnd { inside, actual } => {
1237                write!(
1238                    f,
1239                    "Expected end of syntax but got {actual} while parsing {inside}"
1240                )?;
1241            }
1242            #[cfg(feature = "fmt")]
1243            ErrorKind::BadIndent { level, indent } => {
1244                write!(f, "Got bad indent {level} with existing {indent}")?;
1245            }
1246            ErrorKind::ExpectedSyntax { expected, actual } => {
1247                write!(f, "Expected {expected} but got {actual}")?;
1248            }
1249            ErrorKind::ExpectedSyntaxIn {
1250                inside,
1251                expected,
1252                actual,
1253            } => {
1254                write!(
1255                    f,
1256                    "Expected {expected} but got {actual} while parsing {inside}"
1257                )?;
1258            }
1259            ErrorKind::ExpectedOne { inside, expected } => {
1260                write!(f, "Expected {expected} while parsing {inside}")?;
1261            }
1262            ErrorKind::ExpectedAtMostOne {
1263                inside,
1264                expected,
1265                count,
1266            } => {
1267                write!(
1268                    f,
1269                    "Expected one {expected} but got {count} of them while parsing {inside}"
1270                )?;
1271            }
1272            ErrorKind::ExpectedAtLeastOne { inside, expected } => {
1273                write!(f, "Expected one {expected} while parsing {inside}")?;
1274            }
1275            #[cfg(feature = "fmt")]
1276            ErrorKind::UnsupportedDelimiter { expectation } => {
1277                write!(f, "Unsupported delimiter {expectation}")?;
1278            }
1279        }
1280
1281        Ok(())
1282    }
1283}
1284
1285struct ParameterizedItem<'a>(&'a Item, &'a [Option<Hash>; 2]);
1286
1287impl fmt::Display for ParameterizedItem<'_> {
1288    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1289        let mut it = self.0.iter();
1290
1291        let (Some(item), Some(ty)) = (it.next_back(), it.next_back()) else {
1292            return self.0.fmt(f);
1293        };
1294
1295        let mut first = false;
1296
1297        for c in it {
1298            if first {
1299                write!(f, "::{c}")?;
1300            } else {
1301                write!(f, "{c}")?;
1302            }
1303
1304            first = true;
1305        }
1306
1307        let [ty_param, item_param] = self.1;
1308
1309        if let Some(ty_param) = ty_param {
1310            write!(f, "::{ty}<{ty_param}>")?;
1311        } else {
1312            write!(f, "::{ty}")?;
1313        }
1314
1315        if let Some(item_param) = item_param {
1316            write!(f, "::{item}<{item_param}>")?;
1317        } else {
1318            write!(f, "::{item}")?;
1319        }
1320
1321        Ok(())
1322    }
1323}
1324
1325impl From<alloc::Error> for Error {
1326    #[inline]
1327    fn from(error: alloc::Error) -> Self {
1328        Error::new(Span::empty(), ErrorKind::AllocError { error })
1329    }
1330}
1331
1332impl From<alloc::Error> for ErrorKind {
1333    #[inline]
1334    fn from(error: alloc::Error) -> Self {
1335        ErrorKind::AllocError { error }
1336    }
1337}
1338
1339impl From<alloc::alloc::AllocError> for Error {
1340    #[inline]
1341    fn from(error: alloc::alloc::AllocError) -> Self {
1342        Self::from(alloc::Error::from(error))
1343    }
1344}
1345
1346impl From<alloc::alloc::AllocError> for ErrorKind {
1347    #[inline]
1348    fn from(error: alloc::alloc::AllocError) -> Self {
1349        Self::from(alloc::Error::from(error))
1350    }
1351}
1352
1353impl From<IrErrorKind> for ErrorKind {
1354    #[inline]
1355    fn from(error: IrErrorKind) -> Self {
1356        ErrorKind::Ir(error)
1357    }
1358}
1359
1360impl From<MetaError> for ErrorKind {
1361    #[inline]
1362    fn from(error: MetaError) -> Self {
1363        ErrorKind::Meta(error)
1364    }
1365}
1366
1367impl From<AccessError> for ErrorKind {
1368    #[inline]
1369    fn from(error: AccessError) -> Self {
1370        ErrorKind::Access(error)
1371    }
1372}
1373
1374impl From<VmError> for ErrorKind {
1375    #[inline]
1376    fn from(error: VmError) -> Self {
1377        ErrorKind::Vm(error)
1378    }
1379}
1380
1381impl From<RuntimeError> for ErrorKind {
1382    #[inline]
1383    fn from(error: RuntimeError) -> Self {
1384        ErrorKind::Vm(VmError::new(error.into_vm_error_kind()))
1385    }
1386}
1387
1388impl From<AnyObjError> for ErrorKind {
1389    #[inline]
1390    fn from(error: AnyObjError) -> Self {
1391        Self::from(RuntimeError::from(error))
1392    }
1393}
1394
1395impl From<EncodeError> for ErrorKind {
1396    #[inline]
1397    fn from(error: EncodeError) -> Self {
1398        ErrorKind::Encode(error)
1399    }
1400}
1401
1402impl From<MissingLastId> for ErrorKind {
1403    #[inline]
1404    fn from(error: MissingLastId) -> Self {
1405        ErrorKind::MissingLastId(error)
1406    }
1407}
1408
1409impl From<GuardMismatch> for ErrorKind {
1410    #[inline]
1411    fn from(error: GuardMismatch) -> Self {
1412        ErrorKind::GuardMismatch(error)
1413    }
1414}
1415
1416impl From<MissingScope> for ErrorKind {
1417    #[inline]
1418    fn from(error: MissingScope) -> Self {
1419        ErrorKind::MissingScope(error)
1420    }
1421}
1422
1423impl From<PopError> for ErrorKind {
1424    #[inline]
1425    fn from(error: PopError) -> Self {
1426        ErrorKind::PopError(error)
1427    }
1428}
1429
1430impl From<unescape::ErrorKind> for ErrorKind {
1431    #[inline]
1432    fn from(source: unescape::ErrorKind) -> Self {
1433        ErrorKind::UnescapeError(source)
1434    }
1435}
1436
1437/// Error when encoding AST.
1438#[derive(Debug)]
1439#[non_exhaustive]
1440pub(crate) enum IrErrorKind {
1441    /// Encountered an expression that is not supported as a constant
1442    /// expression.
1443    NotConst,
1444    /// Trying to process a cycle of constants.
1445    ConstCycle,
1446    /// Encountered a compile meta used in an inappropriate position.
1447    UnsupportedMeta {
1448        /// Unsupported compile meta.
1449        meta: MetaInfo,
1450    },
1451    /// A constant evaluation errored.
1452    Expected {
1453        /// The expected value.
1454        expected: TypeInfo,
1455        /// The value we got instead.
1456        actual: TypeInfo,
1457    },
1458    /// Exceeded evaluation budget.
1459    BudgetExceeded,
1460    /// Missing a tuple index.
1461    MissingIndex {
1462        /// The index that was missing.
1463        index: usize,
1464    },
1465    /// Missing an object field.
1466    MissingField {
1467        /// The field that was missing.
1468        field: Box<str>,
1469    },
1470    /// Error raised when trying to use a break outside of a loop.
1471    BreakOutsideOfLoop,
1472    ArgumentCountMismatch {
1473        actual: usize,
1474        expected: usize,
1475    },
1476}
1477
1478impl core::error::Error for IrErrorKind {}
1479
1480impl fmt::Display for IrErrorKind {
1481    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1482        match self {
1483            IrErrorKind::NotConst => {
1484                write!(f, "Expected a constant expression")?;
1485            }
1486            IrErrorKind::ConstCycle => {
1487                write!(f, "Constant cycle detected")?;
1488            }
1489            IrErrorKind::UnsupportedMeta { meta } => {
1490                write!(f, "Item `{meta}` is not supported here",)?
1491            }
1492            IrErrorKind::Expected { expected, actual } => {
1493                write!(f, "Expected a value of type {expected} but got {actual}",)?
1494            }
1495            IrErrorKind::BudgetExceeded => {
1496                write!(f, "Evaluation budget exceeded")?;
1497            }
1498            IrErrorKind::MissingIndex { index } => {
1499                write!(f, "Missing index {index}")?;
1500            }
1501            IrErrorKind::MissingField { field } => {
1502                write!(f, "Missing field `{field}`")?;
1503            }
1504            IrErrorKind::BreakOutsideOfLoop => {
1505                write!(f, "Break outside of supported loop")?;
1506            }
1507            IrErrorKind::ArgumentCountMismatch { actual, expected } => {
1508                write!(
1509                    f,
1510                    "Argument count mismatch, got {actual} but expected {expected}",
1511                )?;
1512            }
1513        }
1514
1515        Ok(())
1516    }
1517}
1518
1519/// A single step in an import.
1520///
1521/// This is used to indicate a step in an import chain in an error message.
1522#[derive(Debug, TryClone)]
1523#[non_exhaustive]
1524pub struct ImportStep {
1525    /// The location of the import.
1526    pub location: Location,
1527    /// The item being imported.
1528    pub item: ItemBuf,
1529}
1530
1531/// A meta error.
1532#[derive(Debug)]
1533pub struct MetaError {
1534    kind: rust_alloc::boxed::Box<MetaErrorKind>,
1535}
1536
1537impl MetaError {
1538    /// Construct a new meta error.
1539    pub(crate) fn new<E>(kind: E) -> Self
1540    where
1541        MetaErrorKind: From<E>,
1542    {
1543        Self {
1544            kind: rust_alloc::boxed::Box::new(kind.into()),
1545        }
1546    }
1547}
1548
1549impl From<alloc::Error> for MetaError {
1550    #[inline]
1551    fn from(error: alloc::Error) -> Self {
1552        Self::new(MetaErrorKind::AllocError { error })
1553    }
1554}
1555
1556impl From<alloc::alloc::AllocError> for MetaError {
1557    #[inline]
1558    fn from(error: alloc::alloc::AllocError) -> Self {
1559        Self::from(alloc::Error::from(error))
1560    }
1561}
1562
1563#[derive(Debug)]
1564/// Tried to add an item that already exists.
1565pub(crate) enum MetaErrorKind {
1566    AllocError {
1567        error: alloc::Error,
1568    },
1569    MetaConflict {
1570        /// The meta we tried to insert.
1571        current: MetaInfo,
1572        /// The existing item.
1573        existing: MetaInfo,
1574        /// Parameters hash.
1575        parameters: Hash,
1576    },
1577}
1578
1579impl fmt::Display for MetaError {
1580    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1581        match &*self.kind {
1582            MetaErrorKind::AllocError { error } => error.fmt(f),
1583            MetaErrorKind::MetaConflict {
1584                current,
1585                existing,
1586                parameters,
1587            } => {
1588                write!(f, "Can't insert item `{current}` ({parameters}) because conflicting meta `{existing}` already exists")
1589            }
1590        }
1591    }
1592}
1593
1594impl core::error::Error for MetaError {}
1595
1596#[derive(Debug)]
1597pub(crate) struct MissingScope(pub(crate) usize);
1598
1599impl fmt::Display for MissingScope {
1600    #[inline]
1601    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1602        write!(f, "Missing scope with id {}", self.0)
1603    }
1604}
1605
1606impl core::error::Error for MissingScope {}
1607
1608#[derive(Debug)]
1609pub(crate) enum PopError {
1610    MissingScope(usize),
1611    MissingParentScope(usize),
1612}
1613
1614impl fmt::Display for PopError {
1615    #[inline]
1616    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1617        match self {
1618            PopError::MissingScope(id) => write!(f, "Missing scope with id {id}"),
1619            PopError::MissingParentScope(id) => write!(f, "Missing parent scope with id {id}"),
1620        }
1621    }
1622}
1623
1624impl core::error::Error for PopError {}