Confusing behavior of aliases when evaluating modules with evalModules



with lib;


  someModule = { = mkOption {
      type = types.bool;
      default = true;


evalModules {
  modules =
    [ someModule
      (mkAliasOptionModule [ "bar" ] [ "foo" ])
  check = false;

Let’s load it in the REPL:

nix-repl> :l <nixpkgs>
Added 10082 variables.

nix-repl> cfg = import ./test.nix lib


error: The option `bar' is used but not defined.

The option bar is defined as an alias of foo. How can it be that foo is defined but bar is not?
I’m using NixOS 19.03.

Looking at the definition of mkAliasOptionModule, it appears that all definitions of bar get propagated to foo, but not vice versa, which is why bar is not defined. I find this confusing, because I thought that "option a is an alias of option b" means "option a is the same option as option b", i.e. every definition of a counts as a definition of b and vice versa. I feel like this is a bug that should be fixed.

Ok, I’m pretty sure this is a bug, here’s why:

  1. mkAliasOptionModule sets the apply attribute of the newly created option (code), so that when its value is computed, it evaluates to the value of the target option. So, in principle, evaluating should evaluate to exactly the same thing as
  2. This doesn’t happen, because the option bar does not have any definitions, and the apply attribute of the option isn’t used (code).

A workaround would be for mkAliasOptionModule to define the newly created option, but give it a very high priority number (so that its priority is very low) and a value that throws an error when evaluated.

I’ve created an issue on github.