diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh index b1994ff31638..f5f7e907d277 100755 --- a/lib/tests/modules.sh +++ b/lib/tests/modules.sh @@ -113,6 +113,7 @@ checkConfigError 'A definition for option .intStrings\.mergeError. is not of typ checkConfigError 'A definition for option .intStrings\.badTagError. is not of type .attribute-tagged union' config.intStrings.badTagError ./types-attrTag.nix checkConfigError 'A definition for option .intStrings\.badTagTypeError\.left. is not of type .signed integer.' config.intStrings.badTagTypeError.left ./types-attrTag.nix checkConfigError 'A definition for option .nested\.right\.left. is not of type .signed integer.' config.nested.right.left ./types-attrTag.nix +checkConfigError 'In attrTag/attrTagWith, each tag value must be an option, but tag int was a bare type, not wrapped in mkOption.' config.opt.int ./types-attrTag-wrong-decl.nix # types.pathInStore checkConfigOutput '".*/store/0lz9p8xhf89kb1c1kk6jxrzskaiygnlh-bash-5.2-p15.drv"' config.pathInStore.ok1 ./types.nix diff --git a/lib/tests/modules/types-attrTag-wrong-decl.nix b/lib/tests/modules/types-attrTag-wrong-decl.nix new file mode 100644 index 000000000000..d03370bc10da --- /dev/null +++ b/lib/tests/modules/types-attrTag-wrong-decl.nix @@ -0,0 +1,14 @@ +{ lib, ... }: +let + inherit (lib) types mkOption; +in +{ + options = { + opt = mkOption { + type = types.attrTag { + int = types.int; + }; + default = { int = 1; }; + }; + }; +} diff --git a/lib/types.nix b/lib/types.nix index 7fe7b5d92eac..a77a8ef11244 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -15,6 +15,7 @@ let isList isString isStorePath + throwIf toDerivation toList ; @@ -627,7 +628,13 @@ rec { mapAttrs (n: opt: builtins.addErrorContext "while checking that attrTag tag ${lib.strings.escapeNixIdentifier n} is an option with a type${inAttrPosSuffix args.tags n}" ( - assert opt._type == "option"; + throwIf (opt._type or null != "option") + "In attrTag/attrTagWith, each tag value must be an option, but tag ${lib.strings.escapeNixIdentifier n} ${ + if opt?_type then + if opt._type == "option-type" + then "was a bare type, not wrapped in mkOption." + else "was of type ${lib.strings.escapeNixString opt._type}." + else "was not."}" opt // { declarations = opt.declarations or ( let pos = builtins.unsafeGetAttrPos n args.tags;