···630630 loc = prefix ++ [name];
631631 defns = pushedDownDefinitionsByName.${name} or [];
632632 defns' = rawDefinitionsByName.${name} or [];
633633- optionDecls = filter (m: isOption m.options) decls;
633633+ optionDecls = filter
634634+ (m: m.options?_type
635635+ && (m.options._type == "option"
636636+ || throwDeclarationTypeError loc m.options._type
637637+ )
638638+ )
639639+ decls;
634640 in
635641 if length optionDecls == length decls then
636642 let opt = fixupOptionType loc (mergeOptionDecls loc decls);
···691697 }) defs
692698 ) unmatchedDefnsByName);
693699 };
700700+701701+ throwDeclarationTypeError = loc: actualTag:
702702+ let
703703+ name = lib.strings.escapeNixIdentifier (lib.lists.last loc);
704704+ path = showOption loc;
705705+ depth = length loc;
706706+707707+ paragraphs = [
708708+ "Expected an option declaration at option path `${path}` but got an attribute set with type ${actualTag}"
709709+ ] ++ optional (actualTag == "option-type") ''
710710+ When declaring an option, you must wrap the type in a `mkOption` call. It should look somewhat like:
711711+ ${comment}
712712+ ${name} = lib.mkOption {
713713+ description = ...;
714714+ type = <the type you wrote for ${name}>;
715715+ ...
716716+ };
717717+ '';
718718+719719+ # Ideally we'd know the exact syntax they used, but short of that,
720720+ # we can only reliably repeat the last. However, we repeat the
721721+ # full path in a non-misleading way here, in case they overlook
722722+ # the start of the message. Examples attract attention.
723723+ comment = optionalString (depth > 1) "\n # ${showOption loc}";
724724+ in
725725+ throw (concatStringsSep "\n\n" paragraphs);
694726695727 /* Merge multiple option declarations into a single declaration. In
696728 general, there should be only one declaration of each option.
+5
lib/tests/modules.sh
···393393 config.set \
394394 ./declare-set.nix ./declare-enable-nested.nix
395395396396+# Options: accidental use of an option-type instead of option (or other tagged type; unlikely)
397397+checkConfigError 'Expected an option declaration at option path .result. but got an attribute set with type option-type' config.result ./options-type-error-typical.nix
398398+checkConfigError 'Expected an option declaration at option path .result.here. but got an attribute set with type option-type' config.result.here ./options-type-error-typical-nested.nix
399399+checkConfigError 'Expected an option declaration at option path .result. but got an attribute set with type configuration' config.result ./options-type-error-configuration.nix
400400+396401# Check that that merging of option collisions doesn't depend on type being set
397402checkConfigError 'The option .group..*would be a parent of the following options, but its type .<no description>. does not support nested options.\n\s*- option.s. with prefix .group.enable..*' config.group.enable ./merge-typeless-option.nix
398403