···1057`dontBenchmark drv`
1058: Set `doBenchmark` to `false` for `drv`.
10591060-`setBuildTargets list drv`
1061: Sets the `buildTarget` argument for `drv` so that the targets specified in `list` are built.
10621063`doCoverage drv`
···1057`dontBenchmark drv`
1058: Set `doBenchmark` to `false` for `drv`.
10591060+`setBuildTargets drv list`
1061: Sets the `buildTarget` argument for `drv` so that the targets specified in `list` are built.
10621063`doCoverage drv`
+32-2
lib/lists.nix
···198 default:
199 # Input list
200 list:
201- let found = filter pred list;
202- in if found == [] then default else head found;
000000000000000000000000000000203204 /* Return true if function `pred` returns true for at least one
205 element of `list`.
···198 default:
199 # Input list
200 list:
201+ let
202+ # A naive recursive implementation would be much simpler, but
203+ # would also overflow the evaluator stack. We use `foldl'` as a workaround
204+ # because it reuses the same stack space, evaluating the function for one
205+ # element after another. We can't return early, so this means that we
206+ # sacrifice early cutoff, but that appears to be an acceptable cost. A
207+ # clever scheme with "exponential search" is possible, but appears over-
208+ # engineered for now. See https://github.com/NixOS/nixpkgs/pull/235267
209+210+ # Invariant:
211+ # - if index < 0 then el == elemAt list (- index - 1) and all elements before el didn't satisfy pred
212+ # - if index >= 0 then pred (elemAt list index) and all elements before (elemAt list index) didn't satisfy pred
213+ #
214+ # We start with index -1 and the 0'th element of the list, which satisfies the invariant
215+ resultIndex = foldl' (index: el:
216+ if index < 0 then
217+ # No match yet before the current index, we need to check the element
218+ if pred el then
219+ # We have a match! Turn it into the actual index to prevent future iterations from modifying it
220+ - index - 1
221+ else
222+ # Still no match, update the index to the next element (we're counting down, so minus one)
223+ index - 1
224+ else
225+ # There's already a match, propagate the index without evaluating anything
226+ index
227+ ) (-1) list;
228+ in
229+ if resultIndex < 0 then
230+ default
231+ else
232+ elemAt list resultIndex;
233234 /* Return true if function `pred` returns true for at least one
235 element of `list`.
···518 expected = false;
519 };
520521+ testFindFirstExample1 = {
522+ expr = findFirst (x: x > 3) 7 [ 1 6 4 ];
523+ expected = 6;
524+ };
525+526+ testFindFirstExample2 = {
527+ expr = findFirst (x: x > 9) 7 [ 1 6 4 ];
528+ expected = 7;
529+ };
530+531+ testFindFirstEmpty = {
532+ expr = findFirst (abort "when the list is empty, the predicate is not needed") null [];
533+ expected = null;
534+ };
535+536+ testFindFirstSingleMatch = {
537+ expr = findFirst (x: x == 5) null [ 5 ];
538+ expected = 5;
539+ };
540+541+ testFindFirstSingleDefault = {
542+ expr = findFirst (x: false) null [ (abort "if the predicate doesn't access the value, it must not be evaluated") ];
543+ expected = null;
544+ };
545+546+ testFindFirstNone = {
547+ expr = builtins.tryEval (findFirst (x: x == 2) null [ 1 (throw "the last element must be evaluated when there's no match") ]);
548+ expected = { success = false; value = false; };
549+ };
550+551+ # Makes sure that the implementation doesn't cause a stack overflow
552+ testFindFirstBig = {
553+ expr = findFirst (x: x == 1000000) null (range 0 1000000);
554+ expected = 1000000;
555+ };
556+557+ testFindFirstLazy = {
558+ expr = findFirst (x: x == 1) 7 [ 1 (abort "list elements after the match must not be evaluated") ];
559+ expected = 1;
560+ };
561562# ATTRSETS
563
+1-1
nixos/modules/config/qt.nix
···20 pkgs.adwaita-qt6
21 ]
22 else if isQtStyle then [ pkgs.libsForQt5.qtstyleplugins ]
23- else if isQt5ct then [ pkgs.libsForQt5.qt5ct ]
24 else if isLxqt then [ pkgs.lxqt.lxqt-qtplugin pkgs.lxqt.lxqt-config ]
25 else if isKde then [ pkgs.libsForQt5.plasma-integration pkgs.libsForQt5.systemsettings ]
26 else throw "`qt.platformTheme` ${cfg.platformTheme} and `qt.style` ${cfg.style} are not compatible.";
···20 pkgs.adwaita-qt6
21 ]
22 else if isQtStyle then [ pkgs.libsForQt5.qtstyleplugins ]
23+ else if isQt5ct then [ pkgs.libsForQt5.qt5ct pkgs.qt6Packages.qt6ct ]
24 else if isLxqt then [ pkgs.lxqt.lxqt-qtplugin pkgs.lxqt.lxqt-config ]
25 else if isKde then [ pkgs.libsForQt5.plasma-integration pkgs.libsForQt5.systemsettings ]
26 else throw "`qt.platformTheme` ${cfg.platformTheme} and `qt.style` ${cfg.style} are not compatible.";