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