diff options
author | Nadrieril | 2019-05-07 18:12:04 +0200 |
---|---|---|
committer | Nadrieril | 2019-05-07 18:12:04 +0200 |
commit | 3da450aa3fae23214aa982643b9bc4dd0ea4eaa6 (patch) | |
tree | 02e00cd008d2e7dc899b9211379596fe792f41c8 /dhall/src/error/mod.rs | |
parent | d8a3e831fb67f86269c4baa99f9f0798a73a7247 (diff) | |
parent | 14dfeb8e7d2aa87a361a711a485243449426b144 (diff) |
Merge branch 'reorganize'
Diffstat (limited to 'dhall/src/error/mod.rs')
-rw-r--r-- | dhall/src/error/mod.rs | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/dhall/src/error/mod.rs b/dhall/src/error/mod.rs new file mode 100644 index 0000000..f84d078 --- /dev/null +++ b/dhall/src/error/mod.rs @@ -0,0 +1,169 @@ +use std::io::Error as IOError; + +use dhall_syntax::{BinOp, Import, Label, ParseError, V}; + +use crate::core::context::TypecheckContext; +use crate::phase::resolve::ImportStack; +use crate::phase::{Normalized, Type, Typed}; + +pub type Result<T> = std::result::Result<T, Error>; + +#[derive(Debug)] +#[non_exhaustive] +pub enum Error { + IO(IOError), + Parse(ParseError), + Decode(DecodeError), + Resolve(ImportError), + Typecheck(TypeError), + Deserialize(String), +} + +#[derive(Debug)] +pub enum ImportError { + Recursive(Import, Box<Error>), + UnexpectedImport(Import), + ImportCycle(ImportStack, Import), +} + +#[derive(Debug)] +pub enum DecodeError { + CBORError(serde_cbor::error::Error), + WrongFormatError(String), +} + +/// A structured type error that includes context +#[derive(Debug)] +pub struct TypeError { + type_message: TypeMessage, + context: TypecheckContext, +} + +/// The specific type error +#[derive(Debug)] +pub(crate) enum TypeMessage { + UnboundVariable(V<Label>), + InvalidInputType(Normalized), + InvalidOutputType(Normalized), + NotAFunction(Typed), + TypeMismatch(Typed, Normalized, Typed), + AnnotMismatch(Typed, Normalized), + Untyped, + InvalidListElement(usize, Normalized, Typed), + InvalidListType(Normalized), + InvalidOptionalType(Normalized), + InvalidPredicate(Typed), + IfBranchMismatch(Typed, Typed), + IfBranchMustBeTerm(bool, Typed), + InvalidFieldType(Label, Type), + NotARecord(Label, Normalized), + MissingRecordField(Label, Typed), + MissingUnionField(Label, Normalized), + BinOpTypeMismatch(BinOp, Typed), + NoDependentTypes(Normalized, Normalized), + InvalidTextInterpolation(Typed), + Sort, + Unimplemented, +} + +impl TypeError { + pub(crate) fn new( + context: &TypecheckContext, + type_message: TypeMessage, + ) -> Self { + TypeError { + context: context.clone(), + type_message, + } + } +} + +impl From<TypeError> for std::option::NoneError { + fn from(_: TypeError) -> std::option::NoneError { + std::option::NoneError + } +} + +impl std::error::Error for TypeMessage { + fn description(&self) -> &str { + use TypeMessage::*; + match *self { + // UnboundVariable => "Unbound variable", + InvalidInputType(_) => "Invalid function input", + InvalidOutputType(_) => "Invalid function output", + NotAFunction(_) => "Not a function", + TypeMismatch(_, _, _) => "Wrong type of function argument", + _ => "Unhandled error", + } + } +} + +impl std::fmt::Display for TypeMessage { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + // UnboundVariable(_) => { + // f.write_str(include_str!("errors/UnboundVariable.txt")) + // } + // TypeMismatch(e0, e1, e2) => { + // let template = include_str!("errors/TypeMismatch.txt"); + // let s = template + // .replace("$txt0", &format!("{}", e0.as_expr())) + // .replace("$txt1", &format!("{}", e1.as_expr())) + // .replace("$txt2", &format!("{}", e2.as_expr())) + // .replace( + // "$txt3", + // &format!( + // "{}", + // e2.get_type() + // .unwrap() + // .as_normalized() + // .unwrap() + // .as_expr() + // ), + // ); + // f.write_str(&s) + // } + _ => f.write_str("Unhandled error message"), + } + } +} + +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::Resolve(err) => write!(f, "{:?}", err), + Error::Typecheck(err) => write!(f, "{:?}", err), + Error::Deserialize(err) => write!(f, "{}", err), + } + } +} + +impl std::error::Error for Error {} +impl From<IOError> for Error { + fn from(err: IOError) -> Error { + Error::IO(err) + } +} +impl From<ParseError> for Error { + fn from(err: ParseError) -> Error { + Error::Parse(err) + } +} +impl From<DecodeError> for Error { + fn from(err: DecodeError) -> Error { + Error::Decode(err) + } +} +impl From<ImportError> for Error { + fn from(err: ImportError) -> Error { + Error::Resolve(err) + } +} +impl From<TypeError> for Error { + fn from(err: TypeError) -> Error { + Error::Typecheck(err) + } +} |