Skip to content

Commit

Permalink
Make a separate ADT case for each user-facing error message.
Browse files Browse the repository at this point in the history
This is preparation for giving better source information in error messages.
  • Loading branch information
dougalm committed Dec 3, 2023
1 parent 75c4184 commit 6595db0
Show file tree
Hide file tree
Showing 27 changed files with 506 additions and 360 deletions.
1 change: 1 addition & 0 deletions src/dex.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import ConcreteSyntax (keyWordStrs, preludeImportBlock)
import RenderHtml
-- import Live.Terminal (runTerminal)
import Live.Web (runWeb)
import PPrint hiding (hardline)
import Core
import Types.Core
import Types.Imp
Expand Down
39 changes: 19 additions & 20 deletions src/lib/AbstractSyntax.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import Data.Text (Text)
import ConcreteSyntax
import Err
import Name
import PPrint ()
import PPrint
import Types.Primitives
import Types.Source
import qualified Types.OpNames as P
Expand Down Expand Up @@ -139,7 +139,7 @@ decl ann (WithSrcs sid _ d) = WithSrcB sid <$> case d of
CLet binder rhs -> do
(p, ty) <- patOptAnn binder
ULet ann p ty <$> asExpr <$> block rhs
CBind _ _ -> throw SyntaxErr "Arrow binder syntax <- not permitted at the top level, because the binding would have unbounded scope."
CBind _ _ -> throw TopLevelArrowBinder
CDefDecl def -> do
(name, lam) <- aDef def
return $ ULet ann (fromSourceNameW name) Nothing (WithSrcE sid (ULam lam))
Expand Down Expand Up @@ -199,7 +199,7 @@ withTrailingConstraints g cont = case g of
Nest (UAnnBinder expl (WithSrcB sid b) ann cs) bs <- withTrailingConstraints lhs cont
s <- case b of
UBindSource s -> return s
UIgnore -> throw SyntaxErr "Can't constrain anonymous binders"
UIgnore -> throw CantConstrainAnonBinders
UBind _ _ -> error "Shouldn't have internal names until renaming pass"
c' <- expr c
return $ UnaryNest (UAnnBinder expl (WithSrcB sid b) ann (cs ++ [c']))
Expand Down Expand Up @@ -261,7 +261,7 @@ uBinder :: GroupW -> SyntaxM (UBinder c VoidS VoidS)
uBinder (WithSrcs sid _ b) = case b of
CLeaf (CIdentifier name) -> return $ fromSourceNameW $ WithSrc sid name
CLeaf CHole -> return $ WithSrcB sid UIgnore
_ -> throw SyntaxErr "Binder must be an identifier or `_`"
_ -> throw UnexpectedBinder

-- Type annotation with an optional binder pattern
tyOptPat :: GroupW -> SyntaxM (UAnnBinder VoidS VoidS)
Expand Down Expand Up @@ -300,8 +300,7 @@ pat (WithSrcs sid _ grp) = WithSrcB sid <$> case grp of
CLeaf (CIdentifier name) -> return $ UPatBinder $ fromSourceNameW $ WithSrc sid name
CJuxtapose True lhs rhs -> do
case lhs of
WithSrcs _ _ (CJuxtapose True _ _) ->
throw SyntaxErr "Only unary constructors can form patterns without parens"
WithSrcs _ _ (CJuxtapose True _ _) -> throw OnlyUnaryWithoutParens
_ -> return ()
name <- identifier "pattern constructor name" lhs
arg <- pat rhs
Expand All @@ -313,11 +312,11 @@ pat (WithSrcs sid _ grp) = WithSrcB sid <$> case grp of
gs' <- mapM pat gs
return $ UPatCon (fromSourceNameW name) (toNest gs')
_ -> error "unexpected postfix group (should be ruled out at grouping stage)"
_ -> throw SyntaxErr "Illegal pattern"
_ -> throw IllegalPattern

tyOptBinder :: Explicitness -> GroupW -> SyntaxM (UAnnBinder VoidS VoidS)
tyOptBinder expl (WithSrcs sid sids grp) = case grp of
CBin (WithSrc _ Pipe) _ _ -> throw SyntaxErr "Unexpected constraint"
CBin (WithSrc _ Pipe) _ _ -> throw UnexpectedConstraint
CBin (WithSrc _ Colon) name ty -> do
b <- uBinder name
ann <- UAnn <$> expr ty
Expand All @@ -341,7 +340,7 @@ binderReqTy expl (WithSrcs _ _ (CBin (WithSrc _ Colon) name ty)) = do
b <- uBinder name
ann <- UAnn <$> expr ty
return $ UAnnBinder expl b ann []
binderReqTy _ _ = throw SyntaxErr $ "Expected an annotated binder"
binderReqTy _ _ = throw ExpectedAnnBinder

argList :: [GroupW] -> SyntaxM ([UExpr VoidS], [UNamedArg VoidS])
argList gs = partitionEithers <$> mapM singleArg gs
Expand All @@ -355,7 +354,7 @@ singleArg = \case
identifier :: String -> GroupW -> SyntaxM SourceNameW
identifier ctx (WithSrcs sid _ g) = case g of
CLeaf (CIdentifier name) -> return $ WithSrc sid name
_ -> throw SyntaxErr $ "Expected " ++ ctx ++ " to be an identifier"
_ -> throw $ ExpectedIdentifier ctx

aEffects :: WithSrcs ([GroupW], Maybe GroupW) -> SyntaxM (UEffectRow VoidS)
aEffects (WithSrcs _ _ (effs, optEffTail)) = do
Expand All @@ -375,7 +374,7 @@ effect (WithSrcs _ _ grp) = case grp of
return $ URWSEffect State $ fromSourceNameW (WithSrc sid h)
CLeaf (CIdentifier "Except") -> return UExceptionEffect
CLeaf (CIdentifier "IO" ) -> return UIOEffect
_ -> throw SyntaxErr "Unexpected effect form; expected one of `Read h`, `Accum h`, `State h`, `Except`, `IO`, or the name of a user-defined effect."
_ -> throw UnexpectedEffectForm

aMethod :: CSDeclW -> SyntaxM (Maybe (UMethodDef VoidS))
aMethod (WithSrcs _ _ CPass) = return Nothing
Expand All @@ -386,7 +385,7 @@ aMethod (WithSrcs src _ d) = Just . WithSrcE src <$> case d of
CLet (WithSrcs sid _ (CLeaf (CIdentifier name))) rhs -> do
rhs' <- ULamExpr Empty ImplicitApp Nothing Nothing <$> block rhs
return $ UMethodDef (fromSourceNameW (WithSrc sid name)) rhs'
_ -> throw SyntaxErr "Unexpected method definition. Expected `def` or `x = ...`."
_ -> throw UnexpectedMethodDef

asExpr :: UBlock VoidS -> UExpr VoidS
asExpr (WithSrcE src b) = case b of
Expand All @@ -403,7 +402,7 @@ blockDecls :: [CSDeclW] -> SyntaxM (Nest UDecl VoidS VoidS, UExpr VoidS)
blockDecls [] = error "shouldn't have empty list of decls"
blockDecls [WithSrcs _ _ d] = case d of
CExpr g -> (Empty,) <$> expr g
_ -> throw SyntaxErr "Block must end in expression"
_ -> throw BlockWithoutFinalExpr
blockDecls (WithSrcs sid _ (CBind b rhs):ds) = do
b' <- binderOptTy Explicit b
rhs' <- asExpr <$> block rhs
Expand All @@ -428,15 +427,15 @@ expr (WithSrcs sid _ grp) = WithSrcE sid <$> case grp of
-- Table constructors here. Other uses of square brackets
-- should be detected upstream, before calling expr.
CBrackets gs -> UTabCon <$> mapM expr gs
CGivens _ -> throw SyntaxErr $ "Unexpected `given` clause"
CGivens _ -> throw UnexpectedGivenClause
CArrow lhs effs rhs -> do
case lhs of
WithSrcs _ _ (CParens gs) -> do
bs <- aPiBinders gs
effs' <- fromMaybeM effs UPure aEffects
resultTy <- expr rhs
return $ UPi $ UPiExpr bs ExplicitApp effs' resultTy
_ -> throw SyntaxErr "Argument types should be in parentheses"
_ -> throw ArgsShouldHaveParens
CDo b -> UDo <$> block b
CJuxtapose hasSpace lhs rhs -> case hasSpace of
True -> extendAppRight <$> expr lhs <*> expr rhs
Expand All @@ -459,22 +458,22 @@ expr (WithSrcs sid _ grp) = WithSrcE sid <$> case grp of
name <- case rhs' of
CLeaf (CIdentifier name) -> return $ FieldName name
CLeaf (CNat i ) -> return $ FieldNum $ fromIntegral i
_ -> throw SyntaxErr "Field must be a name or an integer"
_ -> throw BadField
return $ UFieldAccess lhs' (WithSrc src name)
DoubleColon -> UTypeAnn <$> (expr lhs) <*> expr rhs
EvalBinOp s -> evalOp s
DepAmpersand -> do
lhs' <- tyOptPat lhs
UDepPairTy . (UDepPairType ExplicitDepPair lhs') <$> expr rhs
DepComma -> UDepPair <$> (expr lhs) <*> expr rhs
CSEqual -> throw SyntaxErr "Equal sign must be used as a separator for labels or binders, not a standalone operator"
Colon -> throw SyntaxErr "Colon separates binders from their type annotations, is not a standalone operator.\nIf you are trying to write a dependent type, use parens: (i:Fin 4) => (..i)"
CSEqual -> throw BadEqualSign
Colon -> throw BadColon
ImplicitArrow -> case lhs of
WithSrcs _ _ (CParens gs) -> do
bs <- aPiBinders gs
resultTy <- expr rhs
return $ UPi $ UPiExpr bs ImplicitApp UPure resultTy
_ -> throw SyntaxErr "Argument types should be in parentheses"
_ -> throw ArgsShouldHaveParens
FatArrow -> do
lhs' <- tyOptPat lhs
UTabPi . (UTabPiExpr lhs') <$> expr rhs
Expand All @@ -496,7 +495,7 @@ expr (WithSrcs sid _ grp) = WithSrcE sid <$> case grp of
WithSrcE _ (UIntLit i) -> UIntLit (-i)
WithSrcE _ (UFloatLit i) -> UFloatLit (-i)
e -> unaryApp (mkUVar sid "neg") e
_ -> throw SyntaxErr $ "Prefix (" ++ pprint name ++ ") not legal as a bare expression"
_ -> throw $ BadPrefix $ pprint name
CLambda params body -> do
params' <- explicitBindersOptAnn $ WithSrcs sid [] $ map stripParens params
body' <- block body
Expand Down
3 changes: 2 additions & 1 deletion src/lib/Algebra.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import MTL1
import Name
import Subst
import QueryType
import PPrint
import Types.Core
import Types.Imp
import Types.Primitives
Expand Down Expand Up @@ -55,7 +56,7 @@ sumUsingPolys lim (Abs i body) = do
sumAbs <- refreshAbs (Abs i body) \(i':>_) body' -> do
exprAsPoly body' >>= \case
Just poly' -> return $ Abs i' poly'
Nothing -> throw NotImplementedErr $
Nothing -> throwInternal $
"Algebraic simplification failed to model index computations:\n"
++ "Trying to sum from 0 to " ++ pprint lim ++ " - 1, \\"
++ pprint i' ++ "." ++ pprint body'
Expand Down
18 changes: 3 additions & 15 deletions src/lib/Builder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import Control.Monad.State.Strict (MonadState (..), StateT (..), runStateT)
import qualified Data.Map.Strict as M
import Data.Foldable (fold)
import Data.Graph (graphFromEdges, topSort)
import Data.Text.Prettyprint.Doc (Pretty (..))
import Foreign.Ptr

import qualified Unsafe.Coerce as TrulyUnsafe
Expand All @@ -30,6 +29,7 @@ import MTL1
import Subst
import Name
import PeepholeOptimize
import PPrint
import QueryType
import Types.Core
import Types.Imp
Expand Down Expand Up @@ -103,18 +103,6 @@ buildScopedAssumeNoDecls cont = do
_ -> error "Expected no decl emissions"
{-# INLINE buildScopedAssumeNoDecls #-}

withReducibleEmissions
:: (ScopableBuilder r m, Builder r m, HasNamesE e, SubstE AtomSubstVal e)
=> String
-> (forall o' . (Emits o', DExt o o') => m o' (e o'))
-> m o (e o)
withReducibleEmissions msg cont = do
withDecls <- buildScoped cont
reduceWithDecls withDecls >>= \case
Just t -> return t
_ -> throw TypeErr msg
{-# INLINE withReducibleEmissions #-}

-- === "Hoisting" top-level builder class ===

-- `emitHoistedEnv` lets you emit top env fragments, like cache entries or
Expand Down Expand Up @@ -926,10 +914,10 @@ symbolicTangentTy elTy = lookupSourceMap "SymbolicTangent" >>= \case
Just (UTyConVar symTanName) -> do
return $ toType $ UserADTType "SymbolicTangent" symTanName $
TyConParams [Explicit] [toAtom elTy]
Nothing -> throw UnboundVarErr $
Nothing -> throwInternal $
"Can't define a custom linearization with symbolic zeros: " ++
"the SymbolicTangent type is not in scope."
Just _ -> throw TypeErr "SymbolicTangent should name a `data` type"
Just _ -> throwInternal $ "SymbolicTangent should name a `data` type"

symbolicTangentZero :: EnvReader m => SType n -> m n (SAtom n)
symbolicTangentZero argTy = return $ toAtom $ SumCon [UnitTy, argTy] 0 UnitVal
Expand Down
2 changes: 1 addition & 1 deletion src/lib/CheapReduction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import Core
import Err
import IRVariants
import Name
import PPrint ()
import PPrint
import QueryTypePure
import Types.Core
import Types.Top
Expand Down
30 changes: 15 additions & 15 deletions src/lib/CheckType.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import IRVariants
import MTL1
import Name
import Subst
import PPrint ()
import PPrint
import QueryType
import Types.Core
import Types.Primitives
Expand Down Expand Up @@ -56,7 +56,7 @@ affineUsed name = TyperM $ do
case lookupNameMapE name affines of
Just (LiftE n) ->
if n > 0 then
throw TypeErr $ "Affine name " ++ pprint name ++ " used " ++ show (n + 1) ++ " times."
throwInternal $ "Affine name " ++ pprint name ++ " used " ++ show (n + 1) ++ " times."
else
put $ insertNameMapE name (LiftE $ n + 1) affines
Nothing -> put $ insertNameMapE name (LiftE 1) affines
Expand Down Expand Up @@ -90,7 +90,7 @@ checkTypesEq reqTy ty = alphaEq reqTy ty >>= \case
False -> {-# SCC typeNormalization #-} do
alphaEq reqTy ty >>= \case
True -> return ()
False -> throw TypeErr $ pprint reqTy ++ " != " ++ pprint ty
False -> throwInternal $ pprint reqTy ++ " != " ++ pprint ty
{-# INLINE checkTypesEq #-}

class SinkableE e => CheckableE (r::IR) (e::E) | e -> r where
Expand Down Expand Up @@ -407,7 +407,7 @@ instance IRRep r => CheckableE r (Con r) where
ProdCon xs -> ProdCon <$> mapM checkE xs
SumCon tys tag payload -> do
tys' <- mapM checkE tys
unless (0 <= tag && tag < length tys') $ throw TypeErr "Invalid SumType tag"
unless (0 <= tag && tag < length tys') $ throwInternal "Invalid SumType tag"
payload' <- payload |: (tys' !! tag)
return $ SumCon tys' tag payload'
HeapVal -> return HeapVal
Expand Down Expand Up @@ -570,7 +570,7 @@ instance IRRep r => CheckableWithEffects r (MiscOp r) where
case (destTy', sourceTy) of
(BaseTy dbt@(Scalar _), BaseTy sbt@(Scalar _)) | sizeOf sbt == sizeOf dbt ->
return $ BitcastOp destTy' e'
_ -> throw TypeErr $ "Invalid bitcast: " ++ pprint sourceTy ++ " -> " ++ pprint destTy
_ -> throwInternal $ "Invalid bitcast: " ++ pprint sourceTy ++ " -> " ++ pprint destTy
UnsafeCoerce t e -> UnsafeCoerce <$> checkE t <*> renameM e
GarbageVal t -> GarbageVal <$> checkE t
SumTag x -> do
Expand Down Expand Up @@ -616,14 +616,14 @@ instance IRRep r => CheckableE r (VectorOp r) where
TabTy _ b (BaseTy (Scalar sbt)) <- return $ getType tbl'
i' <- i |: binderType b
ty'@(BaseTy (Vector _ sbt')) <- checkE ty
unless (sbt == sbt') $ throw TypeErr "Scalar type mismatch"
unless (sbt == sbt') $ throwInternal "Scalar type mismatch"
return $ VectorIdx tbl' i' ty'
VectorSubref ref i ty -> do
ref' <- checkE ref
RefTy _ (TabTy _ b (BaseTy (Scalar sbt))) <- return $ getType ref'
i' <- i |: binderType b
ty'@(BaseTy (Vector _ sbt')) <- checkE ty
unless (sbt == sbt') $ throw TypeErr "Scalar type mismatch"
unless (sbt == sbt') $ throwInternal "Scalar type mismatch"
return $ VectorSubref ref' i' ty'

checkHof :: IRRep r => EffTy r o -> Hof r i -> TyperM r i o (Hof r o)
Expand Down Expand Up @@ -706,7 +706,7 @@ instance IRRep r => CheckableWithEffects r (DAMOp r) where
checkExtends effs effAnn'
ixTy' <- checkE ixTy
(carry', carryTy') <- checkAndGetType carry
let badCarry = throw TypeErr $ "Seq carry should be a product of raw references, got: " ++ pprint carryTy'
let badCarry = throwInternal $ "Seq carry should be a product of raw references, got: " ++ pprint carryTy'
case carryTy' of
TyCon (ProdType refTys) -> forM_ refTys \case RawRefTy _ -> return (); _ -> badCarry
_ -> badCarry
Expand Down Expand Up @@ -773,7 +773,7 @@ checkProject i x = case getType x of
TyCon (DepPairTy t) | i == 1 -> do
xFst <- reduceProj 0 x
checkInstantiation t [xFst]
xTy -> throw TypeErr $ "Not a product type:" ++ pprint xTy
xTy -> throwInternal $ "Not a product type:" ++ pprint xTy

checkTabApp :: (IRRep r) => Type r o -> Atom r o -> TyperM r i o (Type r o)
checkTabApp ty i = do
Expand All @@ -794,7 +794,7 @@ checkInstantiation abTop xsTop = do
checkTypesEq (getType x) (binderType b)
rest <- applySubst (b@>SubstVal x) (Abs bs body)
go rest xs
go _ _ = throw ZipErr "Wrong number of args"
go _ _ = throwInternal "Wrong number of args"

checkIntBaseType :: Fallible m => BaseType -> m ()
checkIntBaseType t = case t of
Expand All @@ -809,7 +809,7 @@ checkIntBaseType t = case t of
Word32Type -> return ()
Word64Type -> return ()
_ -> notInt
notInt = throw TypeErr $
notInt = throwInternal $
"Expected a fixed-width scalar integer type, but found: " ++ pprint t

checkFloatBaseType :: Fallible m => BaseType -> m ()
Expand All @@ -822,13 +822,13 @@ checkFloatBaseType t = case t of
Float64Type -> return ()
Float32Type -> return ()
_ -> notFloat
notFloat = throw TypeErr $
notFloat = throwInternal $
"Expected a fixed-width scalar floating-point type, but found: " ++ pprint t

checkValidCast :: (Fallible1 m, IRRep r) => Type r n -> Type r n -> m n ()
checkValidCast (TyCon (BaseType l)) (TyCon (BaseType r)) = checkValidBaseCast l r
checkValidCast sourceTy destTy =
throw TypeErr $ "Can't cast " ++ pprint sourceTy ++ " to " ++ pprint destTy
throwInternal $ "Can't cast " ++ pprint sourceTy ++ " to " ++ pprint destTy

checkValidBaseCast :: Fallible m => BaseType -> BaseType -> m ()
checkValidBaseCast (PtrType _) (PtrType _) = return ()
Expand All @@ -838,13 +838,13 @@ checkValidBaseCast (Scalar _) (Scalar _) = return ()
checkValidBaseCast sourceTy@(Vector sourceSizes _) destTy@(Vector destSizes _) =
assertEq sourceSizes destSizes $ "Can't cast " ++ pprint sourceTy ++ " to " ++ pprint destTy
checkValidBaseCast sourceTy destTy =
throw TypeErr $ "Can't cast " ++ pprint sourceTy ++ " to " ++ pprint destTy
throwInternal $ "Can't cast " ++ pprint sourceTy ++ " to " ++ pprint destTy

scalarOrVectorLike :: Fallible m => BaseType -> ScalarBaseType -> m BaseType
scalarOrVectorLike x sbt = case x of
Scalar _ -> return $ Scalar sbt
Vector sizes _ -> return $ Vector sizes sbt
_ -> throw CompilerErr "only scalar or vector base types should occur here"
_ -> throwInternal $ "only scalar or vector base types should occur here"

data ArgumentType = SomeFloatArg | SomeIntArg | SomeUIntArg

Expand Down
1 change: 1 addition & 0 deletions src/lib/ConcreteSyntax.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import Data.Void
import Text.Megaparsec hiding (Label, State)
import Text.Megaparsec.Char hiding (space, eol)

import Err
import Lexing
import Types.Core
import Types.Source
Expand Down
Loading

0 comments on commit 6595db0

Please sign in to comment.