Skip to content

Can't merge hierarchical options into submodule (or freeform option) #146882

@roberth

Description

@roberth

Describe the bug

Part of an option tree may be free-form.

Extending the free-form part in a separate module is hard and prevents certain use cases and migrations.

Steps To Reproduce

let
  lib = import ./lib;
  inherit (lib) types mkOption;
in
(lib.evalModules {
  modules = [
    {
      options.free = mkOption {
        type = lib.types.submoduleWith {
          modules = [
            # UPDATE: A freeformType is not necessarily part of the problem.
            # { freeformType = lib.types.anything; }
          ];
        };
        default = {};
      };
    }
    {
      options.free = mkOption {
        type = lib.types.submoduleWith {
          modules = [
            {
              options.complicated = mkOption {
                type = types.int;
                default = 1;
              };
            }
          ];
        };
      };
    }
    {
      options.free.specific = mkOption {
        type = lib.types.int;
        default = 2;
      };
    }
  ];
}).config
$ nix-instantiate test.nix  --eval --strict
error: The option `free' in `<unknown-file>' is a prefix of options in `<unknown-file>'.
(use '--show-trace' to show detailed location information)

The submodule only exists in order to provide a freeform type for that subtree, but it is conceptually still the same tree.

Expected behavior

$ nix-instantiate test.nix  --eval --strict
{ free = { complicated = 1; specific = 2; }; }

Additional context

A semi-workaround is to make writing the unnecessary module boundary easier.

    mkSubmoduleOptions =
      options:
      mkOption {
        type = types.submoduleWith {
          modules = [ { inherit options; } ];
        };
      };

However, this is needlessly complicated and it does not help in situations where a freeform type is introduced in a decentralized scenario.

Notify maintainers

@infinisil

Metadata

Maintainer information:

# a list of nixpkgs attributes affected by the problem
attribute:
  - lib.evalModules
  - lib.mkOption
# a list of nixos modules affected by the problem
module:

Metadata

Metadata

Assignees

No one assigned

    Labels

    0.kind: bugSomething is broken0.kind: enhancementAdd something new or improve an existing system.6.topic: module systemAbout "NixOS" module system internals

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions