Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

either does not propagate suboptions #207962

Open
ncfavier opened this issue Dec 27, 2022 · 2 comments · May be fixed by #208227
Open

either does not propagate suboptions #207962

ncfavier opened this issue Dec 27, 2022 · 2 comments · May be fixed by #208227
Labels
0.kind: bug Something is broken 6.topic: module system About "NixOS" module system internals

Comments

@ncfavier
Copy link
Member

An option with the type either foo (submodule ...) (or oneOf [ (submodule ...) ... ]) will not have the suboptions of the submodule appear in the manual. This popped up in #191768 (comment).

The obvious fix would be to add something like getSubOptions = prefix: lib.attrsets.unionOfDisjoint (t1.getSubOptions prefix) (t2.getSubOptions prefix); to either, but this results in an infinite recursion because of recursively defined types like (pkgs.formats.yaml {}).type:

type = with lib.types; let
valueType = nullOr (oneOf [
bool
int
float
str
path
(attrsOf valueType)
(listOf valueType)
]) // {
description = "YAML value";
};
in valueType;

Generating the documentation for an option foo of that type will try to get the suboptions for foo, which will recurse to get the suboptions for foo.<name>, then foo.<name>.<name>, etc.

We could hack our way around this by overriding getSubOptions manually for recursive types, or setting a maximum recursion depth, but I can't really think of an elegant solution to this. Maybe we should just live with it, and document that submodule in either is not supported.

cc @infinisil @roberth

@ncfavier ncfavier added the 0.kind: bug Something is broken label Dec 27, 2022
@roberth
Copy link
Member

roberth commented Dec 27, 2022

Perhaps recursive types should be defined through an explicit fixpoint? That way the fixpoint combinator can take care of plugging the infinite recursions for this, description and future such problems.

boolTree = types.fix (t: oneOf [ (attrsOf t) bool ])

types.fix = tf: lib.fix tf // { description = "recursive type of ${tf (types.null // { description = "the recursive type"; })}"; getSubOptions = ...; }

Not great, but certainly not terrible.

@ncfavier
Copy link
Member Author

That's probably the least bad option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: bug Something is broken 6.topic: module system About "NixOS" module system internals
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants