use std::io::Error as IOError; use crate::semantics::resolve::ImportStack; use crate::syntax::{Import, ParseError}; use crate::NormalizedExpr; mod builder; pub(crate) use builder::*; pub type Result = std::result::Result; #[derive(Debug)] #[non_exhaustive] pub enum Error { IO(IOError), Parse(ParseError), Decode(DecodeError), Encode(EncodeError), Resolve(ImportError), Typecheck(TypeError), } #[derive(Debug)] pub enum ImportError { Recursive(Import, Box), UnexpectedImport(Import), ImportCycle(ImportStack, Import), } #[derive(Debug)] pub enum DecodeError { CBORError(serde_cbor::error::Error), WrongFormatError(String), } #[derive(Debug)] pub enum EncodeError { CBORError(serde_cbor::error::Error), } /// A structured type error #[derive(Debug)] pub struct TypeError { message: TypeMessage, } /// The specific type error #[derive(Debug)] pub(crate) enum TypeMessage { // UnboundVariable(Span), // NotAFunction(Value), // TypeMismatch(Value, Value, Value), // AnnotMismatch(Value, Value), // InvalidListElement(usize, Value, Value), // InvalidListType(Value), // InvalidOptionalType(Value), // InvalidPredicate(Value), // IfBranchMismatch(Value, Value), // IfBranchMustBeTerm(bool, Value), // InvalidFieldType(Label, Value), // NotARecord(Label, Value), // MustCombineRecord(Value), // MissingRecordField(Label, Value), // MissingUnionField(Label, Value), // BinOpTypeMismatch(BinOp, Value), // InvalidTextInterpolation(Value), // Merge1ArgMustBeRecord(Value), // Merge2ArgMustBeUnionOrOptional(Value), // MergeEmptyNeedsAnnotation, // MergeHandlerMissingVariant(Label), // MergeVariantMissingHandler(Label), // MergeAnnotMismatch, // MergeHandlerTypeMismatch, // MergeHandlerReturnTypeMustNotBeDependent, // ProjectionMustBeRecord, // ProjectionMissingEntry, // ProjectionDuplicateField, Sort, // RecordTypeDuplicateField, // RecordTypeMergeRequiresRecordType(Value), // UnionTypeDuplicateField, // EquivalenceArgumentMustBeTerm(bool, Value), // EquivalenceTypeMismatch(Value, Value), // AssertMismatch(Value, Value), // AssertMustTakeEquivalence, Custom(String), } impl TypeError { pub(crate) fn new(message: TypeMessage) -> Self { TypeError { message } } } impl std::fmt::Display for TypeError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { use TypeMessage::*; let msg = match &self.message { // UnboundVariable(var) => var.error("Type error: Unbound variable"), // NotAFunction(v) => v.span().error("Type error: Not a function"), // TypeMismatch(x, y, z) => { // x.span() // .error("Type error: Wrong type of function argument") // + "\n" // + &z.span().error(format!( // "This argument has type {:?}", // z.get_type().unwrap() // )) // + "\n" // + &y.span().error(format!( // "But the function expected an argument of type {:?}", // y // )) // } Custom(s) => format!("Type error: Unhandled error: {}", s), _ => format!("Type error: Unhandled error: {:?}", self.message), }; write!(f, "{}", msg) } } impl std::error::Error for TypeError {} impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { Error::IO(err) => write!(f, "{}", err), Error::Parse(err) => write!(f, "{}", err), Error::Decode(err) => write!(f, "{:?}", err), Error::Encode(err) => write!(f, "{:?}", err), Error::Resolve(err) => write!(f, "{:?}", err), Error::Typecheck(err) => write!(f, "{}", err), } } } impl std::error::Error for Error {} impl From for Error { fn from(err: IOError) -> Error { Error::IO(err) } } impl From for Error { fn from(err: ParseError) -> Error { Error::Parse(err) } } impl From for Error { fn from(err: DecodeError) -> Error { Error::Decode(err) } } impl From for Error { fn from(err: EncodeError) -> Error { Error::Encode(err) } } impl From for Error { fn from(err: ImportError) -> Error { Error::Resolve(err) } } impl From for Error { fn from(err: TypeError) -> Error { Error::Typecheck(err) } }