mirror of
https://github.com/carp-lang/Carp.git
synced 2024-09-11 05:25:28 +03:00
fix: properly assign types to recursive calls (#1210)
This commit fixes an issue whereby all recursive calls were given var types, this resulted in strange behavior such as the following code: ```clojure (defn recurse [a b] (let [c (+ b 1) out (recurse c)] (+ out 1))) (defn main [] (println* (recurse 1 2))) ``` compiling just fine and yielding runtime segfaults. Now, if a recursive instance of a symbol was previously typed, we use that type--if not, we assign a fresh type variable (the old behavior). This fixes code like that above, throwing an error at compile time about an incorrect number of arguments for `recurse`. Fixes #348
This commit is contained in:
parent
e7746c3d1e
commit
86e409fbd1
@ -116,11 +116,16 @@ initialTypes typeEnv rootEnv root = evalState (visit rootEnv root) 0
|
||||
-- catchall case for exhaustive patterns
|
||||
unknown -> pure (Left (InvalidObj unknown xobj))
|
||||
visitSymbol :: Env -> XObj -> SymPath -> State Integer (Either TypeError XObj)
|
||||
visitSymbol _ xobj@(XObj (Sym _ LookupRecursive) _ _) _ =
|
||||
-- Recursive lookups are left untouched (this avoids problems with looking up the thing they're referring to)
|
||||
do
|
||||
freshTy <- genVarTy
|
||||
pure (Right xobj {xobjTy = Just freshTy})
|
||||
visitSymbol e xobj@(XObj (Sym name LookupRecursive) _ _) _ =
|
||||
case E.searchValueBinder e name of
|
||||
-- If this recursive symbol is already typed in this environment, use that type.
|
||||
-- This is relevant for, e.g. recursive function calls.
|
||||
-- We need to use search here to check parents as our let-binding handling possibly puts recursive
|
||||
-- environments as the parent of a more local environment for the let bindings.
|
||||
Right (Binder _ found) -> pure (Right xobj {xobjTy = xobjTy found})
|
||||
-- Other recursive lookups are left untouched (this avoids problems with looking up the thing they're referring to)
|
||||
Left _ -> do freshTy <- genVarTy
|
||||
pure (Right xobj {xobjTy = Just freshTy})
|
||||
visitSymbol env xobj symPath =
|
||||
case symPath of
|
||||
-- Symbols with leading ? are 'holes'.
|
||||
|
Loading…
Reference in New Issue
Block a user