use core::convert::Infallible;
use core::fmt;
#[cfg(feature = "std")]
use std::io;
#[cfg(feature = "std")]
use std::path::PathBuf;
use crate as rune;
use crate::alloc::prelude::*;
use crate::alloc::{self, Box, String, Vec};
use crate::ast;
use crate::ast::unescape;
use crate::ast::{Span, Spanned};
use crate::compile::ir;
use crate::compile::{HasSpan, Location, MetaInfo, Visibility};
use crate::hash::TooManyParameters;
use crate::indexing::items::{GuardMismatch, MissingLastId};
use crate::macros::{SyntheticId, SyntheticKind};
use crate::parse::{Expectation, IntoExpectation, LexerMode};
use crate::runtime::debug::DebugSignature;
use crate::runtime::unit::EncodeError;
use crate::runtime::{AccessError, AnyObjError, RuntimeError, TypeInfo, TypeOf, VmError};
#[cfg(feature = "std")]
use crate::source;
use crate::{Hash, Item, ItemBuf, SourceId};
#[derive(Debug)]
pub struct Error {
span: Span,
kind: rust_alloc::boxed::Box<ErrorKind>,
}
impl Error {
pub(crate) fn new<S, K>(span: S, kind: K) -> Self
where
S: Spanned,
ErrorKind: From<K>,
{
Self {
span: span.span(),
kind: rust_alloc::boxed::Box::new(ErrorKind::from(kind)),
}
}
pub fn msg<S, M>(span: S, message: M) -> Self
where
S: Spanned,
M: fmt::Display + fmt::Debug + Send + Sync + 'static,
{
Self {
span: span.span(),
kind: rust_alloc::boxed::Box::new(ErrorKind::msg(message)),
}
}
#[cfg(feature = "emit")]
pub(crate) fn kind(&self) -> &ErrorKind {
&self.kind
}
#[cfg(test)]
pub(crate) fn into_kind(self) -> ErrorKind {
*self.kind
}
}
impl Spanned for Error {
#[inline]
fn span(&self) -> Span {
self.span
}
}
impl core::error::Error for Error {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
self.kind.source()
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.kind, f)
}
}
impl From<Infallible> for Error {
#[inline]
fn from(value: Infallible) -> Self {
match value {}
}
}
impl<S, E> From<HasSpan<S, E>> for Error
where
S: Spanned,
ErrorKind: From<E>,
{
fn from(spanned: HasSpan<S, E>) -> Self {
Self::new(spanned.span(), spanned.into_inner())
}
}
impl From<TooManyParameters> for ErrorKind {
#[inline]
fn from(error: TooManyParameters) -> Self {
ErrorKind::TooManyParameters(error)
}
}
impl From<fmt::Error> for ErrorKind {
#[inline]
fn from(fmt::Error: fmt::Error) -> Self {
ErrorKind::FormatError
}
}
impl From<syntree::Error<alloc::Error>> for ErrorKind {
#[inline]
fn from(error: syntree::Error<alloc::Error>) -> Self {
ErrorKind::Syntree(error)
}
}
#[cfg(feature = "std")]
impl From<io::Error> for ErrorKind {
#[inline]
fn from(error: io::Error) -> Self {
Self::from(anyhow::Error::from(error))
}
}
impl From<ir::scopes::MissingLocal> for ErrorKind {
#[inline]
fn from(error: ir::scopes::MissingLocal) -> Self {
ErrorKind::MissingLocal { name: error.0 }
}
}
impl From<anyhow::Error> for ErrorKind {
#[inline]
fn from(error: anyhow::Error) -> Self {
ErrorKind::Custom { error }
}
}
impl From<&'static str> for ErrorKind {
#[inline]
fn from(value: &'static str) -> Self {
ErrorKind::msg(value)
}
}
impl<T> From<Box<T>> for ErrorKind
where
ErrorKind: From<T>,
{
#[inline]
fn from(kind: Box<T>) -> Self {
ErrorKind::from(Box::into_inner(kind))
}
}
impl<T> From<rust_alloc::boxed::Box<T>> for ErrorKind
where
ErrorKind: From<T>,
{
#[inline]
fn from(kind: rust_alloc::boxed::Box<T>) -> Self {
ErrorKind::from(*kind)
}
}
impl From<alloc::Error> for rust_alloc::boxed::Box<ErrorKind> {
#[inline]
fn from(error: alloc::Error) -> Self {
rust_alloc::boxed::Box::new(ErrorKind::from(error))
}
}
impl Error {
pub fn expected_meta<S>(spanned: S, meta: MetaInfo, expected: &'static str) -> Self
where
S: Spanned,
{
Self::new(spanned, ErrorKind::ExpectedMeta { meta, expected })
}
pub(crate) fn expected<A, E>(actual: A, expected: E) -> Self
where
A: IntoExpectation + Spanned,
E: IntoExpectation,
{
Self::new(
actual.span(),
ErrorKind::Expected {
actual: actual.into_expectation(),
expected: expected.into_expectation(),
},
)
}
pub(crate) fn unsupported<T, E>(actual: T, what: E) -> Self
where
T: Spanned,
E: IntoExpectation,
{
Self::new(
actual.span(),
ErrorKind::Unsupported {
what: what.into_expectation(),
},
)
}
pub(crate) fn expected_type<E>(spanned: impl Spanned, actual: TypeInfo) -> Self
where
E: TypeOf,
{
Self::new(
spanned,
IrErrorKind::Expected {
expected: TypeInfo::from(E::STATIC_TYPE_INFO),
actual,
},
)
}
}
#[derive(Debug)]
#[non_exhaustive]
pub(crate) enum ErrorKind {
Custom {
error: anyhow::Error,
},
AllocError {
error: alloc::Error,
},
IrError(IrErrorKind),
MetaError(MetaError),
AccessError(AccessError),
VmError(VmError),
EncodeError(EncodeError),
MissingLastId(MissingLastId),
GuardMismatch(GuardMismatch),
MissingScope(MissingScope),
PopError(PopError),
UnescapeError(unescape::ErrorKind),
Syntree(syntree::Error<alloc::Error>),
TooManyParameters(TooManyParameters),
FormatError,
#[cfg(feature = "std")]
SourceError {
path: PathBuf,
error: source::FromPathError,
},
Expected {
actual: Expectation,
expected: Expectation,
},
Unsupported {
what: Expectation,
},
#[cfg(feature = "std")]
ModNotFound {
path: PathBuf,
},
ModAlreadyLoaded {
item: ItemBuf,
#[cfg(feature = "emit")]
existing: (SourceId, Span),
},
MissingMacro {
item: ItemBuf,
},
MissingSelf,
MissingLocal {
name: Box<str>,
},
MissingItem {
item: ItemBuf,
},
MissingItemHash {
hash: Hash,
},
MissingItemParameters {
item: ItemBuf,
parameters: [Option<Hash>; 2],
},
UnsupportedGlobal,
UnsupportedModuleSource,
#[cfg(feature = "std")]
UnsupportedModuleRoot {
root: PathBuf,
},
#[cfg(feature = "std")]
UnsupportedModuleItem {
item: ItemBuf,
},
UnsupportedSelf,
UnsupportedUnaryOp {
op: ast::UnOp,
},
UnsupportedBinaryOp {
op: ast::BinOp,
},
UnsupportedLitObject {
meta: MetaInfo,
},
LitObjectMissingField {
field: Box<str>,
item: ItemBuf,
},
LitObjectNotField {
field: Box<str>,
item: ItemBuf,
},
UnsupportedAssignExpr,
UnsupportedBinaryExpr,
UnsupportedRef,
BadArgumentCount {
expected: usize,
actual: usize,
},
UnsupportedPatternExpr,
UnsupportedBinding,
DuplicateObjectKey {
#[cfg(feature = "emit")]
existing: Span,
#[cfg(feature = "emit")]
object: Span,
},
InstanceFunctionOutsideImpl,
UnsupportedTupleIndex {
number: ast::Number,
},
BreakUnsupported,
BreakUnsupportedValue,
ContinueUnsupported,
ContinueUnsupportedBlock,
SelectMultipleDefaults,
ExpectedBlockSemiColon {
#[cfg(feature = "emit")]
followed_span: Span,
},
FnConstAsyncConflict,
BlockConstAsyncConflict,
ClosureKind,
UnsupportedSelfType,
UnsupportedSuper,
UnsupportedSuperInSelfType,
UnsupportedAfterGeneric,
IllegalUseSegment,
UseAliasNotSupported,
FunctionConflict {
existing: DebugSignature,
},
FunctionReExportConflict {
hash: Hash,
},
ConstantConflict {
hash: Hash,
},
StaticStringMissing {
hash: Hash,
slot: usize,
},
StaticBytesMissing {
hash: Hash,
slot: usize,
},
StaticStringHashConflict {
hash: Hash,
current: String,
existing: String,
},
StaticBytesHashConflict {
hash: Hash,
current: Vec<u8>,
existing: Vec<u8>,
},
StaticObjectKeysMissing {
hash: Hash,
slot: usize,
},
StaticObjectKeysHashConflict {
hash: Hash,
current: Box<[String]>,
existing: Box<[String]>,
},
ConflictingLabels {
#[cfg_attr(not(feature = "emit"), allow(unused))]
existing: Span,
},
DuplicateSelectDefault {
#[cfg_attr(not(feature = "emit"), allow(unused))]
existing: Span,
},
MissingLabel {
label: Box<str>,
},
ExpectedLeadingPathSegment,
UnsupportedVisibility,
ExpectedMeta {
expected: &'static str,
meta: MetaInfo,
},
NoSuchBuiltInMacro {
name: Box<str>,
},
VariableMoved {
#[cfg(feature = "emit")]
moved_at: Span,
},
UnsupportedGenerics,
NestedTest {
#[cfg(feature = "emit")]
nested_span: Span,
},
NestedBench {
#[cfg(feature = "emit")]
nested_span: Span,
},
MissingFunctionHash {
hash: Hash,
},
FunctionConflictHash {
hash: Hash,
},
PatternMissingFields {
item: ItemBuf,
#[cfg(feature = "emit")]
fields: Box<[Box<str>]>,
},
MissingLabelLocation {
name: &'static str,
index: usize,
},
MaxMacroRecursion {
depth: usize,
max: usize,
},
YieldInConst,
AwaitInConst,
AwaitOutsideAsync,
ExpectedEof {
actual: ast::Kind,
},
UnexpectedEof,
BadLexerMode {
actual: LexerMode,
expected: LexerMode,
},
ExpectedEscape,
UnterminatedStrLit,
UnterminatedByteStrLit,
UnterminatedCharLit,
UnterminatedByteLit,
ExpectedCharClose,
ExpectedCharOrLabel,
ExpectedByteClose,
UnexpectedChar {
c: char,
},
PrecedenceGroupRequired,
BadSignedOutOfBounds {
size: ast::NumberSize,
},
BadUnsignedOutOfBounds {
size: ast::NumberSize,
},
BadFieldAccess,
ExpectedMacroCloseDelimiter {
expected: ast::Kind,
actual: ast::Kind,
},
MultipleMatchingAttributes {
name: &'static str,
},
MissingSourceId {
source_id: SourceId,
},
ExpectedMultilineCommentTerm,
BadSlice,
BadSyntheticId {
kind: SyntheticKind,
id: SyntheticId,
},
BadCharLiteral,
BadByteLiteral,
BadNumberLiteral,
AmbiguousItem {
item: ItemBuf,
#[cfg(feature = "emit")]
locations: Vec<(Location, ItemBuf)>,
},
AmbiguousContextItem {
item: ItemBuf,
#[cfg(feature = "emit")]
infos: Box<[MetaInfo]>,
},
NotVisible {
#[cfg(feature = "emit")]
chain: Vec<Location>,
#[cfg(feature = "emit")]
location: Location,
visibility: Visibility,
item: ItemBuf,
from: ItemBuf,
},
NotVisibleMod {
#[cfg(feature = "emit")]
chain: Vec<Location>,
#[cfg(feature = "emit")]
location: Location,
visibility: Visibility,
item: ItemBuf,
from: ItemBuf,
},
MissingMod {
item: ItemBuf,
},
ImportCycle {
#[cfg(feature = "emit")]
path: Vec<ImportStep>,
},
ImportRecursionLimit {
count: usize,
#[allow(unused)]
path: Vec<ImportStep>,
},
LastUseComponent,
RttiConflict {
hash: Hash,
},
TypeRttiConflict {
hash: Hash,
},
ArenaWriteSliceOutOfBounds {
index: usize,
},
ArenaAllocError {
requested: usize,
},
UnsupportedPatternRest,
UnsupportedMut,
UnsupportedSuffix,
ClosureInConst,
AsyncBlockInConst,
#[cfg(feature = "fmt")]
BadSpan {
len: usize,
},
UnexpectedEndOfSyntax {
inside: Expectation,
},
UnexpectedEndOfSyntaxWith {
inside: Expectation,
expected: Expectation,
},
ExpectedSyntaxEnd {
inside: Expectation,
actual: Expectation,
},
#[cfg(feature = "fmt")]
BadIndent {
level: isize,
indent: usize,
},
ExpectedSyntax {
expected: Expectation,
actual: Expectation,
},
ExpectedSyntaxIn {
inside: Expectation,
expected: Expectation,
actual: Expectation,
},
ExpectedOne {
inside: Expectation,
expected: Expectation,
},
ExpectedAtMostOne {
inside: Expectation,
expected: Expectation,
count: usize,
},
ExpectedAtLeastOne {
inside: Expectation,
expected: Expectation,
},
#[cfg(feature = "fmt")]
UnsupportedDelimiter {
expectation: Expectation,
},
}
impl ErrorKind {
pub(crate) fn msg<M>(message: M) -> Self
where
M: fmt::Display + fmt::Debug + Send + Sync + 'static,
{
Self::Custom {
error: anyhow::Error::msg(message),
}
}
}
impl core::error::Error for ErrorKind {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match self {
ErrorKind::Custom { error } => Some(error.as_ref()),
ErrorKind::IrError(source) => Some(source),
ErrorKind::MetaError(source) => Some(source),
ErrorKind::AccessError(source) => Some(source),
ErrorKind::VmError(source) => Some(source),
ErrorKind::EncodeError(source) => Some(source),
ErrorKind::MissingLastId(source) => Some(source),
ErrorKind::GuardMismatch(source) => Some(source),
ErrorKind::MissingScope(source) => Some(source),
ErrorKind::PopError(source) => Some(source),
ErrorKind::UnescapeError(source) => Some(source),
#[cfg(feature = "std")]
ErrorKind::SourceError { error, .. } => Some(error),
_ => None,
}
}
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ErrorKind::Custom { error } => {
error.fmt(f)?;
}
ErrorKind::AllocError { error } => {
error.fmt(f)?;
}
ErrorKind::IrError(error) => {
error.fmt(f)?;
}
ErrorKind::MetaError(error) => {
error.fmt(f)?;
}
ErrorKind::AccessError(error) => {
error.fmt(f)?;
}
ErrorKind::VmError(error) => {
error.fmt(f)?;
}
ErrorKind::EncodeError(error) => {
error.fmt(f)?;
}
ErrorKind::MissingLastId(error) => {
error.fmt(f)?;
}
ErrorKind::GuardMismatch(error) => {
error.fmt(f)?;
}
ErrorKind::MissingScope(error) => {
error.fmt(f)?;
}
ErrorKind::PopError(error) => {
error.fmt(f)?;
}
ErrorKind::UnescapeError(error) => {
error.fmt(f)?;
}
ErrorKind::Syntree(error) => {
error.fmt(f)?;
}
ErrorKind::TooManyParameters(error) => {
error.fmt(f)?;
}
ErrorKind::FormatError => {
write!(f, "Formatting error")?;
}
#[cfg(feature = "std")]
ErrorKind::SourceError { path, error } => {
write!(
f,
"Failed to load source at `{path}`: {error}",
path = path.display(),
)?;
}
ErrorKind::Expected { actual, expected } => {
write!(f, "Expected {expected} but got {actual}")?;
}
ErrorKind::Unsupported { what } => {
write!(f, "Unsupported {what}")?;
}
#[cfg(feature = "std")]
ErrorKind::ModNotFound { path } => {
write!(
f,
"File not found, expected a module file like `{path}.rn`",
path = path.display()
)?;
}
ErrorKind::ModAlreadyLoaded { item, .. } => {
write!(f, "Module `{item}` has already been loaded")?;
}
ErrorKind::MissingMacro { item } => {
write!(f, "Missing macro {item}")?;
}
ErrorKind::MissingSelf => write!(f, "No `self` in current context")?,
ErrorKind::MissingLocal { name } => {
write!(f, "No local variable `{name}`")?;
}
ErrorKind::MissingItem { item } => {
write!(f, "Missing item {item}")?;
}
ErrorKind::MissingItemHash { hash } => {
write!(
f,
"Tried to insert meta with hash `{hash}` which does not have an item",
)?;
}
ErrorKind::MissingItemParameters { item, parameters } => {
write!(f, "Missing item {}", ParameterizedItem(item, parameters))?;
}
ErrorKind::UnsupportedGlobal => {
write!(f, "Unsupported crate prefix `::`")?;
}
ErrorKind::UnsupportedModuleSource => {
write!(
f,
"Cannot load modules using a source without an associated URL"
)?;
}
#[cfg(feature = "std")]
ErrorKind::UnsupportedModuleRoot { root } => {
write!(
f,
"Cannot load modules relative to `{root}`",
root = root.display()
)?;
}
#[cfg(feature = "std")]
ErrorKind::UnsupportedModuleItem { item } => {
write!(f, "Cannot load module for `{item}`")?;
}
ErrorKind::UnsupportedSelf => {
write!(f, "Keyword `self` not supported here")?;
}
ErrorKind::UnsupportedUnaryOp { op } => {
write!(f, "Unsupported unary operator `{op}`")?;
}
ErrorKind::UnsupportedBinaryOp { op } => {
write!(f, "Unsupported binary operator `{op}`")?;
}
ErrorKind::UnsupportedLitObject { meta } => {
write!(f, "Item `{meta}` is not an object")?;
}
ErrorKind::LitObjectMissingField { field, item } => {
write!(f, "Missing field `{field}` in declaration of `{item}`")?;
}
ErrorKind::LitObjectNotField { field, item } => {
write!(f, "Field `{field}` is not a field in `{item}`")?;
}
ErrorKind::UnsupportedAssignExpr => {
write!(f, "Cannot assign to expression")?;
}
ErrorKind::UnsupportedBinaryExpr => {
write!(f, "Unsupported binary expression")?;
}
ErrorKind::UnsupportedRef => {
write!(f, "Cannot take reference of expression")?;
}
ErrorKind::BadArgumentCount { expected, actual } => {
write!(f, "Wrong number of arguments {actual}, expected {expected}",)?;
}
ErrorKind::UnsupportedPatternExpr => {
write!(f, "This kind of expression is not supported as a pattern")?;
}
ErrorKind::UnsupportedBinding => {
write!(f, "Not a valid binding")?;
}
ErrorKind::DuplicateObjectKey { .. } => {
write!(f, "Duplicate key in literal object")?;
}
ErrorKind::InstanceFunctionOutsideImpl => {
write!(f, "Instance function declared outside of `impl` block")?;
}
ErrorKind::UnsupportedTupleIndex { number } => {
write!(f, "Unsupported tuple index `{number}`")?;
}
ErrorKind::BreakUnsupported => {
write!(f, "Break outside of loop")?;
}
ErrorKind::BreakUnsupportedValue => {
write!(
f,
"Can only break with a value inside `loop` or breakable block"
)?;
}
ErrorKind::ContinueUnsupported => {
write!(f, "Continue outside of loop")?;
}
ErrorKind::ContinueUnsupportedBlock => {
write!(f, "Labeled blocks cannot be `continue`'d")?;
}
ErrorKind::SelectMultipleDefaults => {
write!(f, "Multiple `default` branches in select")?;
}
ErrorKind::ExpectedBlockSemiColon { .. } => {
write!(f, "Expected expression to be terminated by a semicolon `;`")?;
}
ErrorKind::FnConstAsyncConflict => {
write!(
f,
"An `fn` can't both be `async` and `const` at the same time"
)?;
}
ErrorKind::BlockConstAsyncConflict => {
write!(
f,
"A block can't both be `async` and `const` at the same time"
)?;
}
ErrorKind::ClosureKind => {
write!(f, "Unsupported closure kind")?;
}
ErrorKind::UnsupportedSelfType => {
write!(
f,
"Keyword `Self` is only supported inside of `impl` blocks"
)?;
}
ErrorKind::UnsupportedSuper => {
write!(
f,
"Keyword `super` is not supported at the root module level"
)?;
}
ErrorKind::UnsupportedSuperInSelfType => {
write!(
f,
"Keyword `super` can't be used in paths starting with `Self`"
)?;
}
ErrorKind::UnsupportedAfterGeneric => {
write!(
f,
"This kind of path component cannot follow a generic argument"
)?;
}
ErrorKind::IllegalUseSegment => {
write!(
f,
"Another segment can't follow wildcard `*` or group imports"
)?;
}
ErrorKind::UseAliasNotSupported => {
write!(
f,
"Use aliasing is not supported for wildcard `*` or group imports"
)?;
}
ErrorKind::FunctionConflict { existing } => {
write!(
f,
"Conflicting function signature already exists `{existing}`",
)?;
}
ErrorKind::FunctionReExportConflict { hash } => {
write!(f, "Conflicting function hash already exists `{hash}`")?;
}
ErrorKind::ConstantConflict { hash } => {
write!(f, "Conflicting constant for hash `{hash}`")?;
}
ErrorKind::StaticStringMissing { hash, slot } => {
write!(
f,
"Missing static string for hash `{hash}` and slot `{slot}`",
)?;
}
ErrorKind::StaticBytesMissing { hash, slot } => {
write!(
f,
"Missing static byte string for hash `{hash}` and slot `{slot}`",
)?;
}
ErrorKind::StaticStringHashConflict {
hash,
current,
existing,
} => {
write!(f,"Conflicting static string for hash `{hash}` between `{existing:?}` and `{current:?}`")?;
}
ErrorKind::StaticBytesHashConflict {
hash,
current,
existing,
} => {
write!(f,"Conflicting static string for hash `{hash}` between `{existing:?}` and `{current:?}`")?;
}
ErrorKind::StaticObjectKeysMissing { hash, slot } => {
write!(
f,
"Missing static object keys for hash `{hash}` and slot `{slot}`",
hash = hash,
slot = slot
)?;
}
ErrorKind::StaticObjectKeysHashConflict {
hash,
current,
existing,
} => {
write!(f,"Conflicting static object keys for hash `{hash}` between `{existing:?}` and `{current:?}`")?;
}
ErrorKind::ConflictingLabels { .. } => {
write!(f, "Multiple labels provided")?;
}
ErrorKind::DuplicateSelectDefault { .. } => {
write!(f, "Multiple default select branches")?;
}
ErrorKind::MissingLabel { label } => {
write!(f, "Missing label '{label}")?;
}
ErrorKind::ExpectedLeadingPathSegment => {
write!(f, "Segment is only supported in the first position")?;
}
ErrorKind::UnsupportedVisibility => {
write!(f, "Visibility modifier not supported")?;
}
ErrorKind::ExpectedMeta { expected, meta } => {
write!(f, "Expected {expected} but got `{meta}`")?;
}
ErrorKind::NoSuchBuiltInMacro { name } => {
write!(f, "No such built-in macro `{name}`")?;
}
ErrorKind::VariableMoved { .. } => {
write!(f, "Variable moved")?;
}
ErrorKind::UnsupportedGenerics => {
write!(f, "Unsupported generic argument")?;
}
ErrorKind::NestedTest { .. } => {
write!(f, "Attribute `#[test]` is not supported on nested items")?;
}
ErrorKind::NestedBench { .. } => {
write!(f, "Attribute `#[bench]` is not supported on nested items")?;
}
ErrorKind::MissingFunctionHash { hash } => {
write!(f, "Missing function with hash `{hash}`")?;
}
ErrorKind::FunctionConflictHash { hash } => {
write!(f, "Conflicting function already exists `{hash}`")?;
}
ErrorKind::PatternMissingFields { item, .. } => {
write!(f, "Non-exhaustive pattern for `{item}`")?;
}
ErrorKind::MissingLabelLocation { name, index } => {
write!(
f,
"Use of label `{name}_{index}` which has no code location",
)?;
}
ErrorKind::MaxMacroRecursion { depth, max } => {
write!(
f,
"Reached macro recursion limit at {depth}, limit is {max}",
)?;
}
ErrorKind::YieldInConst => {
write!(f, "Expression `yield` inside of constant function")?;
}
ErrorKind::AwaitInConst => {
write!(f, "Expression `.await` inside of constant context")?;
}
ErrorKind::AwaitOutsideAsync => {
write!(f, "Expression `.await` outside of async function or block")?;
}
ErrorKind::ExpectedEof { actual } => {
write!(f, "Expected end of file, but got {actual}")?;
}
ErrorKind::UnexpectedEof => {
write!(f, "Unexpected end of file")?;
}
ErrorKind::BadLexerMode { actual, expected } => {
write!(f, "Bad lexer mode `{actual}`, expected `{expected}`")?;
}
ErrorKind::ExpectedEscape => {
write!(f, "Expected escape sequence")?;
}
ErrorKind::UnterminatedStrLit => {
write!(f, "Unterminated string literal")?;
}
ErrorKind::UnterminatedByteStrLit => {
write!(f, "Unterminated byte string literal")?;
}
ErrorKind::UnterminatedCharLit => {
write!(f, "Unterminated character literal")?;
}
ErrorKind::UnterminatedByteLit => {
write!(f, "Unterminated byte literal")?;
}
ErrorKind::ExpectedCharClose => {
write!(f, "Expected character literal to be closed")?;
}
ErrorKind::ExpectedCharOrLabel => {
write!(f, "Expected label or character")?;
}
ErrorKind::ExpectedByteClose => {
write!(f, "Expected byte literal to be closed")?;
}
ErrorKind::UnexpectedChar { c } => {
write!(f, "Unexpected character `{c}`", c = c)?;
}
ErrorKind::PrecedenceGroupRequired => {
write!(f, "Group required in expression to determine precedence")?;
}
ErrorKind::BadSignedOutOfBounds { size } => {
write!(
f,
"Number literal out of bounds `{}` to `{}`",
size.signed_min(),
size.signed_max(),
)?;
}
ErrorKind::BadUnsignedOutOfBounds { size } => {
write!(
f,
"Number literal out of bounds `{}` to `{}`",
size.unsigned_min(),
size.unsigned_max(),
)?;
}
ErrorKind::BadFieldAccess => {
write!(f, "Unsupported field access")?;
}
ErrorKind::ExpectedMacroCloseDelimiter { expected, actual } => {
write!(f, "Expected close delimiter {expected}, but got {actual}")?;
}
ErrorKind::MultipleMatchingAttributes { name } => {
write!(f, "Can only specify one attribute named `{name}`")?;
}
ErrorKind::MissingSourceId { source_id } => {
write!(f, "Missing source id `{source_id}`")?;
}
ErrorKind::ExpectedMultilineCommentTerm => {
write!(f, "Expected multiline comment to be terminated with a `*/`")?;
}
ErrorKind::BadSlice => {
write!(f, "Tried to read bad slice from source")?;
}
ErrorKind::BadSyntheticId { kind, id } => {
write!(
f,
"Tried to get bad synthetic identifier `{id}` for `{kind}`",
)?;
}
ErrorKind::BadCharLiteral => {
write!(f, "Bad character literal")?;
}
ErrorKind::BadByteLiteral => {
write!(f, "Bad byte literal")?;
}
ErrorKind::BadNumberLiteral => {
write!(f, "Number literal not valid")?;
}
ErrorKind::AmbiguousItem { item, .. } => {
write!(f, "Item `{item}` can refer to multiple things")?;
}
ErrorKind::AmbiguousContextItem { item, .. } => {
write!(
f,
"Item `{item}` can refer to multiple things from the context"
)?;
}
ErrorKind::NotVisible {
visibility,
item,
from,
..
} => {
write!(f,"Item `{item}` with visibility `{visibility}`, is not accessible from module `{from}`")?;
}
ErrorKind::NotVisibleMod {
visibility,
item,
from,
..
} => {
write!(f,"Module `{item}` with {visibility} visibility, is not accessible from module `{from}`")?;
}
ErrorKind::MissingMod { item } => {
write!(f, "Missing query meta for module {item}")?;
}
ErrorKind::ImportCycle { .. } => {
write!(f, "Cycle in import")?;
}
ErrorKind::ImportRecursionLimit { count, .. } => {
write!(f, "Import recursion limit reached ({count})", count = count)?;
}
ErrorKind::LastUseComponent => {
write!(f, "Missing last use component")?;
}
ErrorKind::RttiConflict { hash } => {
write!(f,"Tried to insert variant runtime type information, but conflicted with hash `{hash}`")?;
}
ErrorKind::TypeRttiConflict { hash } => {
write!(
f,
"Tried to insert runtime type information, but conflicted with hash `{hash}`",
hash = hash
)?;
}
ErrorKind::ArenaWriteSliceOutOfBounds { index } => {
write!(
f,
"Writing arena slice out of bounds for index {index}",
index = index
)?;
}
ErrorKind::ArenaAllocError { requested } => {
write!(f, "Allocation error for {requested} bytes")?;
}
ErrorKind::UnsupportedPatternRest => {
write!(f, "Pattern `..` is not supported in this location")?;
}
ErrorKind::UnsupportedMut => {
write!(
f,
"The `mut` modifier is not supported in Rune, everything is mutable by default"
)?;
}
ErrorKind::UnsupportedSuffix => {
write!(
f,
"Unsupported suffix, expected one of `u8`, `i64`, `u64`, or `f64`"
)?;
}
ErrorKind::ClosureInConst => {
write!(f, "Closures are not supported in constant contexts")?;
}
ErrorKind::AsyncBlockInConst => {
write!(f, "Async blocks are not supported in constant contexts")?;
}
#[cfg(feature = "fmt")]
ErrorKind::BadSpan { len } => {
write!(f, "Span is outside of source 0-{len}")?;
}
ErrorKind::UnexpectedEndOfSyntax { inside } => {
write!(f, "Unexpected end of syntax while parsing {inside}")?;
}
ErrorKind::UnexpectedEndOfSyntaxWith { inside, expected } => {
write!(
f,
"Expected {expected} but got end of syntax while parsing {inside}"
)?;
}
ErrorKind::ExpectedSyntaxEnd { inside, actual } => {
write!(
f,
"Expected end of syntax but got {actual} while parsing {inside}"
)?;
}
#[cfg(feature = "fmt")]
ErrorKind::BadIndent { level, indent } => {
write!(f, "Got bad indent {level} with existing {indent}")?;
}
ErrorKind::ExpectedSyntax { expected, actual } => {
write!(f, "Expected {expected} but got {actual}")?;
}
ErrorKind::ExpectedSyntaxIn {
inside,
expected,
actual,
} => {
write!(
f,
"Expected {expected} but got {actual} while parsing {inside}"
)?;
}
ErrorKind::ExpectedOne { inside, expected } => {
write!(f, "Expected {expected} while parsing {inside}")?;
}
ErrorKind::ExpectedAtMostOne {
inside,
expected,
count,
} => {
write!(
f,
"Expected one {expected} but got {count} of them while parsing {inside}"
)?;
}
ErrorKind::ExpectedAtLeastOne { inside, expected } => {
write!(f, "Expected one {expected} while parsing {inside}")?;
}
#[cfg(feature = "fmt")]
ErrorKind::UnsupportedDelimiter { expectation } => {
write!(f, "Unsupported delimiter {expectation}")?;
}
}
Ok(())
}
}
struct ParameterizedItem<'a>(&'a Item, &'a [Option<Hash>; 2]);
impl fmt::Display for ParameterizedItem<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut it = self.0.iter();
let (Some(item), Some(ty)) = (it.next_back(), it.next_back()) else {
return self.0.fmt(f);
};
let base = it.as_item();
let [ty_param, item_param] = self.1;
write!(f, "{base}")?;
if let Some(ty_param) = ty_param {
write!(f, "::{ty}<{ty_param}>")?;
} else {
write!(f, "::{ty}")?;
}
if let Some(item_param) = item_param {
write!(f, "::{item}<{item_param}>")?;
} else {
write!(f, "::{item}")?;
}
Ok(())
}
}
impl From<alloc::Error> for Error {
#[inline]
fn from(error: alloc::Error) -> Self {
Error::new(Span::empty(), ErrorKind::AllocError { error })
}
}
impl From<alloc::Error> for ErrorKind {
#[inline]
fn from(error: alloc::Error) -> Self {
ErrorKind::AllocError { error }
}
}
impl From<alloc::alloc::AllocError> for Error {
#[inline]
fn from(error: alloc::alloc::AllocError) -> Self {
Self::from(alloc::Error::from(error))
}
}
impl From<alloc::alloc::AllocError> for ErrorKind {
#[inline]
fn from(error: alloc::alloc::AllocError) -> Self {
Self::from(alloc::Error::from(error))
}
}
impl From<IrErrorKind> for ErrorKind {
#[inline]
fn from(error: IrErrorKind) -> Self {
ErrorKind::IrError(error)
}
}
impl From<MetaError> for ErrorKind {
#[inline]
fn from(error: MetaError) -> Self {
ErrorKind::MetaError(error)
}
}
impl From<AccessError> for ErrorKind {
#[inline]
fn from(error: AccessError) -> Self {
ErrorKind::AccessError(error)
}
}
impl From<VmError> for ErrorKind {
#[inline]
fn from(error: VmError) -> Self {
ErrorKind::VmError(error)
}
}
impl From<RuntimeError> for ErrorKind {
#[inline]
fn from(error: RuntimeError) -> Self {
ErrorKind::VmError(VmError::new(error.into_vm_error_kind()))
}
}
impl From<AnyObjError> for ErrorKind {
#[inline]
fn from(error: AnyObjError) -> Self {
Self::from(RuntimeError::from(error))
}
}
impl From<EncodeError> for ErrorKind {
#[inline]
fn from(error: EncodeError) -> Self {
ErrorKind::EncodeError(error)
}
}
impl From<MissingLastId> for ErrorKind {
#[inline]
fn from(error: MissingLastId) -> Self {
ErrorKind::MissingLastId(error)
}
}
impl From<GuardMismatch> for ErrorKind {
#[inline]
fn from(error: GuardMismatch) -> Self {
ErrorKind::GuardMismatch(error)
}
}
impl From<MissingScope> for ErrorKind {
#[inline]
fn from(error: MissingScope) -> Self {
ErrorKind::MissingScope(error)
}
}
impl From<PopError> for ErrorKind {
#[inline]
fn from(error: PopError) -> Self {
ErrorKind::PopError(error)
}
}
impl From<unescape::ErrorKind> for ErrorKind {
#[inline]
fn from(source: unescape::ErrorKind) -> Self {
ErrorKind::UnescapeError(source)
}
}
#[derive(Debug)]
#[non_exhaustive]
pub(crate) enum IrErrorKind {
NotConst,
ConstCycle,
UnsupportedMeta {
meta: MetaInfo,
},
Expected {
expected: TypeInfo,
actual: TypeInfo,
},
BudgetExceeded,
MissingIndex {
index: usize,
},
MissingField {
field: Box<str>,
},
BreakOutsideOfLoop,
ArgumentCountMismatch {
actual: usize,
expected: usize,
},
}
impl core::error::Error for IrErrorKind {}
impl fmt::Display for IrErrorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
IrErrorKind::NotConst => {
write!(f, "Expected a constant expression")?;
}
IrErrorKind::ConstCycle => {
write!(f, "Constant cycle detected")?;
}
IrErrorKind::UnsupportedMeta { meta } => {
write!(f, "Item `{meta}` is not supported here",)?
}
IrErrorKind::Expected { expected, actual } => {
write!(f, "Expected a value of type {expected} but got {actual}",)?
}
IrErrorKind::BudgetExceeded => {
write!(f, "Evaluation budget exceeded")?;
}
IrErrorKind::MissingIndex { index } => {
write!(f, "Missing index {index}")?;
}
IrErrorKind::MissingField { field } => {
write!(f, "Missing field `{field}`")?;
}
IrErrorKind::BreakOutsideOfLoop => {
write!(f, "Break outside of supported loop")?;
}
IrErrorKind::ArgumentCountMismatch { actual, expected } => {
write!(
f,
"Argument count mismatch, got {actual} but expected {expected}",
)?;
}
}
Ok(())
}
}
#[derive(Debug, TryClone)]
#[non_exhaustive]
pub struct ImportStep {
pub location: Location,
pub item: ItemBuf,
}
#[derive(Debug)]
pub struct MetaError {
kind: ::rust_alloc::boxed::Box<MetaErrorKind>,
}
impl MetaError {
pub(crate) fn new<E>(kind: E) -> Self
where
MetaErrorKind: From<E>,
{
Self {
kind: ::rust_alloc::boxed::Box::new(kind.into()),
}
}
}
impl From<alloc::Error> for MetaError {
#[inline]
fn from(error: alloc::Error) -> Self {
Self::new(MetaErrorKind::AllocError { error })
}
}
impl From<alloc::alloc::AllocError> for MetaError {
#[inline]
fn from(error: alloc::alloc::AllocError) -> Self {
Self::from(alloc::Error::from(error))
}
}
#[derive(Debug)]
pub(crate) enum MetaErrorKind {
AllocError {
error: alloc::Error,
},
MetaConflict {
current: MetaInfo,
existing: MetaInfo,
parameters: Hash,
},
}
impl fmt::Display for MetaError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &*self.kind {
MetaErrorKind::AllocError { error } => error.fmt(f),
MetaErrorKind::MetaConflict {
current,
existing,
parameters,
} => {
write!(f, "Can't insert item `{current}` ({parameters}) because conflicting meta `{existing}` already exists")
}
}
}
}
impl core::error::Error for MetaError {}
#[derive(Debug)]
pub(crate) struct MissingScope(pub(crate) usize);
impl fmt::Display for MissingScope {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Missing scope with id {}", self.0)
}
}
impl core::error::Error for MissingScope {}
#[derive(Debug)]
pub(crate) enum PopError {
MissingScope(usize),
MissingParentScope(usize),
}
impl fmt::Display for PopError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PopError::MissingScope(id) => write!(f, "Missing scope with id {id}"),
PopError::MissingParentScope(id) => write!(f, "Missing parent scope with id {id}"),
}
}
}
impl core::error::Error for PopError {}