Open oxalica opened 2 years ago
Since 2 is easy and mostly works, if there are cases where it's not sufficient a way to annotate (a comment after the arg?) the correct type could be useful.
I like the idea of for flakes being able to evaluate the flake and its outputs and record the types things had during that evaluation so they're guaranteed to be right. Could even record multiple types when something has different types depending on where it's called. That also sounds really hard.
An idea I have about this issue is to possibly use type annotations or otherwise say where the things going into some lambda come from, since it will be different in NixOS modules (regrettably).
Like:
# @type callPackage
{ hello, stdenv }: ....
The initial implementation of type system is included in 2022-11-07. Currently type inference is done in individual files and have no information input. Polymorphism is also not implemented yet. But it already improved the completion experience a lot.
Type schema of flake.nix
is implemented since d044c9c5b4241975ff64f7e1ee4ad0b26c036fea. Completion of inputs and known input fields like outPath
, modifiedDate
work now. But since we don't evaluate flakes yet, their real output cannot be completed.
Flake output fields also work, but only when a direct Attrset literal is given in the output. If you use other wrappers like flake-utils
, it will not work currently.
Ideally this could be extended to even provide diagnostics.
I thought, one could start with typing all builtins and maybe nixpkgs.lib
and then inferring every time there is a guaranteed type conflict, i.e. when someone swaps the arguments of map
.
Are there plans to add support for type annotations?
Previously mentioned in,
Without some kinds of "evaluation" going on, it's not possible to complete any meaningful attributes after
.
or?
. The most obvious thought is to introduce a type system with inference.For a typical file from nixpkgs,
We have these main goals:
stdenv.mk|
.stdenv
has known type in current file.fetchurl { u| }
.fetchurl
has known type in current file.{ lib, stde| }
.stdenv
.lib.optional
.builtins.attrNames
, which is not currently implemented. See also #15flake.nix
.{ inputs = /**/; outputs = inputs: inputs.| }
Since the file itself doesn't provide any information about the types of its parameter. We should somehow figure out how it is expected to be called, by either,
nixpkgs.legacyPackages.<system>
. Guess parameter types by evaluating corresponding attributes via Nix invocation.I think we'll go method (2) since it's much simpler and works in most cases.
If anyone has more ideas on this, please comments here.