~jojo/Carth

9f609fd9b971c818f46d6481daddc5ce9ebc2c66 — JoJo 2 years ago 58767c2
Fix loop bug in assertNoRec

Fixes bad test "data-direct-recursion-loop-bug.carth".
It now properly reports the error instead of looping forever.
2 files changed, 12 insertions(+), 9 deletions(-)

M src/Front/Check.hs
M src/Front/Inferred.hs
M src/Front/Check.hs => src/Front/Check.hs +11 -9
@@ 158,20 158,22 @@ builtinDataTypes' =
    where unit' = ("Unit", [])

assertNoRec :: Inferred.TypeDefs -> (String, ([TVar], Inferred.TypeDefRhs)) -> Except TypeErr ()
assertNoRec tdefs' (x, (_, rhs)) = assertNoRec' rhs Map.empty
assertNoRec tdefs' (x, (xinst, rhs)) = assertNoRec' (Set.singleton (x, map TVar xinst))
                                                    rhs
                                                    Map.empty
  where
    assertNoRec' (Inferred.Data cs) s =
        forM_ cs $ \(WithPos cpos _, cts) -> forM_ cts (assertNoRecType cpos . subst s)
    assertNoRec' (Inferred.Alias pos t) s = assertNoRecType pos (subst s t)
    assertNoRecType cpos = \case
        Inferred.TConst (y, ts) -> do
            when (x == y) $ throwError (RecTypeDef x cpos)
    assertNoRec' seen (Inferred.Data cs) s =
        forM_ cs $ \(WithPos cpos _, cts) -> forM_ cts (assertNoRecType seen cpos . subst s)
    assertNoRec' seen (Inferred.Alias pos t) s = assertNoRecType seen pos (subst s t)
    assertNoRecType seen cpos = \case
        Inferred.TConst (y, yinst) -> do
            when (Set.member (y, yinst) seen) $ throwError (RecTypeDef x cpos)
            let (tvs, cs) = Map.findWithDefault
                    (ice $ "assertNoRec: type id " ++ show y ++ " not in tdefs")
                    y
                    tdefs'
            let substs = Map.fromList (zip tvs ts)
            assertNoRec' cs substs
            let substs = Map.fromList (zip tvs yinst)
            assertNoRec' (Set.insert (y, yinst) seen) cs substs
        _ -> pure ()

checkExterns :: Inferred.TypeDefs -> [Parsed.Extern] -> Except TypeErr Inferred.Externs

M src/Front/Inferred.hs => src/Front/Inferred.hs +1 -0
@@ 112,6 112,7 @@ data Def = VarDef VarDef | RecDefs RecDefs deriving Show
type VarDef = (String, (Scheme, Expr))
type RecDefs = [(String, (Scheme, Fun))]
data TypeDefRhs = Data [(WithPos String, [Type])] | Alias SrcPos Type
    deriving Show
type TypeDefs = Map String ([TVar], TypeDefRhs)
type TypeAliases = Map String ([TVar], Type)
type Ctors = Map String (VariantIx, (String, [TVar]), [Type], Span)