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