1{ lib, options, ... }:
2let discardPositions = lib.mapAttrs (k: v: v);
3in
4# unsafeGetAttrPos is unspecified best-effort behavior, so we only want to consider this test on an evaluator that satisfies some basic assumptions about this function.
5assert builtins.unsafeGetAttrPos "a" { a = true; } != null;
6assert builtins.unsafeGetAttrPos "a" (discardPositions { a = true; }) == null;
7{
8 imports = [
9 {
10 options.imported.line10 = lib.mkOption {
11 type = lib.types.int;
12 };
13
14 # Simulates various patterns of generating modules such as
15 # programs.firefox.nativeMessagingHosts.ff2mpv. We don't expect to get
16 # line numbers for these, but we can fall back on knowing the file.
17 options.generated = discardPositions {
18 line18 = lib.mkOption {
19 type = lib.types.int;
20 };
21 };
22
23 options.submoduleLine34.extraOptLine23 = lib.mkOption {
24 default = 1;
25 type = lib.types.int;
26 };
27 }
28 ];
29
30 options.nested.nestedLine30 = lib.mkOption {
31 type = lib.types.int;
32 };
33
34 options.submoduleLine34 = lib.mkOption {
35 default = { };
36 type = lib.types.submoduleWith {
37 modules = [
38 ({ options, ... }: {
39 options.submodDeclLine39 = lib.mkOption { };
40 })
41 { freeformType = with lib.types; lazyAttrsOf (uniq unspecified); }
42 ];
43 };
44 };
45
46 config = {
47 submoduleLine34.submodDeclLine39 = (options.submoduleLine34.type.getSubOptions [ ]).submodDeclLine39.declarationPositions;
48 };
49}