oxalica / nil

NIx Language server, an incremental analysis assistant for writing in Nix.
Apache License 2.0
1.28k stars 39 forks source link

type of attrset from function application in let-binding is not propagated to usage in the let body #105

Open cassandracomar opened 11 months ago

cassandracomar commented 11 months ago

simple example:

{ stdenv, ... }:
let
  archComponentsFor = system: {
    "aarch64-darwin" = {
      arch = "arm64";
      os = "darwin";
      sha256 = "3c1e8b95cef4ff6e52d5f4b8c65b8d9d06b75f42d1cb40986c1d67729d82411a";
    };
  }.${system};
  # components is correctly recognized here:
  # Let binding components
  # { arch: string, os: string, sha256: ? 
  components = archComponentsFor stdenv.system;

in {
 # components is not correctly recognized here:
 # Let binding components
 # ?
  test = components.|
}

consequently, no completions are available inside the let body until the fields are used. I'm also not sure why the sha256 attribute has type ? when it's set to a string, but that's not really that big of a deal as it's a simple value.

oxalica commented 11 months ago

The inference fails for the dynamic attribute {..}.${system} when system is not a string literal. components in your example has type ? for me. The hint you see may result from inferences from your other piece of code.

Your case has only a single attribute in that attrset. But for { a = { foo = 1; }; b = { bar = 2; }; }.${system}, I'm not sure what type should it have. Probably a union of all field types { foo?: int, bar?: int }? It may be huge and costly for already-huge attrsets like pkgs, and may not help much.