jfecher / ante

A safe, easy systems language
http://antelang.org
MIT License
1.9k stars 80 forks source link

No definition for 'recur2' #119

Closed jfecher closed 1 year ago

jfecher commented 2 years ago

Trying the following code:

row = 0
col = 0

match ()
| () ->
    recur2 col = print col
    recur2 col

    recur row = recur2 row
    recur row

Fails with:

r.an:9:17       error: No declaration for `recur2` was found in scope
    recur row = recur2 row

Expected result: It should successfully compile with line 9 capturing recur2, making recur a closure.

jfecher commented 2 years ago

This bug also may be preventing nested loops from compiling as the shadowed recur names they desugar to may not be resolved properly (citation needed).

jfecher commented 2 years ago

The nested loop issue seems to be separate. Showing information from name resolution in the parse tree for a similar file with nested loops:

(row$510 = 0);
(col$511 = 0);
(match () (()
    (recur$512 = (fn row$513 -> (match () (()
        (recur$514 = (fn col$515 -> (print$63 col$515)));
        (recur$514 col$511)
    ))));
    (recur$512 row$510)
))

Show that the two recurs (recur 512, and recur 514) are correctly identified as separate.

ArbilGit commented 2 years ago

I minified the two errors and found a new one which may be the most tractable as it reaches an unreachable! line.

  1. Your original

    if true then
    f () = ()
    g () = f ()
    ()

    Fails with No declaration for 'f' was found in scope

  2. The "loop error"

    n = 0
    f () = 
    g x = print x
    g n

    Fails with Recursion limit reached when searching for impls for Print a

It works if n is declared in inner scope.

  1. fn () ->
    f x = x
    g x = f x
    g 0

    Fails with thread 'main' panicked at 'internal error: entered unreachable code', src/types/mod.rs:214:48

All three seem to be errors at different compiler passes. What they have in common is captures in nested scopes.

jfecher commented 1 year ago

These seem to be separate errors, I've pushed a commit fixing the original 'No declaration' error. It was caused by the name resolution algorithm not searching the full top-level scope when we're not at top level - only the subset of definitions that were global. I've pushed a fix to search through all of them and if the declaration is not global then create a closure.

Creating the closure then progresses until it triggers error (3) where it seems the captured function has never undergone typechecking and crashes when unwrapping its type. I'm considering this a separate error and will create a new issue for it.