use crate::ast;
use crate::token::Kind;
use runestick::{Item, Meta, Span};
use std::fmt;
use std::io;
use thiserror::Error;
pub type CompileResult<T, E = CompileError> = std::result::Result<T, E>;
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, Error)]
pub enum Error {
#[error("parse error")]
ParseError(#[from] ParseError),
#[error("compile error")]
CompileError(#[from] CompileError),
#[error("configuration error")]
ConfigurationError(#[from] ConfigurationError),
#[error("I/O error")]
Io(#[from] io::Error),
#[error("formatting error")]
Fmt(#[from] fmt::Error),
#[error("virtual machine error")]
VmError(#[from] runestick::VmError),
#[error("context error")]
ContextError(#[from] runestick::ContextError),
}
#[derive(Debug, Clone, Error)]
pub enum ConfigurationError {
#[error("unsupported optimization option `{option}`")]
UnsupportedOptimizationOption {
option: String,
},
}
#[derive(Debug, Clone, Copy, Error)]
pub enum ParseError {
#[error("unexpected end-of-file")]
UnexpectedEof {
span: Span,
},
#[error("expected end of file, but encountered `{actual}`")]
ExpectedEof {
span: Span,
actual: Kind,
},
#[error("expected import component but found `{actual}`")]
ExpectedDeclUseImportComponent {
span: Span,
actual: Kind,
},
#[error("expected escape")]
ExpectedStringEscape {
span: Span,
},
#[error("unterminated string literal")]
UnterminatedStrLit {
span: Span,
},
#[error("unterminated character literal")]
UnterminatedCharLit {
span: Span,
},
#[error("unterminated byte literal")]
UnterminatedByteLit {
span: Span,
},
#[error("expected character literal to be closed")]
ExpectedCharClose {
span: Span,
},
#[error("expected byte literal to be closed")]
ExpectedByteClose {
span: Span,
},
#[error("expected string template to be closed")]
ExpectedTemplateClose {
span: Span,
},
#[error("expected character character")]
ExpectedCharEscape {
span: Span,
},
#[error("token mismatch, expected `{expected}` but was `{actual}`")]
TokenMismatch {
span: Span,
expected: Kind,
actual: Kind,
},
#[error("expected start of pattern but got `{actual}`")]
ExpectedPatError {
span: Span,
actual: Kind,
},
#[error("expected start of expression but got `{actual}`")]
ExpectedExpr {
span: Span,
actual: Kind,
},
#[error("expected enum variant but got `{actual}`")]
ExpectedEnumVariant {
span: Span,
actual: Kind,
},
#[error("expected loop but got `{actual}")]
ExpectedLoop {
span: Span,
actual: Kind,
},
#[error("expected block expression but got `{actual}`")]
ExpectedBlockExpr {
span: Span,
actual: Kind,
},
#[error("unexpected character `{c}`")]
UnexpectedChar {
span: Span,
c: char,
},
#[error("expected number but got `{actual}`")]
ExpectedNumber {
span: Span,
actual: Kind,
},
#[error("expected byte but got `{actual}`")]
ExpectedByte {
span: Span,
actual: Kind,
},
#[error("expected char but got `{actual}`")]
ExpectedChar {
span: Span,
actual: Kind,
},
#[error("expected string but got `{actual}`")]
ExpectedString {
span: Span,
actual: Kind,
},
#[error("expected operator (`+`, `-`, `/`, `*`) but got `{actual}`")]
ExpectedOperator {
span: Span,
actual: Kind,
},
#[error("expected `true` or `false` but got `{actual}`")]
ExpectedBool {
span: Span,
actual: Kind,
},
#[error("expected an object key (string or identifier) but got `{actual}`")]
ExpectedLitObjectKey {
span: Span,
actual: Kind,
},
#[error("expected unary operator (`!`) but got `{actual}`")]
ExpectedUnaryOperator {
span: Span,
actual: Kind,
},
#[error("group required in expression to determine precedence")]
PrecedenceGroupRequired {
span: Span,
},
#[error("tried to read bad slice from source `{span}`")]
BadSlice {
span: Span,
},
#[error("bad escape sequence")]
BadEscapeSequence {
span: Span,
},
#[error("number literal not valid")]
BadNumberLiteral {
span: Span,
},
#[error("number literal out of bounds `-9223372036854775808` to `9223372036854775807`")]
BadNumberOutOfBounds {
span: Span,
},
#[error("bad character literal")]
BadCharLiteral {
span: Span,
},
#[error("bad byte literal")]
BadByteLiteral {
span: Span,
},
#[error("unicode escapes are not supported as a byte or byte string")]
UnicodeEscapeNotSupported {
span: Span,
},
#[error("bad unicode escape")]
BadUnicodeEscape {
span: Span,
},
#[error(
"this form of character escape may only be used with characters in the range [\\x00-\\x7f]"
)]
UnsupportedUnicodeByteEscape {
span: Span,
},
#[error(
"this form of byte escape may only be used with characters in the range [\\x00-\\xff]"
)]
UnsupportedByteEscape {
span: Span,
},
#[error("bad byte escape")]
BadByteEscape {
span: Span,
},
#[error("invalid template literal")]
InvalidTemplateLiteral {
span: Span,
},
#[error("closing braces must be escaped inside of templates with `\\}}`")]
UnexpectedCloseBrace {
span: Span,
},
#[error("unsupported field access")]
UnsupportedFieldAccess {
span: Span,
},
#[error("not supported as a function or closure argument")]
ExpectedFunctionArgument {
span: Span,
},
}
impl ParseError {
pub fn span(&self) -> Span {
match *self {
Self::UnexpectedEof { span, .. } => span,
Self::ExpectedEof { span, .. } => span,
Self::ExpectedStringEscape { span, .. } => span,
Self::UnterminatedStrLit { span, .. } => span,
Self::UnterminatedCharLit { span, .. } => span,
Self::UnterminatedByteLit { span, .. } => span,
Self::ExpectedCharEscape { span, .. } => span,
Self::ExpectedCharClose { span, .. } => span,
Self::ExpectedByteClose { span, .. } => span,
Self::ExpectedTemplateClose { span, .. } => span,
Self::TokenMismatch { span, .. } => span,
Self::ExpectedPatError { span, .. } => span,
Self::ExpectedExpr { span, .. } => span,
Self::ExpectedEnumVariant { span, .. } => span,
Self::ExpectedLoop { span, .. } => span,
Self::ExpectedBlockExpr { span, .. } => span,
Self::UnexpectedChar { span, .. } => span,
Self::ExpectedNumber { span, .. } => span,
Self::ExpectedByte { span, .. } => span,
Self::ExpectedChar { span, .. } => span,
Self::ExpectedString { span, .. } => span,
Self::ExpectedOperator { span, .. } => span,
Self::ExpectedBool { span, .. } => span,
Self::ExpectedLitObjectKey { span, .. } => span,
Self::ExpectedUnaryOperator { span, .. } => span,
Self::PrecedenceGroupRequired { span, .. } => span,
Self::BadSlice { span, .. } => span,
Self::BadEscapeSequence { span, .. } => span,
Self::BadNumberLiteral { span, .. } => span,
Self::BadNumberOutOfBounds { span, .. } => span,
Self::BadCharLiteral { span, .. } => span,
Self::BadByteLiteral { span, .. } => span,
Self::UnicodeEscapeNotSupported { span, .. } => span,
Self::BadUnicodeEscape { span, .. } => span,
Self::UnsupportedUnicodeByteEscape { span, .. } => span,
Self::UnsupportedByteEscape { span, .. } => span,
Self::BadByteEscape { span, .. } => span,
Self::InvalidTemplateLiteral { span, .. } => span,
Self::UnexpectedCloseBrace { span, .. } => span,
Self::UnsupportedFieldAccess { span, .. } => span,
Self::ExpectedFunctionArgument { span, .. } => span,
Self::ExpectedDeclUseImportComponent { span, .. } => span,
}
}
}
#[derive(Debug, Error)]
pub enum CompileError {
#[error("internal compiler error: {msg}")]
Internal {
msg: &'static str,
span: Span,
},
#[error("unit construction error: {error}")]
UnitError {
#[from]
error: runestick::UnitError,
},
#[error("{error}")]
ParseError {
#[from]
error: ParseError,
},
#[error("found conflicting item `{existing}`")]
ItemConflict {
span: Span,
existing: Item,
},
#[error("variable `{name}` conflicts")]
VariableConflict {
span: Span,
name: String,
existing_span: Span,
},
#[error("missing variable `{name}`")]
MissingLocal {
span: Span,
name: String,
},
#[error("no type matching `{item}`")]
MissingType {
span: Span,
item: Item,
},
#[error("missing module `{item}`")]
MissingModule {
span: Span,
item: Item,
},
#[error("label not found in scope")]
MissingLabel {
span: Span,
},
#[error("wildcard support not supported in this position")]
UnsupportedWildcard {
span: Span,
},
#[error("cannot declare instance functions for type `{meta}`")]
UnsupportedInstanceFunction {
span: Span,
meta: Meta,
},
#[error("`{meta}` cannot be used as a value")]
UnsupportedValue {
span: Span,
meta: Meta,
},
#[error("`{meta}` cannot be used as a type")]
UnsupportedType {
span: Span,
meta: Meta,
},
#[error("argument not supported here")]
UnsupportedArgument {
span: Span,
},
#[error("`self` not supported here")]
UnsupportedSelf {
span: Span,
},
#[error("unsupported unary operator `{op}`")]
UnsupportedUnaryOp {
span: Span,
op: ast::UnaryOp,
},
#[error("unsupported binary operator `{op}`")]
UnsupportedBinaryOp {
span: Span,
op: ast::BinOp,
},
#[error("type `{item}` is not an object")]
UnsupportedLitObject {
span: Span,
item: Item,
},
#[error("missing field `{field}` in declaration of `{item}`")]
LitObjectMissingField {
span: Span,
field: String,
item: Item,
},
#[error("`{field}` is not a field in `{item}`")]
LitObjectNotField {
span: Span,
field: String,
item: Item,
},
#[error("cannot assign to expression")]
UnsupportedAssignExpr {
span: Span,
},
#[error("unsupported operator `{op}` in assignment")]
UnsupportedAssignBinOp {
span: Span,
op: ast::BinOp,
},
#[error("cannot take reference of expression")]
UnsupportedRef {
span: Span,
},
#[error("`await` expression is not supported in this location")]
UnsupportedAwait {
span: Span,
},
#[error("unsupported select pattern")]
UnsupportedSelectPattern {
span: Span,
},
#[error("unsupported field access")]
UnsupportedFieldAccess {
span: Span,
},
#[error("wrong number of arguments, expected `{expected}` but got `{actual}`")]
UnsupportedArgumentCount {
span: Span,
meta: Meta,
expected: usize,
actual: usize,
},
#[error("`{meta}` is not supported in a pattern like this")]
UnsupportedMetaPattern {
meta: Meta,
span: Span,
},
#[error("`{meta}` is not supported as a closure")]
UnsupportedMetaClosure {
meta: Meta,
span: Span,
},
#[error("item is not supported in a pattern")]
UnsupportedPattern {
span: Span,
},
#[error("not a valid binding")]
UnsupportedBinding {
span: Span,
},
#[error("break expressions cannot be used as a value")]
BreakOutsideOfLoop {
span: Span,
},
#[error("cannot return locally created references")]
ReturnLocalReferences {
block: Span,
span: Span,
references_at: Vec<Span>,
},
#[error("floating point numbers cannot be used in patterns")]
MatchFloatInPattern {
span: Span,
},
#[error("duplicate key in literal object")]
DuplicateObjectKey {
span: Span,
existing: Span,
object: Span,
},
#[error("`{item}` is not a function")]
MissingFunction {
span: Span,
item: Item,
},
#[error("`yield` must be used in function or closure")]
YieldOutsideFunction {
span: Span,
},
#[error("instance function declared outside of `impl` block")]
InstanceFunctionOutsideImpl {
span: Span,
},
#[error("async generators are not supported")]
UnsupportedAsyncGenerator {
span: Span,
},
#[error("import `{item}` (imported in prelude) does not exist")]
MissingPreludeModule {
item: Item,
},
}
impl CompileError {
pub fn internal(msg: &'static str, span: Span) -> Self {
Self::Internal { msg, span }
}
}
impl CompileError {
pub fn span(&self) -> Span {
match *self {
Self::UnitError { .. } => Span::default(),
Self::Internal { span, .. } => span,
Self::ParseError { error, .. } => error.span(),
Self::ItemConflict { span, .. } => span,
Self::VariableConflict { span, .. } => span,
Self::MissingLocal { span, .. } => span,
Self::MissingType { span, .. } => span,
Self::MissingModule { span, .. } => span,
Self::MissingLabel { span, .. } => span,
Self::UnsupportedWildcard { span, .. } => span,
Self::UnsupportedRef { span, .. } => span,
Self::UnsupportedAwait { span, .. } => span,
Self::UnsupportedInstanceFunction { span, .. } => span,
Self::UnsupportedValue { span, .. } => span,
Self::UnsupportedType { span, .. } => span,
Self::UnsupportedArgument { span, .. } => span,
Self::UnsupportedSelf { span, .. } => span,
Self::UnsupportedUnaryOp { span, .. } => span,
Self::UnsupportedBinaryOp { span, .. } => span,
Self::UnsupportedLitObject { span, .. } => span,
Self::UnsupportedAssignExpr { span, .. } => span,
Self::UnsupportedAssignBinOp { span, .. } => span,
Self::UnsupportedSelectPattern { span, .. } => span,
Self::UnsupportedFieldAccess { span, .. } => span,
Self::UnsupportedArgumentCount { span, .. } => span,
Self::UnsupportedMetaPattern { span, .. } => span,
Self::UnsupportedMetaClosure { span, .. } => span,
Self::UnsupportedPattern { span, .. } => span,
Self::UnsupportedBinding { span, .. } => span,
Self::BreakOutsideOfLoop { span, .. } => span,
Self::ReturnLocalReferences { span, .. } => span,
Self::MatchFloatInPattern { span, .. } => span,
Self::DuplicateObjectKey { span, .. } => span,
Self::LitObjectMissingField { span, .. } => span,
Self::LitObjectNotField { span, .. } => span,
Self::MissingFunction { span, .. } => span,
Self::YieldOutsideFunction { span, .. } => span,
Self::InstanceFunctionOutsideImpl { span, .. } => span,
Self::UnsupportedAsyncGenerator { span, .. } => span,
Self::MissingPreludeModule { .. } => Span::empty(),
}
}
}