-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
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
Recursive type deprecation #99132
Recursive type deprecation #99132
Conversation
1eac859
to
258b3a6
Compare
I’m not enough of a type system wizard to review this, but maybe @nbp can take a look? |
I marked this as stale due to inactivity. → More info |
This will be used to issue deprecation warnings recursively in the next commit In addition, this allows easily getting nested types of other options, which is useful when you want to create an option that aliases a part of another one.
In 2d45a62, the submodule type description was amended with the freeformType description. This causes all the modules passed to the submodule to be evaluated once on their own, without any extra definitions from the config section. This means that the specified modules need to be valid on their own, without any undeclared options. This commit adds a test that evaluates a submodules option description, which would trigger the above problem for one of the tests, if it were not fixed by this commit as well. This is done because the next commit makes option evaluation a bit more strict, which would also trigger this test failure, even though it's not related to the change at all.
Previously, an option of type attrsOf string wouldn't throw a deprecation warning, even though the string type is deprecated. This was because the deprecation warning trigger only looked at the type of the option itself, not any of its subtypes. This commit fixes this, causing each of the types deprecationMessages to trigger for the option. This relies on the subtypes mkOptionType attribute introduced in 26607a5a2e06653fec453c83d063cdfc4b59185f
258b3a6
to
8b957e3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. OfBorg failed to eval though, so please look into that.
Nice, it's actually working! |
OfBorg catches it, nice! |
Hm this broke my config with an infinite recursion error in like 5 different places and debugging it seems too hard :< (I'll try to investigate when I can but just reverting locally for now) |
In Nixpkgs, recursive types also set |
maybeWarn = warnIf (type.deprecationMessage != null) | ||
"The type `types.${type.name}' of option `${showOption loc}' defined in ${showFiles opt.declarations} is deprecated. ${type.deprecationMessage}"; | ||
in | ||
if visited ? ${type.name} then visited |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Being strict in type.name
turns out to be a significant problem, leading to incomprehensible errors when users define their own recursive types.
While this is technically a limitation of name
, it manifests because of this use of it.
…ely"" This reverts commit a36e676. There was one report saying that this broke a configuration, but I cannot reproduce this: NixOS#99132 (comment) We should give this another go
Motivation for this change
In #97114 better type deprecation messages were introduced. However they didn't trigger for nested types. So for example
wouldn't warn about
string
being deprecated, which is no good! This PR fixes this, you will get the proper warning now:To be able to get this working properly, these steps were necessary:
options.foo.type.elemType
as an option type and propagate its value as an attribute of thefoo
option.Note: For some types,
.functor.wrapped
contains subtypes as well. This however can't be reused because that doesn't contain all the subtypes. And justifiably so, because.functor
is only necessary for type merging.This does make option evaluation a bit more strict, because to be able to issue deprecation warnings, you need to evaluate all subtypes. This shouldn't be a problem in practice though. If anything, it exposes some errors. Performance will get a little worse, almost not significantly so in my testing though.
Note that 0bf115e doesn't really have anything to do with this PR, other than this PR being a trigger for it.
Ping @roberth @rnhmjoj @rycee @Profpatsch
Things done