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