@@ -11,6 +11,7 @@ import qualified Data.Text as Text
1111import qualified AST.Module.Name as ModuleName
1212import qualified Reporting.Annotation as A
1313import qualified Reporting.Error.Type as Error
14+import qualified Type.Occurs as Occurs
1415import qualified Type.State as TS
1516import Type.Type as Type
1617import Type.Unify
@@ -268,7 +269,7 @@ crash msg =
268269occurs :: (Text.Text, A.Located Variable) -> TS.Solver ()
269270occurs (name, A.A region variable) =
270271 {-# SCC elm_compiler_type_occurs #-}
271− do hasOccurred <- liftIO $ occursHelp [] variable
272+ do hasOccurred <- liftIO $ Occurs.occurs variable
272273 case hasOccurred of
273274 False ->
274275 return ()
@@ -276,44 +277,3 @@ occurs (name, A.A region variable) =
276277 True ->
277278 do overallType <- liftIO (Type.toSrcType variable)
278279 TS.addError region (Error.InfiniteType name overallType)
279−
280−
281−occursHelp :: [Variable] -> Variable -> IO Bool
282−occursHelp seen var =
283− if elem var seen then
284− do infiniteDescriptor <- UF.descriptor var
285− UF.setDescriptor var (infiniteDescriptor { _content = Error })
286− return True
287−
288− else
289− do desc <- UF.descriptor var
290− case _content desc of
291− Atom _ ->
292− return False
293−
294− Var _ _ _ ->
295− return False
296−
297− Error ->
298− return False
299−
300− Alias _ args _ ->
301− -- TODO is it okay to only check args?
302− or <$> mapM (occursHelp (var:seen) . snd) args
303−
304− Structure term ->
305− let
306− go = occursHelp (var:seen)
307− in
308− case term of
309− App1 a b ->
310− (||) <$> go a <*> go b
311−
312− Fun1 a b ->
313− (||) <$> go a <*> go b
314−
315− EmptyRecord1 ->
316− return False
317−
318− Record1 fields ext ->
319− or <$> mapM go (ext : Map.elems fields)