summary refs log tree commit diff
path: root/lib/types.nix
diff options
context:
space:
mode:
Diffstat (limited to 'lib/types.nix')
-rw-r--r--lib/types.nix31
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/types.nix b/lib/types.nix
index c47a35cd0d6..acc7eac104e 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -61,7 +61,11 @@ let
     boolToString
     ;
 
-  inherit (lib.modules) mergeDefinitions;
+  inherit (lib.modules)
+    mergeDefinitions
+    fixupOptionType
+    mergeOptionDecls
+    ;
   outer_types =
 rec {
   isType = type: x: (x._type or "") == type;
@@ -525,6 +529,31 @@ rec {
       modules = toList modules;
     };
 
+    # The type of a type!
+    optionType = mkOptionType {
+      name = "optionType";
+      description = "optionType";
+      check = value: value._type or null == "option-type";
+      merge = loc: defs:
+        let
+          # Prepares the type definitions for mergeOptionDecls, which
+          # annotates submodules types with file locations
+          optionModules = map ({ value, file }:
+            {
+              _file = file;
+              # There's no way to merge types directly from the module system,
+              # but we can cheat a bit by just declaring an option with the type
+              options = lib.mkOption {
+                type = value;
+              };
+            }
+          ) defs;
+          # Merges all the types into a single one, including submodule merging.
+          # This also propagates file information to all submodules
+          mergedOption = fixupOptionType loc (mergeOptionDecls loc optionModules);
+        in mergedOption.type;
+    };
+
     submoduleWith =
       { modules
       , specialArgs ? {}