![LiquidHaskell](/resources/logo.png) [![Hackage](https://img.shields.io/hackage/v/liquidhaskell.svg)](https://hackage.haskell.org/package/liquidhaskell) [![Hackage-Deps](https://img.shields.io/hackage-deps/v/liquidhaskell.svg)](http://packdeps.haskellers.com/feed?needle=liquidhaskell) [![Build Status](https://img.shields.io/circleci/project/ucsd-progsys/liquidhaskell/master.svg)](https://circleci.com/gh/ucsd-progsys/liquidhaskell) [![Windows build status](https://ci.appveyor.com/api/projects/status/78y7uusjcgor5p16/branch/develop?svg=true)](https://ci.appveyor.com/project/varosi/liquidhaskell-nlhra/branch/develop) This is the **development** site of the LiquidHaskell formal verification tool. If you're a LiquidHaskell **user** (or just curious), you probably want to go to [the documentation website](https://ucsd-progsys.github.io/liquidhaskell/) instead. # Contributing This is an open-source project, and we love getting feedback (and patches)! ## Reporting a Bug If something doesn't work as it should, please consider opening a [github issue](https://github.com/ucsd-progsys/liquidhaskell/issues) to let us know. If possible, try to: * Try to use a descriptive title; * State as clearly as possible what is the problem you are facing; * Provide a small Haskell file producing the issue; * Write down the expected behaviour vs the actual behaviour; * If possible, let us know if you have used the [plugin](install.md) or the [executable](legacy.md) and which _GHC version_ you are using. ## Your first Pull Request We are thrilled to get PRs! Please follow these guidelines, as doing so will increase the chances of having your PR accepted: * The main LH repo [lives here](https://github.com/ucsd-progsys/liquidhaskell) * Please create pull requests against the `develop` branch. * Please be sure to include test cases that illustrate the effect of the PR - e.g. show new features that that are supported or how it fixes some previous issue * If you're making user-visible changes, please also add documentation - e.g. [options.md](options.md), [specifications.md](specifications.md), the [main tutorial](https:///github.com/ucsd-progsys/intro-refinement-types) (as relevant) Pull requests don't just have to be about code: documentation can often be improved too! ## Ask for Help If you have further questions or you just need help, you can always reach out on our [slack channel](https://join.slack.com/t/liquidhaskell/shared_invite/enQtMjY4MTk3NDkwODE3LTFmZGFkNGEzYWRkNDJmZDQ0ZGU1MzBiZWZiZDhhNmY3YTJiMjUzYTRlNjMyZDk1NDU3ZGIxYzhlOTIzN2UxNWE), [google groups mailing list](https://groups.google.com/forum/#!forum/liquidhaskell), [GitHub issue tracker](https://github.com/ucsd-progsys/liquidhaskell/issues), or by emailing one of our star developers: [Ranjit Jhala](https://github.com/ranjitjhala), [Niki Vazou](https://github.com/nikivazou). # General Development Guide For those diving into the implementation of LiquidHaskell, here are a few tips: ## Fast (re)compilation When working on the `liquidhaskell` library, usually all we want is to make changes and quickly recompile only the bare minimum, to try out new ideas. Using a fully-fledged GHC plugin doesn't help in this sense, because packages like `liquid-base` or `liquid-ghc-prim` all have a direct dependency on `liquidhaskell`, and therefore every time the latter changes, an expensive rebuild of those packages is triggered, which might become tedious overtime. To mitigate this, we offer a faster, "dev-style" build mode which is based on the assumption that most changes to the `liquidhaskell` library do not alter the validity of already-checked libraries, and therefore things like `liquid-base` and `liquid-ghc-prim` can be considered "static assets", avoiding the need for a recompilation. In other terms, we explicitly disable recompilation of any of the `liquid-*` ancillary library in dev mode, so that rebuilds would also influence the `liquidhaskell` library. ### Usage and recommended workflow This is how you can use this: * To begin with, perform a **full** build of **all** the libraries, by doing either `cabal v2-build` or `stack build`, **without** specifying any extra environment variables from the command line. This is needed to ensure that we things like `liquid-base` and `liquid-ghc-prim` are compiled at least once, as we would need the refinements they contain to correctly checks other downstream programs; * At this point, the content of the `liquid-*` packages is considered "trusted" and "frozen", until you won't force another full, _non-dev_ build; * In order to quickly test changes to the `liquidhaskell` library without recompiling the `liquid-*` packages, we need to start a build passing the `LIQUID_DEV_MODE` env var as part of the build command. Examples: #### Stack ``` env LIQUID_DEV_MODE=true stack build ``` #### Cabal ``` LIQUID_DEV_MODE=true cabal v2-build ``` It's also possible (but not recommended) to add `LIQUID_DEV_MODE` to .bashrc or similar, but this would permanently disable building the `liquid-*` packages, and this might silently mask breaking changes to the `liquidhaskell` library that would manifest only when compiling these other packages. If you wish to force building all the libraries again, it's sufficient to issue the same builds commands without the `LIQUID_DEV_MODE`. ## How To Run Regression Tests _For a way of running the test suite for multiple GHC versions, consult the General Development FAQs. below_ There are particular scripts for running LH in the different modes, e.g. for different compiler versions and in plugin mode or as standalone. These scripts are in: $ ./scripts/test So you can run *all* the tests for say the ghc-8.10 version by $ ./scripts/test/test_810.sh You can run a particular test instead by $ LIQUID_DEV_MODE=true ./scripts/test/test_810.sh BadDataDeclTyVars.hs Note that the script uses the `BadDataDeclTyVars.hs` as a pattern so will run *all* tests that match. So, for example, $ LIQUID_DEV_MODE=true ./scripts/test/test_810.sh Error-Messages will run all the tests in the `Error-Messages` group. To pass in specific parameters and run a subset of the tests **FIXME** $ stack test liquidhaskell --fast --test-arguments "--liquid-opts --no-termination -p Unit Or your favorite number of threads, depending on cores etc. You can directly extend and run the tests by modifying tests/test.hs ## How to create performance comparison charts Everytime `liquidhaskell` tests are run, a report of the time taken by each test is written to a file `tests/logs/-