@@ -6,6 +6,7 @@ module Fay.Compiler.Desugar
66 (desugar
77 ) where
88
9+ import Fay.Exts.NoAnnotation (unAnn )
910import Fay.Types (CompileError (.. ))
1011
1112import Control.Applicative
@@ -116,10 +117,10 @@ desugarExp ex = case ex of
116117 Paren l e -> Paren l <$> desugarExp e
117118 RecConstr l q f -> RecConstr l (desugarQName q) <$> mapM desugarFieldUpdate f
118119 RecUpdate l e f -> RecUpdate l <$> desugarExp e <*> mapM desugarFieldUpdate f
119- EnumFrom l e -> EnumFrom l <$> desugarExp e
120- EnumFromTo l e1 e2 -> EnumFromTo l <$> desugarExp e1 <*> desugarExp e2
121- EnumFromThen l e1 e2 -> EnumFromThen l <$> desugarExp e1 <*> desugarExp e2
122- EnumFromThenTo l e1 e2 e3 -> EnumFromThenTo l <$> desugarExp e1 <*> desugarExp e2 <*> desugarExp e3
120+ e @ ( EnumFrom l e1) -> checkEnum e >> ( EnumFrom l <$> desugarExp e1)
121+ e @ ( EnumFromTo l e1 e2) -> checkEnum e >> ( EnumFromTo l <$> desugarExp e1 <*> desugarExp e2)
122+ e @ ( EnumFromThen l e1 e2) -> checkEnum e >> ( EnumFromThen l <$> desugarExp e1 <*> desugarExp e2)
123+ e @ ( EnumFromThenTo l e1 e2 e3) -> checkEnum e >> ( EnumFromThenTo l <$> desugarExp e1 <*> desugarExp e2 <*> desugarExp e3)
123124 ListComp l e qs -> ListComp l <$> desugarExp e <*> mapM desugarQualStmt qs
124125 ParComp l e qqs -> ParComp l <$> desugarExp e <*> mapM (mapM desugarQualStmt) qqs
125126 ExpTypeSig l e t -> ExpTypeSig l <$> desugarExp e <*> return (desugarType t)
@@ -286,3 +287,32 @@ desugarTupleSec l xs = do
286287 (rn, re) <- genSlotNames l rest ns
287288 e' <- desugarExp e
288289 return (rn, e' : re)
290+
291+ -- | We only have Enum instance for Int, but GHC hard codes [x..y]
292+ -- syntax to GHC.Base.Enum instead of using our Enum class so we check
293+ -- for obviously incorrect usages and throw an error on them. This can
294+ -- only checks literals, but it helps a bit.
295+ checkEnum :: Exp l -> Desugar ()
296+ checkEnum exp = case exp of
297+ EnumFrom _ e -> checkIntOrUnknown [e]
298+ EnumFromTo _ e1 e2 -> checkIntOrUnknown [e1,e2]
299+ EnumFromThen _ e1 e2 -> checkIntOrUnknown [e1,e2]
300+ EnumFromThenTo _ e1 e2 e3 -> checkIntOrUnknown [e1,e2,e3]
301+ _ -> error " checkEnum: Only for Enums"
302+ where
303+ checkIntOrUnknown :: [Exp l ] -> Desugar ()
304+ checkIntOrUnknown es = if any isIntOrUnknown es
305+ then return ()
306+ else throwError . UnsupportedEnum $ unAnn exp
307+ isIntOrUnknown :: Exp l -> Bool
308+ isIntOrUnknown e = case e of
309+ Con {} -> False
310+ Lit _ Int {} -> True
311+ Lit {} -> False
312+ Tuple {} -> False
313+ List {} -> False
314+ EnumFrom {} -> False
315+ EnumFromTo {} -> False
316+ EnumFromThen {} -> False
317+ EnumFromThenTo {} -> False
318+ _ -> True
0 commit comments