idris-lang / Idris2

A purely functional programming language with first class types
https://idris-lang.org/
Other
2.5k stars 375 forks source link

[ parser ] Add support for impossible lambdas #3270

Closed dunhamsteve closed 5 months ago

dunhamsteve commented 5 months ago

Description

A user on the Discord was having trouble figuring out the syntax for creating a lambda whose cases are impossible. It is currently supported via a case lambda: \case Refl impossible, but not with a bare lambda. The error message is unclear on what to do.

With this change we can now write expressions like \Refl impossible for impossible lambdas.

Should this change go in the CHANGELOG?

dunhamsteve commented 5 months ago

The build failure is weird. An ENOMEM starting runtests. I’m going to force CI to run again.

dunhamsteve commented 5 months ago

I haven't sorted this out yet, but I think it's going to happen to any other PR that adds a test.

The test runner fails to load after this PR adds a test. It did not fail prior to merging, when there was one less test. The issue does not reproduce locally. I am also on aarch64, also using homebrew chez, and using the same version of macos as the build VM. The error message looks like it's running out of some resource when scanning a small directory during the runtests initialization. (possibly a file handle? - it's ENOMEM, which is used for other resources too). Removing another test (perror001) resolves the issue.

The error message is:

./build/exec/runtests /Users/runner/work/Idris2/Idris2/build/exec/idris2  --timing --failure-file failures --threads 3 --only  --except 
failed to list allschemes: Cannot allocate memory
make[1]: *** [test] Error 1
make: *** [test] Error 2
dunhamsteve commented 5 months ago

So the test runner assigns a lot of IO TestPool to global variables, like so:

ttimpTests : IO TestPool
ttimpTests = testsInDir "ttimp" "TTImp"

where testsInDir starts ike:

testsInDir dirName poolName = do
  Right names <- listDir dirName
    | Left e => die $ "failed to list " ++ dirName ++ ": " ++ show e
   ...

and listDir begins:

listDir name = do Right d <- openDir name
                    | Left e => pure $ Left e
    ...

I believe the openDir name gets run eagerly, and we have a bunch of filehandles or some other resource held open. If I block it like so:

 testsInDir dirName poolName = do
+  _ <- pure ()
   Right names <- listDir dirName
     | Left e => die $ "failed to list " ++ dirName ++ ": " ++ show e
   ...

the problem goes away. For a big more clarity, I just do declare testsInDir lazy instead.

I can also PR this change separately if desired.

andrevidela commented 5 months ago

amazing detective work on the CI. The diff looks good to me, in it goes