hercules-ci / flake-parts

❄️ Simplify Nix Flakes with the module system
https://flake.parts
MIT License
699 stars 38 forks source link

infinite recursion when `self` assigned to option #185

Closed DavHau closed 9 months ago

DavHau commented 11 months ago

The following flake leads to an infinite recursion:

{
  outputs = inputs@{flake-parts, nixpkgs, self, ...}:
    flake-parts.lib.mkFlake {inherit inputs;} {
      nixosConfigurations.default = nixpkgs.lib.nixosSystem {
        modules = [
          {
            # assigning self to a non existent option triggers the infinite recursion
            foo.repoRoot = self;
          }
        ];
      };
    };
}

I think this issue is import to fix. For example this could as well happen with the treefmt.repoRoot option. If it ever gets deprecated, users will be puzzled by a hard to debug issue.

In my case this lead to a stack overflow with no trace at all.

This does only happen when using flake-parts and not with vanilla flakes.

roberth commented 11 months ago

@DavHau which version and platform did that happen?

When I run it on x86_64-linux, I get infinite recursions instead, which do have a trace, although the quality of the trace varies between Nix versions. 2.13.3 seems best. Good thing the latest two or three releases have test infrastructure to catch such regressions - wish we had it sooner.

Seems like a serious problem indeed. I think we should add sourceInfo directly to inputs in Nix to solve this without removing source locations for all the other errors when they occur in the anonymous "root" module that is the mkFlake {} argument.

This solution may also help with

DavHau commented 11 months ago

In my case this lead to a stack overflow with no trace at all.

The example above results in an infinite recursion for me as well. I got a stack overflow error in dream2nix, but after stripping it down to a minimal reproducer it became an infinite recursion. Not sure if that change in behavior was due to complexity or due to library versions.

Let me know if I should publish the dream2nix expression that lead to a stack overflow.

roberth commented 11 months ago

Could you try with this?

PR description shows how to nix run that nix.

You might be able to tell what's the difference between your original problem and reproducer with it.

roberth commented 11 months ago

Blocked on https://github.com/NixOS/nix/pull/8908

roberth commented 9 months ago

Does #192 help?

With it I get:

$ nix eval . --override-input flake-parts github:hercules-ci/flake-parts/refs/pull/192/head
warning: not writing modified lock file of flake 'path:/home/user/h/issue-flake-parts-185':
• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/7f53fdb7bdc5bb237da7fefef12d099e4fd611ca' (2023-09-01)
  → 'github:hercules-ci/flake-parts/0effb5db5ccc46f8787c98ca91ec64cc9721c121' (2023-10-13)
error: The option `nixosConfigurations' does not exist. Definition values:
       - In `<unknown-file>'
(use '--show-trace' to show detailed location information)

Still an error, as expected, but actionable.

Fixing it up a bit:

{
  outputs = inputs@{flake-parts, nixpkgs, self, ...}:
    flake-parts.lib.mkFlake {inherit inputs;} {
      systems = [ "x86_64-linux" ];
      flake.nixosConfigurations.default = nixpkgs.lib.nixosSystem {
        modules = [
          {
            # assigning self to a non existent option triggers the infinite recursion
            foo.repoRoot = self;
          }
        ];
      };
    };
}

I then get this, simulating nixos-rebuild a bit:

$ nix eval .#nixosConfigurations.default.config.system.build.toplevel.drvPath --override-input flake-parts github:hercules-ci/flake-parts/refs/pull/192/head
warning: not writing modified lock file of flake 'path:/home/user/h/issue-flake-parts-185':
• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/7f53fdb7bdc5bb237da7fefef12d099e4fd611ca' (2023-09-01)
  → 'github:hercules-ci/flake-parts/0effb5db5ccc46f8787c98ca91ec64cc9721c121' (2023-10-13)
error: Neither nixpkgs.hostPlatform nor the legacy option nixpkgs.system has been set.
       You can set nixpkgs.hostPlatform in hardware-configuration.nix by re-running
       a recent version of nixos-generate-config.
       The option nixpkgs.system is still fully supported for NixOS 22.05 interoperability,
       but will be deprecated in the future, so we recommend to set nixpkgs.hostPlatform.
(use '--show-trace' to show detailed location information)
roberth commented 9 months ago

Fixed in #192