{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE Safe #-} -- | Errors from typechecking foreign functions. module Cryptol.TypeCheck.FFI.Error where import Control.DeepSeq import GHC.Generics import Cryptol.TypeCheck.PP import Cryptol.TypeCheck.Subst import Cryptol.TypeCheck.Type data FFITypeError = FFITypeError Type FFITypeErrorReason deriving (Show, Generic, NFData) data FFITypeErrorReason = FFIBadWordSize | FFIBadFloatSize | FFIBadArrayType | FFIBadComponentTypes [FFITypeError] | FFIBadType | FFINotFunction deriving (Show, Generic, NFData) instance TVars FFITypeError where apSubst su (FFITypeError t r) = FFITypeError !$ apSubst su t !$ apSubst su r instance TVars FFITypeErrorReason where apSubst su r = case r of FFIBadWordSize -> r FFIBadFloatSize -> r FFIBadArrayType -> r FFIBadComponentTypes errs -> FFIBadComponentTypes !$ apSubst su errs FFIBadType -> r FFINotFunction -> r instance FVS FFITypeError where fvs (FFITypeError t r) = fvs (t, r) instance FVS FFITypeErrorReason where fvs r = case r of FFIBadWordSize -> mempty FFIBadFloatSize -> mempty FFIBadArrayType -> mempty FFIBadComponentTypes errs -> fvs errs FFIBadType -> mempty FFINotFunction -> mempty instance PP (WithNames FFITypeError) where ppPrec _ (WithNames (FFITypeError t r) names) = nest 2 $ "Type unsupported for FFI:" $$ vcat [ ppWithNames names t , "Due to:" , ppWithNames names r ] instance PP (WithNames FFITypeErrorReason) where ppPrec _ (WithNames r names) = case r of FFIBadWordSize -> vcat [ "Unsupported word size" , "Only words of up to 64 bits are supported" ] FFIBadFloatSize -> vcat [ "Unsupported Float format" , "Only Float32 and Float64 are supported" ] FFIBadArrayType -> vcat [ "Unsupported sequence element type" , "Only words or floats are supported as the element type of" , "(possibly multidimensional) sequences" ] FFIBadComponentTypes errs -> indent 2 $ vcat $ map (ppWithNames names) errs FFIBadType -> vcat [ "Only Bit, words, floats, Integer, Z, Rational, sequences, or structs" , "or tuples of the above are supported as FFI argument or return types" ] FFINotFunction -> "FFI binding must be a function"