Skip to content

[#1994] Display TZIP-16 storage checks in the LSP

Motivation and Context

Display TZIP-16 warnings in the language server.

Also, refactor LIGO to avoid over-use of in library code.

Related issues

Resolves #1994 (closed).

Checklist for the LIGO Language Server

  • I checked whether I need to update the file for the plugin and did so if necessary:
    • If I implemented a new LSP request, I added it to the list of supported features that may be disabled
    • If I implemented a new LSP method, I added it to the list of supported functionality
  • I checked that my changes work in Emacs, Vim, and Visual Studio Code
  • (Before merging) The commit history is squashed and prettified, and follows the Serokell commit policy, or the MR is set to squash the commits


Refactor LIGO to avoid overuse of in library code, as this will crash the language server. This is because calls to can't be nested, but the language server already runs entirely inside one of such calls. For this, I had to also use try%lwt and create some helper functions in Trace, such as try_with_lwt which is aware of Lwt. This is because Lwt catches exceptions and turns them into rejected promises, but OCaml's try _ with _ won't handle such promises, which will become cryptic ("Local(_)") errors. Propagate Lwt.t up until we reach executable code, test code, or a Lwt callback. There is only one place in the code where I had to keep in LIGO's formatters, I'm not sure how to remove that one.

Refactor storage a bit, so it can take an Ast_typed rather than a raw file, in order to reuse the Ast_typed that we obtain from scopes, and avoid recompilation.

Create a new function in Get_scope that tries to find a storage, and if found, generates a dummy virtual entry-point with that storage type, and calls the storage checks using that entry-point. Some of the diagnostics from such checks had no locations, so I added them to them.

In on_doc, cache storage checks, since they can download files from the internet and lag the LSP server. We only invalidate the cache if the storage was changed; this is done by traversing the CST and checking if the changes done by the user intersect with the storage. Add diagnostic tests for such checks.


  • compiler
  • website
  • webide
  • vscode-plugin
  • debugger

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Performance improvement (non-breaking change that improves performance)
  • None (change with no changelog)


Warnings related to a contract's storage should now be displayed by the language server for TZIP-16 compliance. These warnings are only visible if there is a top-level definition called storage with an appropriate storage type.

In addition, more diagnostics will be shown, such as ones for unused variables.


  • Changes follow the existing coding style (use dune @fmt to check).
  • Tests for the changes have been added (for bug fixes / feature).
  • Documentation has been updated.
  • Changelog description has been added (if appropriate).
  • Start titles under ## Changelog section with #### (if appropriate).
  • There is no image or uploaded file in changelog
  • Examples in changed behaviour have been added to the changelog (for breaking change / feature).
Edited by Heitor Toledo Lassarote de Paula

Merge request reports